This is not the final version of the GPU, but it is the current version and working very well. Supports 16 colors
UPDATE: Replaced the ROMs with a RAM. Hope this can make it easier!
CB PPU
CB stands for "Color Burst"
This is a graphics processor/screen driver for 8-bit CPUs.
It works with 16x16 screens or under.
It has a sprite system that has 16 slots.
Most of this description you can find in the project.
Update Notes:
V1 (2024, April 30):
Frame buffer works! Implemented single pixel drawing.
V2 (2024, May 2):
Tinting and Grayscale color operations are added to the pixel drawer. But further development on this is scrapped due to being inefficient.
V3 (2024, May 15) Release 1:
First release of Color Burst! Yipee!!!
Anyways, full flag register, instructions, sprites, and background!
REGISTERS
FLG:
The Flag register for effects.
Op:
The chosen operation (writing to it executes the operation)
Pos1:
Used interchangeably but usually a position (changes based on OP)
Pos2:
Used interchangeably but usually a position (changes based on OP)
SPos:
The Position of the currently selected Sprite
S:
The Slot used for table and sprite updates
BK:
The background color (RRRGGBBB)
CLR register:
This holds the color register for stuff (RRRGGBBB)
FLAG Register
AECg BGRM
M = Pos1, Pos2 OR Pos, Dim
R = Adds 32 to r channel from then on (Tint Red)
G = Adds 32 to g channel from then on (Tint Green)
B = Adds 32 to b channel from then on (Tint Blue)
g = Uses CLR as grayscale value from then on
C = Nothing?
E = Disable background
A = Graphics update by clock or manual
INSTRUCTION SET
00: NOP
01: Flip - Invokes a Graphics update (32 units)
02: Disable Sprite - Disables the sprite at slot S
03: Enable Sprite - Enables the sprite at slot S
04: CreateSp - Creates a sprite using Pos1 as position, Pos2 as dim or pos, C as color
05: UpdateSpPos - Changes the position of sprite at S into Pos1
06: UpdateSpDim - Changes dim of sprite at S to Pos2
07: UpdateSpClr - Changes the color of sprite at S to C
08: Scroll - Adds to the Sprite positions based on Pos1 (32 units)
GUIDE
In order to enable RTX, set the C flag to 1. (JOKE)
--QNA--
Q: Why is it called PPU?
A: It's called that because PPU stands for Picture Processing Unit. I used this name because by naming it a GPU it would sound more powerful than it actually is. Also the NES' graphics processor calls itself PPU as well.
Q: Why in the heck would you make this?
A: Because I wanted to make Graphical games on my CPU projects.
Q: What happens if you scroll it past the side?
A: It will wrap the coordinates around which might make a weird effect due to how the sprites are drawn.
Q: Can it work with 4K?
A: Maybe... Just kidding, it's impossible to drive anything over 16x16 due to the coordinates being only 4 bits each.
--Format--
Color on Color Burst is specified as
RRRGGBBB
This means that there's an unequal distribution of green in comparison with other colors. Unfortunately in order to achieve full use of the 8 bits, I have decided to make greennot as precise. These colors are also shifted in order to fit the 24 bit depth additive color that drives the screen.
Position and Dimensions are specified as
XXXXYYYY
This means that this PPU will only drive a 16x16 or smaller screen.
--Sprites--
Anyways you can make a total of 16 different sprites. Each sprite is well, a rectangle. By the M flag you can select whether you want to specify each sprite as Position and Dimension or Position and Position. It uses the POS1 and POS2 Register for this operation. If you try to use a value over 16 on the S register, it will wrap. Also, sprites are drawn bottom to top so sprite 16 would be on top and 1 on bottom.
--Background--
Each graphics update, the screen is erased and replaced with the background color. In order to change this color, update the BK register. The erasing and updating can be disabled though by using the E flag so that you could theoretically have more than 16 sprites. You can of course read the position from the selected Sprite as well using SPOS.
--Effects--
There are a few effects to choose from on here. Tint Red, Tint Green, Tint Blue, and grayscale. These instructions are controlled by the flag register as R,G,B,g. In order to use them, just set them to 1. Also the tint operations add 32 to the channels by default but future versions of this PPU could have a register to change that.
--Instructions--
Instructions are triggered upon writing to the register. There are 8 instructions. Flip just updates the screen with new data. Scroll just uses the value of POS1 in order to update every sprite by adding it to the position. (This takes 32 units). Other instructions are explained in the set well.
--Other--
If you want to update the graphics by clock instead of instruction, you can change A to 1 and then you can choose a clock speed for the updates (Keep in mind that the clock must last for over 32 units due to graphics updates taking that long.
PLANS
Possible memory maps:
Consider a possible frame buffer implementation.
Without PPU:
Byte 1: Position
(On position write, it will verify pixel write)
Byte 2-4: RGB 24 bit value
With PPU 8-bit color:
two bit perlast two bits should be apply mode (add, sub, replace, or mult) nah it's too hard.
Or use a 4 bit hue, 2 bit saturation, and 2 bit value.
HSV would be too hard due to having to decrease the differnce between each color
Or maybe make a custom byte based color pallete for 8 bit color using boxes (x = r, y = g, box# = b) wait hold on that'll still be inconsistent.
Just use three bit values for colors except green (2 bits)
On overflow, it will do nothing.Sprites are drawn based on slot order. (Except on creation and update)
Full 24 bit color is impractical.
Function method:
OPS:
SetColor (RGB) - Set Color Register
SetPOS (PP) - Set POS Registers
DrawRect - Draws a rectangle starting at POS1 then ending at POS2 using Color
DrawCircle (R) - Draws a circle using POS1, R, and Color
DrawLine - Draws a line using Color, POS1, POS2
SetPixel (P) - Draws a pixel at X,Y
SavSprite (SD) - Saves a sprite to memory at slot S with length and width and the Color
LodSPrite (SP) - Loads a sprite at S at XY
ReadSprite (S) - Reads the length and width of the sprite and outputs it
ReadSpriteClr (S) - Reads color of sprite and outputs it
MM:
Byte 1: OP
Byte 2-4: Arguments
Byte 5-7: Output
Register Method:
OPS:
DrawPix - Draws C at Pos1
DrawLine - Draws C line using Pos1 and Pos2
DrawRect - Draws C rect using Pos1 and Pos2
SaveTbl - Uses Pos1 and C for a table entry and saves it to slot S
LoadTbl - Uses S reg to draw an instance of a table entry to Pos1
SetBack - Sets a color for the background using C
Erase - Erases all updates to background but keeps sprites.
CreateSp - Creates a sprite using Pos1 as position, Pos2 as table slot,
Enable Sprite - Draws the sprite at slot S
Disable Sprite - Erases the sprite at slot S
UpdateSpPos - Changes the position of sprite at S into Pos1
UpdateSpClr - Changes the color of sprite at S to C
Scroll - Adds to the Sprite positions based on Pos1 (Also erases everything)
MM:
Byte 1: C reg
Byte 2: Pos1 reg
Byte 3: Pos2 reg
Byte 4: SPos (R)
Byte 5: S reg
Byte 6: OP (W)
Byte 7: Flag reg
Docs:
Flag:MRGB gCEAM = Pos1, Pos2 OR Pos, Dim
R = Adds 10 to r channel from then on
G = Adds 10 to g channel from then on
B = Adds 10 to b channel from then on
g = Uses r value as grayscale value from then on
C = Enables clipping for sprite placing.
E = Automatically erases a sprite after position update
A = Graphics update by clock or manual
C register: This holds the color register for stuff (RRRGGBBB)
Pos1: Used interchangeably but usually a position (changes based on OP)
Pos2:Used interchangeably but usually a position (changes based on OP)
SPos:
The Position of the currently selected SpriteS:
The Slot used for table and sprite updates
Op:The chosen operation (writing to it executes the operation)
-Chose register method for v1.
V2 is near impossible unless updates are always done. (Could be done on a regular circuit sim)-
V1.1:
Adds frame flip feature so that you wouldn't see screen updates.
V2:
V2 is more similar to a NES type PPU.
Each slot is 2x2 and there's background and sprites.
Table of instance-able tiles are created.
Sprite table is created
Background table is createPallette table is also created.
Sprite hits are also detected.Frame-based instead of canvas.
MM:
OPS:
STbl -
LTbl -
CreateSp - Uses Pos1 as position, Pos2 as table slot, then S as slot
UpdateSp - Updates the sprite position using Pos1 and S as slot
EnableSP - Enables or disables a sprite using S as slot and Pos1 as argument (bit0)
SetBack - Pos1 as table position for tile and then S as the table slot.
VO:OPS:Flip - Invokes a Graphics update (32 units)
CreateSp - Creates a sprite using Pos1 as position, Pos2 as table slot, C as color
Enable Sprite - Enables the sprite at slot S
Disable Sprite - Disables the sprite at slot S
UpdateSpPos - Changes the position of sprite at S into Pos1
UpdateSpDim - Changes dim of sprite at S to Pos2
UpdateSpClr - Changes the color of sprite at S to C
Scroll - Adds to the Sprite positions based on Pos1 (32 units)
MM:
Byte 1: C reg
Byte 2: Pos1 reg
Byte 3: Pos2 reg
Byte 4: SPos (R)Byte 5: S reg
Byte 6: OP (W)
Byte 7: Flag reg
Byte 8: Back reg
Docs:
Flag:MRGB gCEAM = Pos1, Pos2 OR Pos, DimR = Adds 10 to r channel from then onG = Adds 10 to g channel from then on
B = Adds 10 to b channel from then on
g = Uses r value as grayscale value from then on
C =
E = Disable background
A = Graphics update by clock or manual
C register: This holds the color register for stuff (RRRGGBBB)
Pos1: Used interchangeably but usually a position (changes based on OP)
Pos2:Used interchangeably but usually a position (changes based on OP)
SPos:
The Position of the currently selected Sprite
S:
The Slot used for table and sprite updates
Op:
The chosen operation (writing to it executes the operation)
Back:
The background color