The Spectrum Next/TBBlue have a new hardware sprites system, enabling easier programming of sprites and their manipulation on screen. The characteristics of the sprites are:

  • Total 64 sprites in 64 attribute slots and 64 pattern slots;
  • Size 16 by 16 pixels;
  • 512 colors per pixel;
  • A sprite offset that can be used to recolor the sprite;
  • Transparent mask;
  • Maximum of 12 sprites per scanline;
  • Collision detection of sprites;
  • Rotate and X/Y mirror flag;
  • Possibility to display sprites over the ZX Spectrum border.

The memory used for the sprites is separated from the main memory of the ZX Spectrum, being implemented in the internal memory of the FPGA and accessible via I/O ports.

Some options are configured via the TBBlue port system, reproduced here:

Port 0x243B is write-only and is used to set the registry number.

Port 0x253B is used to access the registry value.

(R/W) 0x15 (21) => Sprite and Layers system
  bit 7 - LoRes mode, 128 x 96 x 256 colours (1 = enabled)
  bits 6-5 = Reserved, must be 0
  bits 4-2 = set layers priorities:
     Reset default is 000, sprites over the Layer 2, over the ULA graphics
     000 - S L U
     001 - L S U
     010 - S U L
     011 - L U S
     100 - U S L
     101 - U L S
  bit 1 = Over border (1 = yes)(Back to 0 after a reset)
  bit 0 = Sprites visible (1 = visible)(Back to 0 after a reset)

To turn on the sprites, bit 0 of register 21 must be set. If bit 1 is on, the sprites may be displayed over the default ZX Spectrum border.

Port 0x303B, if read, returns some information:

  • Bits 7-2: Reserved, always 0.
  • Bit 1: max sprites per line flag.
  • Bit 0: Collision flag.

Port 0x303B, if written, defines the sprite slot to be configured by ports 0x57 and 0x5B, and also initializes the address of the palette.

Port 0x57 is write-only and is used to send the attributes of the selected sprite slot, being the address is auto-incremented each writing and after sending the 4 bytes of attributes the address points to the next sprite. The description of each byte follows below:

  • 1st: X position (bits 7-0).
  • 2nd: Y position (0-255).
  • 3rd: bits 7-4 is palette offset, bit 3 is X mirror, bit 2 is Y mirror, bit 1 is the rotate flag and bit 0 is X MSB.
  • 4th: bit 7 is the visible flag, bit 6 is reserved, bits 5-0 is Name (pattern index, 0-63).

Port 0x5B is write-only and is used to send the pattern of the selected sprite slot, with the address being auto-incremented with each write and after sending the 256 bytes of the pattern the address points to the next sprite slot. Each pattern byte represents the offset of the palette and the order is left to right and top to bottom.

Addresses from Ports 0x57 and 0x5B are independent and configured together in the write port 0x303B, however, the increment of the address is done separately, can be sent the pattern of 10 sprites, for example, and then sent the attributes of the 10 sprites without having to rewrite in the port 0x303B.

Because sprites can be displayed on top of the ZX Spectrum border, the coordinates of each sprite can range from 0 to 319 for the X-axis and 0 to 255 for the Y-axis. For both axes, values from 0 to 31 are reserved for the Left or top border, for the X-axis the values 288 to 319 is reserved for the right border and for the Y axis values 224 to 255 for the lower border.

If the display of the sprites on the border is disabled, the coordinates of the sprites range from (32,32) to (287,223).

The priority of the sprites is from 0 (least priority) to 63 (highest priority) and all sprites have the highest priority over all spectrum screens.

Each sprite has the Name attribute that defines which pattern it will display, and more than one sprite can display the same pattern. Each byte of the pattern defines the index of the palette with the 4 most significant bits being summed with bits 7-4 of the third byte of the attributes, allowing the programmer to display the same pattern with different colors.

As an example of the palette offset, if the byte of the pixel pattern (0,0) is 0x14, and the palette offset is 0x00, the color will be of the palette index 0x14, but if the palette offset is set to 0x20, The palette index will be 0x34.

Collisions of 2 or more sprites only happen if at least 2 non-transparent pixels are drawn in the same position on the screen.

As an example of a sprite, let’s check the pattern below:

Pattern example

Using the default palette, which is initialized at the reset for colors 0 through 255, the hexadecimal values for this pattern follow below, divided into 16 bytes per line with 16 rows in total:


The value in hexadecimal 0xE3 points to index 227 of the palette containing the color 0xE3 that represents the transparent index. The index used can be changed using the Next register 0x4b;

(R/W) 0x4B (75) => trasnparency index for Sprites
  bits 7-0 = Set the 8 bit colour.
  (0XE3 after a reset)

To set this pattern for some sprite, we must set the slot number of the patterns through port 0x303B and then send the 256 bytes in sequence to port 0x5B. In the following example we will choose slot #2:

OUT 0x303B, 2: REM Select pattern #2

OUT 0x5B, 0x04: OUT 0x5B, 0x04........... : REM Send pattern data

To display the sprite at some screen position, we must set up some sprite to be visible by setting its attributes, pointing to pattern #2 and turning on the sprites display. In the following example we will choose sprite slot #9:

OUT 0x303B, 9: REM Select sprite #9

OUT 0x57, 32: REM X position in 32

OUT 0x57, 32: REM Y position in 32

OUT 0x57, 0: REM no palette offset and no rotate and mirrors flags

OUT 0x57, 130: REM Sprite visible and show pattern #2

OUT 0x243B, 21: REM Select register #21

OUT 0x253B, 1: REM All sprites visible

The Next screen should be displayed as below:

TBBlue Screen sample


All possibilities of Rotate, Mirror X and Mirror Y flags.