My 2D GPU: Gpu1
Gpu1 is a GPU without a framebuffer, the pixels are generated just in time to display like the arcade machine and game console from the 80s and 90s.
It has 128 hardware sprites of any size (no tiles) and 16 color palettes, each sprite has a single color palette.
Current resolution is 320x480 and later will be 720x480 with a refresh rate of 60 frames per second and the colors are 18bits (262144 colors).
Each sprite has a position in the range -1024, 1023, a size in the range 0 to 2047 and a plane from 0 to 3. The sprites on plane 0 are at the bottom, the sprites on plane 1 cover sprites on plane 0. Sprites on plane 2 cover plane 0 and 1 and sprites on plane 3 cover plane 0, 1 and 2.
There is maximum 128 sprites per line and maximum 32 sprites per plane per line. The plane 0 can have more than 32 sprites but some sprites have to be different lines.
When sprites on the same plane are over each other, the sprite with the lowest x coordinate is displayed first and the other sprite is not displayed completely.
The sprite pixel have 1 bit, each palette has 2 colors. When a sprite is a background, there is no transparent color and when a sprite is not a background, color 0 is transparent.
The number of bit per pixel can be increased to 8 bits, 256 colors per sprite.
The sprite ram is 512kb, for 1bpp sprites it is large enough.
When a frame is finished being displayed, a hardware interrupt is sent from the gpu to the cpu. In the interrupt, the cpu changes the sprite configurations for the next frame and the cpu can run at least 10000 instructions before the next frame starts.
The gpu interrupt is interrupt 8 in the cpu.
How images are displayed
When line y is being displayed, the gpu creates the sprite list for the next line. There is a sprite list of 32 elements for each plane. The sprites on the next line are added to the lists, then the 4 lists are sorted by x with a hardware implemented bubble sort. Bubble sort is always done with sorting before the next line starts being displayed. Bubble sort is used here because it is the sorting algorithm which requires the less memory. If there were 64 sprites on each list, bubble sort wouldn't be finished before the next line starts.
The line is displayed by going through the sprite lists and check if the x coordinate in a sprite. It starts with sprite at index 0, when x is outside on the right the next sprite is checked.
Address map
The registers are aligned on 64bit addresses and the address map is the same on 32 and 64bit systems.
- 0x00000000 Default color (when there is no sprite)
Sprite configurations, n is the sprite index:
- 0x08 + n * 0x80 sprite address
- 0x10 + n * 0x80 x coordinate
- 0x18 + n * 0x80 y coordinate
- 0x20 + n * 0x80 w width
- 0x28 + n * 0x80 h height
- 0x30 + n * 0x80 bg 0 sprite with transparent color 1 background sprite without transparent color
- 0x38 + n * 0x80 palette index
- 0x40 + n * 0x80 enabled 0 don't display this sprite 1 show this sprite
- 0x48 + n * 0x80 sprite plane
The palette colors are starting at address 0x4008 (128 sprites * 0x80 + 8), there are 16 palettes and 2 colors in each palette, n is the palette index:
- 0x4008 + n * 0x10 color 0
- 0x4010 + n * 0x10 color 1
Sprite ram, the sprite addresses are offsets in this ram:
- 0x10000 pixel data for sprites