Assembly Language Fundamentals

Intermediate
Version:
1.0

Overlaying Sprites to Create Multi-Colour Effects

Introduction

The Tatung Einstein’s TMS9129 Video Display Processor (VDP) allows only one colour per sprite pattern. While this keeps the hardware simple, it can also limit your creativity when designing more detailed graphics.

Fortunately, there’s a clever way to bypass this restriction: overlaying multiple sprites at the same position, each with a different pattern and colour. When drawn together, they appear as one richly detailed image — for example, a metallic flying saucer with white highlights and grey shading that looks almost three-dimensional.

This technique allows you to simulate multi-colour sprites, add shadows or highlights, and give your graphics more depth and texture, all without modifying the hardware.

How It Works

Each sprite is drawn separately by the VDP, based on its pattern, colour, and position. By carefully aligning two sprites on the same X and Y coordinates, the hardware composites them visually on screen, effectively layering their patterns.

To achieve a convincing effect:

  1. Define two complementary patterns — one containing highlights (for white or bright pixels) and another with shadows (for grey or darker pixels).
  2. Set different colour values for each sprite, such as white and grey.
  3. Overlay them exactly by using the same X and Y coordinates.
  4. Ensure pattern bits complement each other, so that bright and dark pixels do not overlap completely — this prevents flickering and preserves the illusion of depth.

The result is a detailed, pseudo-multi-colour sprite that appears more advanced than the hardware technically supports.

Full Program

The following program overlays two sprite pairs — white and grey — to form a simple 3D-looking flying saucer. Each half is made up of two overlapping sprites, giving subtle shading effects and breaking the single-colour limitation.

ORG 256

; -----------------------
; Enable Graphics Mode II
; ----------------------

LD   A,2
OUT  (9),A
LD   A,128
OUT  (9),A

LD   A,224
OUT  (9),A
LD   A,129
OUT  (9),A

; ---------------------------
; Set Foreground / Background
; ---------------------------

LD   A,240        ; 11110000 (white foreground, black background)
OUT  (9),A
LD   A,135        ; 128 + 7 = register 7
OUT  (9),A

     ; -----------------
     ; Write Blank Tiles
     ; -----------------

     ; Top Third Blank Tile

     LD   A, 0            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 64           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A, 0            ; Load 170 into A
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8

     ; Middle Third Blank Tile

     LD   A, 0            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 72           ; Load 72 into A register
     OUT  (9), A          ; Send to Port 9

     LD A, 0            ; Load 170 into A
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8

     ; Bottom Third Blank Tile

     LD   A, 0            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 80           ; Load 80 into A register
     OUT  (9), A          ; Send to Port 9

     LD A, 0              ; Load 170 into A
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8



; (Repeated blank tile setup omitted for brevity)

; --------------------------------
; Clear Name Table with Blank Tile
; --------------------------------

LD A,0
OUT (9),A
LD A,120
OUT (9),A
LD BC,768

ClearLoop:
LD A,0
OUT (8),A
DEC BC
LD A,B
OR C
JR NZ,ClearLoop

; ---------------------
; Define Sprite Pattern
; ---------------------

; Saucer shading pattern (white layer)
LD A,0
OUT (9),A
LD A,88
OUT (9),A

LD A,%00001111 : OUT (8),A
LD A,%00011111 : OUT (8),A
LD A,%00111000 : OUT (8),A
LD A,%11111000 : OUT (8),A
LD A,%00111111 : OUT (8),A
LD A,%00011111 : OUT (8),A
LD A,%00001111 : OUT (8),A
LD A,%00000000 : OUT (8),A

; Saucer shading pattern (grey layer)
LD A,%11110000 : OUT (8),A
LD A,%11111000 : OUT (8),A
LD A,%00011100 : OUT (8),A
LD A,%00011111 : OUT (8),A
LD A,%11111100 : OUT (8),A
LD A,%11111000 : OUT (8),A
LD A,%11110000 : OUT (8),A
LD A,%00000000 : OUT (8),A

; Additional patterns for the lower shaded reflection
LD A,%00000000 : OUT (8),A
LD A,%00000000 : OUT (8),A
LD A,%00000000 : OUT (8),A
LD A,%00000111 : OUT (8),A
LD A,%11000000 : OUT (8),A
LD A,%00111111 : OUT (8),A
LD A,%00011111 : OUT (8),A
LD A,%00001111 : OUT (8),A

LD A,%00000000 : OUT (8),A
LD A,%00000000 : OUT (8),A
LD A,%00000000 : OUT (8),A
LD A,%11100000 : OUT (8),A
LD A,%00000011 : OUT (8),A
LD A,%11111100 : OUT (8),A
LD A,%11111000 : OUT (8),A
LD A,%11110000 : OUT (8),A

; ------------------------
; Define Sprite Attributes
; ------------------------

LD A,0
OUT (9),A
LD A,123
OUT (9),A

; White layer (highlight)
LD A,100 : OUT (8),A
LD A,120 : OUT (8),A
LD A,0   : OUT (8),A
LD A,15  : OUT (8),A

LD A,100 : OUT (8),A
LD A,128 : OUT (8),A
LD A,1   : OUT (8),A
LD A,15  : OUT (8),A

; Grey layer (shadow)
LD A,100 : OUT (8),A
LD A,120 : OUT (8),A
LD A,2   : OUT (8),A
LD A,14  : OUT (8),A

LD A,100 : OUT (8),A
LD A,128 : OUT (8),A
LD A,3   : OUT (8),A
LD A,14  : OUT (8),A

JP $

Result

When you run this program, you’ll see a flying saucer that appears shaded and slightly three-dimensional. This illusion is created by overlaying two sprite pairs: one white layer providing the bright top surface, and one grey layer adding darker edges and underside reflections.

Although each sprite is still only one colour, the visual blending of white and grey layers creates a composite image with much more depth and realism.

Why This Technique Is Useful

Overlaying sprites to simulate multiple colours expands what’s possible with the TMS9129 hardware. It allows you to:

It’s a technique often used in professional 8-bit games to overcome colour limitations and produce more striking visuals.

Summary

Previous Module
Next Module