Sprite table reference

Sprite table format

The location of the sprite table in VRAM is determined by VDP register $85xx.

The sprite table consists of either 80 or 64 entries (depending on whether the horizontal resolution is H40 or H32, respectively). Each entry is 8 bytes long:

Sprite table entry
OffsetSizeDescription
+02 bytesY coordinate
+21 byteSprite size
+31 byteSprite link
+42 bytesTile ID and flags
+62 bytesX coordinate

X and Y coordinates

These two fields indicate the position of the top-left corner of the sprite on screen. The origin is at -128;-128, i.e. you should add 128 to both coordinates to match their position on screen.

These fields are only 9-bit (the rest of the bits are ignored) so the coordinates will wrap around every 512 pixels. This is only relevant if you don't clip out the sprites at the screen boundaries.

Tile ID and flags

This is the field that indicates which graphic the sprite uses and whatever effects are applied to it (flipping, palette, etc.):

Sprite tile ID and flags
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
1st byte PRI CP1 CP0 VF HF SN10 SN9 SN8
2nd byte SN7 SN6 SN5 SN4 SN3 SN2 SN1 SN0

Sprites use consecutive tile IDs, i.e. if your sprite is 3×2 tiles and the first tile ID is 100, then it'll use tiles 100, 101, 102, 103, 104 and 105.

The flip flags apply to the whole sprite, not each individual tile. Coordinates still refer to the top-left corner of the already flipped sprite, so you will need to adjust them if this is not what you wanted.

To make things easier, you can OR these flags with the tile ID to set the respective effects (you may OR up to one of each group):

NOFLIP:  equ $0000  ; Don't flip
HFLIP:   equ $0800  ; Flip horizontally
VFLIP:   equ $1000  ; Flip vertically
HVFLIP:  equ $1800  ; Flip both ways

PAL0:    equ $0000  ; 1st palette
PAL1:    equ $2000  ; 2nd palette
PAL2:    equ $4000  ; 3rd palette
PAL3:    equ $6000  ; 4th palette

LOPRI:   equ $0000  ; Low priority
HIPRI:   equ $8000  ; High priority

Sprite size

This field indicates the size of the sprite (in tiles). It has the following format:

Sprite size field
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
0 0 0 0 HS1 HS0 VS1 VS0

Both width and height are measured in tiles minus one (i.e. 00 is 1 tile and 11 is 4 tiles), any combination is allowed. The remaining bits are ignored. You may use the following constants to make your life easier:

; Name is SPR_*x# where * is the
; width and # is the height

SPR_1x1:  equ %0000  ; 1x1 tiles
SPR_2x1:  equ %0100  ; 2x1 tiles
SPR_3x1:  equ %1000  ; 3x1 tiles
SPR_4x1:  equ %1100  ; 4x1 tiles
SPR_1x2:  equ %0001  ; 1x2 tiles
SPR_2x2:  equ %0101  ; 2x2 tiles
SPR_3x2:  equ %1001  ; 3x2 tiles
SPR_4x2:  equ %1101  ; 4x2 tiles
SPR_1x3:  equ %0010  ; 1x3 tiles
SPR_2x3:  equ %0110  ; 2x3 tiles
SPR_3x3:  equ %1010  ; 3x3 tiles
SPR_4x3:  equ %1110  ; 4x3 tiles
SPR_1x4:  equ %0011  ; 1x4 tiles
SPR_2x4:  equ %0111  ; 2x4 tiles
SPR_3x4:  equ %1011  ; 3x4 tiles
SPR_4x4:  equ %1111  ; 4x4 tiles

The sprite table is not linear but actually a linked list. This means that each sprite which one follows in the list. This field indicates which sprite follows (1 = second entry, 2 = third entry, etc.). If this field is 0, it indicates the end of the list.

The list always starts with sprite 0. Bits 6-0 are used (bit 7 is ignored).

128k VRAM mode

In 128k VRAM mode, there's room for 4096 unique tiles, but only 2048 can be addressed at once. The VDP deals with this by splitting VRAM into two "banks" of 2048 tiles. VDP register $86xx determines which of the two banks is used by all sprites:

VDP register $86xx
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
0 0 AP16 0 0 0 0 0

AP16 is 0 to use the lower 64KB of VRAM and 1 to use the upper 64KB of VRAM.

The sprite table is not affected by this register, but rather the sprite table address simply gains an extra bit. This means you can place the table in the opposite bank if you wish.