Score
The panel now shows 'saved / total' — three glyphs drawn by a shared subroutine. A slash glyph joins two digits, giving the player a clear goal.
The panel shows a single digit, but there’s no context. How many creatures are there in total? In this unit, the display expands from one digit to a “saved / total” readout — three glyphs drawn by a shared subroutine.

The panel now reads “0/3” — zero saved out of three. As creatures reach the exit, the first digit updates. The slash and total are drawn once at the start and never change.
Three Glyphs, One Subroutine
The previous unit drew a single digit with a dedicated routine. Now we need three glyphs at different positions — a digit, a slash, and another digit. Rather than duplicating the drawing code, we split it into two layers:
;──────────────────────────────────────────────────────────────
; draw_panel_digit — Draw digit D0 at x position D1
;──────────────────────────────────────────────────────────────
draw_panel_digit:
cmp.w #9,d0
ble.s .ok
move.w #9,d0
.ok:
lsl.w #3,d0 ; * 8 bytes per glyph
lea font_digits,a1
add.w d0,a1
; Fall through to draw_panel_glyph
;──────────────────────────────────────────────────────────────
; draw_panel_glyph — Draw 8x8 glyph at A1, x position D1
;──────────────────────────────────────────────────────────────
draw_panel_glyph:
lea panel_bitplane,a0
add.w #PANEL_DIGIT_Y*BYTES_PER_ROW,a0
move.w d1,d2
lsr.w #3,d2
add.w d2,a0
moveq #7,d3
.draw:
move.b (a1)+,(a0)
add.w #BYTES_PER_ROW,a0
dbra d3,.draw
rts
draw_panel_digit converts a number into a glyph pointer, then falls through to draw_panel_glyph. The fall-through is a common 68000 pattern — when one subroutine’s last action is to call another, you skip the BSR and let execution flow directly into the next routine. No stack overhead, no wasted cycles.
draw_panel_glyph takes a glyph pointer in A1 and an x position in D1. It works with any 8x8 glyph — digits, letters, symbols. The same 8-byte copy loop draws everything.
The Score Display
The draw_saved_count subroutine calls the drawing routines three times:
;──────────────────────────────────────────────────────────────
; draw_saved_count — Draw "saved / total" in the panel
;──────────────────────────────────────────────────────────────
draw_saved_count:
; Draw saved digit
move.w saved_count,d0
move.w #PANEL_SAVED_X,d1
bsr draw_panel_digit
; Draw slash
lea font_slash,a1
move.w #PANEL_SLASH_X,d1
bsr draw_panel_glyph
; Draw total digit
move.w #NUM_CREATURES,d0
move.w #PANEL_TOTAL_X,d1
bsr draw_panel_digit
rts
Three positions are defined as constants:
PANEL_SAVED_X equ 144 ; Saved digit
PANEL_SLASH_X equ 152 ; Slash separator
PANEL_TOTAL_X equ 160 ; Total digit
Each glyph is 8 pixels wide, so they’re spaced 8 pixels apart. The total digit uses NUM_CREATURES directly — it never changes, so there’s no variable to track.
The Slash Glyph
A new font entry draws the separator:
font_slash:
dc.b %00000010
dc.b %00000100
dc.b %00001000
dc.b %00010000
dc.b %00100000
dc.b %01000000
dc.b %10000000
dc.b %00000000
One diagonal line of pixels, bottom-left to top-right. Simple, readable, and drawn by the same draw_panel_glyph routine that handles digits.
The Complete Code
;──────────────────────────────────────────────────────────────
; EXODUS - A terrain puzzle for the Commodore Amiga
; Unit 13: Score Display
;
; The panel shows "saved / total" as two digits with a slash.
; The score updates live as creatures reach the exit.
;──────────────────────────────────────────────────────────────
;══════════════════════════════════════════════════════════════
; TWEAKABLE VALUES
;══════════════════════════════════════════════════════════════
COLOUR_SKY_DEEP equ $0016
COLOUR_SKY_UPPER equ $0038
COLOUR_SKY_MID equ $005B
COLOUR_SKY_LOWER equ $007D
COLOUR_SKY_HORIZON equ $009E
COLOUR_TERRAIN equ $0741
COLOUR_PANEL_BG equ $0223
COLOUR_PANEL_FG equ $0FFF
COLOUR_SPR0_1 equ $0FFF
COLOUR_SPR0_2 equ $0F80
COLOUR_SPR0_3 equ $0000
CREATURE_SPEED equ 1
FALL_SPEED equ 2
FOOT_OFFSET_X equ 8
FOOT_OFFSET_Y equ 12
STEP_PERIOD equ 400
STEP_VOLUME equ 48
NUM_CREATURES equ 3
; Creature data table offsets
CR_X equ 0
CR_Y equ 2
CR_DX equ 4
CR_STATE equ 6
CR_STEP equ 8
CR_SIZE equ 10
STATE_WALKING equ 0
STATE_FALLING equ 1
STATE_SAVED equ 2
; Exit zone
EXIT_X equ 280
EXIT_Y equ 108
EXIT_W equ 24
EXIT_H equ 12
; Panel
PANEL_Y equ 200 ; Scanline where panel starts
PANEL_SAVED_X equ 144 ; X position for saved digit (byte-aligned)
PANEL_SLASH_X equ 152 ; X position for slash
PANEL_TOTAL_X equ 160 ; X position for total digit
PANEL_DIGIT_Y equ 4 ; Y offset within panel bitplane
; Terrain
GROUND_L_X equ 0
GROUND_L_Y equ 152
GROUND_L_W equ 128
GROUND_L_H equ 48
GROUND_R_X equ 128
GROUND_R_Y equ 120
GROUND_R_W equ 192
GROUND_R_H equ 80
PLATFORM_X equ 24
PLATFORM_Y equ 104
PLATFORM_W equ 72
PLATFORM_H equ 8
;══════════════════════════════════════════════════════════════
; DISPLAY CONSTANTS
;══════════════════════════════════════════════════════════════
SCREEN_WIDTH equ 320
SCREEN_HEIGHT equ 200 ; Game area only (panel below)
BYTES_PER_ROW equ SCREEN_WIDTH/8
BITPLANE_SIZE equ BYTES_PER_ROW*SCREEN_HEIGHT
PANEL_HEIGHT equ 56
PANEL_SIZE equ BYTES_PER_ROW*PANEL_HEIGHT
SPRITE_HEIGHT equ 12
STEP_INTERVAL equ 8
;══════════════════════════════════════════════════════════════
; HARDWARE REGISTERS
;══════════════════════════════════════════════════════════════
CUSTOM equ $dff000
DMACON equ $096
INTENA equ $09a
INTREQ equ $09c
COP1LC equ $080
COPJMP1 equ $088
BPLCON0 equ $100
BPLCON1 equ $102
BPLCON2 equ $104
BPL1MOD equ $108
DIWSTRT equ $08e
DIWSTOP equ $090
DDFSTRT equ $092
DDFSTOP equ $094
BPL1PTH equ $0e0
BPL1PTL equ $0e2
SPR0PTH equ $120
SPR0PTL equ $122
SPR1PTH equ $124
SPR1PTL equ $126
SPR2PTH equ $128
SPR2PTL equ $12a
COLOR00 equ $180
COLOR01 equ $182
COLOR17 equ $1a2
COLOR18 equ $1a4
COLOR19 equ $1a6
VPOSR equ $004
AUD0LC equ $0a0
AUD0LEN equ $0a4
AUD0PER equ $0a6
AUD0VOL equ $0a8
;══════════════════════════════════════════════════════════════
; CODE (Chip RAM)
;══════════════════════════════════════════════════════════════
section code,code_c
start:
lea CUSTOM,a5
move.w #$7fff,INTENA(a5)
move.w #$7fff,INTREQ(a5)
move.w #$7fff,DMACON(a5)
; --- Initialise creatures ---
lea creatures,a0
move.w #80,CR_X(a0)
move.w #92,CR_Y(a0)
move.w #CREATURE_SPEED,CR_DX(a0)
move.w #STATE_WALKING,CR_STATE(a0)
move.w #0,CR_STEP(a0)
move.w #16,CR_X+CR_SIZE(a0)
move.w #140,CR_Y+CR_SIZE(a0)
move.w #CREATURE_SPEED,CR_DX+CR_SIZE(a0)
move.w #STATE_WALKING,CR_STATE+CR_SIZE(a0)
move.w #4,CR_STEP+CR_SIZE(a0)
move.w #160,CR_X+CR_SIZE*2(a0)
move.w #108,CR_Y+CR_SIZE*2(a0)
move.w #CREATURE_SPEED,CR_DX+CR_SIZE*2(a0)
move.w #STATE_WALKING,CR_STATE+CR_SIZE*2(a0)
move.w #2,CR_STEP+CR_SIZE*2(a0)
move.w #0,saved_count
; --- Draw terrain ---
move.w #GROUND_L_X,d0
move.w #GROUND_L_Y,d1
move.w #GROUND_L_W,d2
move.w #GROUND_L_H,d3
bsr draw_rect
move.w #GROUND_R_X,d0
move.w #GROUND_R_Y,d1
move.w #GROUND_R_W,d2
move.w #GROUND_R_H,d3
bsr draw_rect
move.w #PLATFORM_X,d0
move.w #PLATFORM_Y,d1
move.w #PLATFORM_W,d2
move.w #PLATFORM_H,d3
bsr draw_rect
; Exit marker
move.w #EXIT_X,d0
move.w #EXIT_Y,d1
move.w #EXIT_W,d2
move.w #1,d3
bsr draw_rect
move.w #EXIT_X,d0
move.w #EXIT_Y+EXIT_H-1,d1
move.w #EXIT_W,d2
move.w #1,d3
bsr draw_rect
; --- Draw initial digit in panel ---
bsr draw_saved_count
; --- Patch bitplane pointer ---
lea bitplane,a0
move.l a0,d0
swap d0
lea bpl1pth_val,a1
move.w d0,(a1)
swap d0
lea bpl1ptl_val,a1
move.w d0,(a1)
; --- Patch panel bitplane pointer ---
lea panel_bitplane,a0
move.l a0,d0
swap d0
lea panel_bpl1pth_val,a1
move.w d0,(a1)
swap d0
lea panel_bpl1ptl_val,a1
move.w d0,(a1)
; --- Patch sprite pointers ---
lea sprite0_data,a0
move.l a0,d0
swap d0
lea spr0pth_val,a1
move.w d0,(a1)
swap d0
lea spr0ptl_val,a1
move.w d0,(a1)
lea sprite1_data,a0
move.l a0,d0
swap d0
lea spr1pth_val,a1
move.w d0,(a1)
swap d0
lea spr1ptl_val,a1
move.w d0,(a1)
lea sprite2_data,a0
move.l a0,d0
swap d0
lea spr2pth_val,a1
move.w d0,(a1)
swap d0
lea spr2ptl_val,a1
move.w d0,(a1)
; --- Install Copper list ---
lea copperlist,a0
move.l a0,COP1LC(a5)
move.w d0,COPJMP1(a5)
; --- Enable DMA ---
move.w #$83a1,DMACON(a5)
; === Main Loop ===
mainloop:
move.l #$1ff00,d1
.vbwait:
move.l VPOSR(a5),d0
and.l d1,d0
bne.s .vbwait
; --- Process all creatures ---
lea creatures,a2
moveq #NUM_CREATURES-1,d7
.creature_loop:
move.w saved_count,d6 ; Remember count before update
bsr update_creature
add.w #CR_SIZE,a2
dbra d7,.creature_loop
; --- Redraw count if changed ---
move.w saved_count,d0
cmp.w d6,d0
beq.s .no_redraw
bsr draw_saved_count
.no_redraw:
; --- Update sprites ---
lea creatures,a2
lea sprite0_data,a0
bsr write_sprite_pos
lea creatures+CR_SIZE,a2
lea sprite1_data,a0
bsr write_sprite_pos
lea creatures+CR_SIZE*2,a2
lea sprite2_data,a0
bsr write_sprite_pos
btst #6,$bfe001
bne mainloop
.halt:
bra.s .halt
;──────────────────────────────────────────────────────────────
; update_creature — Update one creature (A2 = creature data)
;──────────────────────────────────────────────────────────────
update_creature:
move.w CR_STATE(a2),d0
cmp.w #STATE_SAVED,d0
beq .done
cmp.w #STATE_FALLING,d0
beq .do_fall
; --- Walking ---
move.w CR_X(a2),d0
add.w CR_DX(a2),d0
add.w #FOOT_OFFSET_X,d0
move.w CR_Y(a2),d1
add.w #FOOT_OFFSET_Y,d1
bsr check_pixel
tst.b d0
beq.s .walk_no_floor
move.w CR_X(a2),d0
add.w CR_DX(a2),d0
move.w d0,CR_X(a2)
bsr check_exit
move.w CR_STEP(a2),d0
subq.w #1,d0
bgt.s .no_step
bsr play_step
move.w #STEP_INTERVAL,d0
.no_step:
move.w d0,CR_STEP(a2)
move.w CR_X(a2),d0
add.w #FOOT_OFFSET_X,d0
move.w CR_Y(a2),d1
add.w #FOOT_OFFSET_Y,d1
bsr check_pixel
tst.b d0
bne.s .done
move.w #STATE_FALLING,CR_STATE(a2)
bra.s .done
.walk_no_floor:
neg.w CR_DX(a2)
bra.s .done
; --- Falling ---
.do_fall:
move.w CR_Y(a2),d0
add.w #FALL_SPEED,d0
cmp.w #SCREEN_HEIGHT-SPRITE_HEIGHT,d0
blt.s .fall_ok
move.w #SCREEN_HEIGHT-SPRITE_HEIGHT,d0
move.w d0,CR_Y(a2)
move.w #STATE_WALKING,CR_STATE(a2)
bra.s .done
.fall_ok:
move.w d0,CR_Y(a2)
move.w CR_X(a2),d0
add.w #FOOT_OFFSET_X,d0
move.w CR_Y(a2),d1
add.w #FOOT_OFFSET_Y,d1
bsr check_pixel
tst.b d0
beq.s .done
move.w #STATE_WALKING,CR_STATE(a2)
.done:
rts
;──────────────────────────────────────────────────────────────
; check_exit — Test if creature is inside the exit zone
;──────────────────────────────────────────────────────────────
check_exit:
move.w CR_X(a2),d0
add.w #FOOT_OFFSET_X,d0
cmp.w #EXIT_X,d0
blt.s .not_in
cmp.w #EXIT_X+EXIT_W,d0
bge.s .not_in
move.w CR_Y(a2),d1
add.w #FOOT_OFFSET_Y,d1
cmp.w #EXIT_Y,d1
blt.s .not_in
cmp.w #EXIT_Y+EXIT_H,d1
bge.s .not_in
move.w #STATE_SAVED,CR_STATE(a2)
addq.w #1,saved_count
move.w #0,CR_Y(a2)
.not_in:
rts
;──────────────────────────────────────────────────────────────
; draw_score — Draw "saved / total" in the panel
;──────────────────────────────────────────────────────────────
draw_saved_count:
; Draw saved digit
move.w saved_count,d0
move.w #PANEL_SAVED_X,d1
bsr draw_panel_digit
; Draw slash
lea font_slash,a1
move.w #PANEL_SLASH_X,d1
bsr draw_panel_glyph
; Draw total digit
move.w #NUM_CREATURES,d0
move.w #PANEL_TOTAL_X,d1
bsr draw_panel_digit
rts
;──────────────────────────────────────────────────────────────
; draw_panel_digit — Draw digit D0 at x position D1
;──────────────────────────────────────────────────────────────
draw_panel_digit:
cmp.w #9,d0
ble.s .ok
move.w #9,d0
.ok:
lsl.w #3,d0 ; * 8 bytes per glyph
lea font_digits,a1
add.w d0,a1
; Fall through to draw_panel_glyph
;──────────────────────────────────────────────────────────────
; draw_panel_glyph — Draw 8x8 glyph at A1, x position D1
;──────────────────────────────────────────────────────────────
draw_panel_glyph:
lea panel_bitplane,a0
add.w #PANEL_DIGIT_Y*BYTES_PER_ROW,a0
move.w d1,d2
lsr.w #3,d2
add.w d2,a0
moveq #7,d3
.draw:
move.b (a1)+,(a0)
add.w #BYTES_PER_ROW,a0
dbra d3,.draw
rts
;──────────────────────────────────────────────────────────────
; write_sprite_pos — Write position from creature data to sprite
;──────────────────────────────────────────────────────────────
write_sprite_pos:
move.w CR_STATE(a2),d0
cmp.w #STATE_SAVED,d0
beq.s .hide
move.w CR_Y(a2),d0
add.w #$2c,d0
move.w d0,d1
add.w #SPRITE_HEIGHT,d1
move.w CR_X(a2),d2
add.w #$80,d2
move.b d0,d3
lsl.w #8,d3
move.w d2,d4
lsr.w #1,d4
or.b d4,d3
move.w d3,(a0)+
move.b d1,d3
lsl.w #8,d3
moveq #0,d4
btst #8,d0
beq.s .no_vs8
bset #2,d4
.no_vs8:
btst #8,d1
beq.s .no_ve8
bset #1,d4
.no_ve8:
btst #0,d2
beq.s .no_h0
bset #0,d4
.no_h0:
or.b d4,d3
move.w d3,(a0)
rts
.hide:
move.w #0,(a0)+
move.w #0,(a0)
rts
;──────────────────────────────────────────────────────────────
; play_step — Trigger the footstep sample on Paula channel 0
;──────────────────────────────────────────────────────────────
play_step:
lea CUSTOM,a6
lea step_sample,a0
move.l a0,AUD0LC(a6)
move.w #STEP_SAMPLE_LEN/2,AUD0LEN(a6)
move.w #STEP_PERIOD,AUD0PER(a6)
move.w #STEP_VOLUME,AUD0VOL(a6)
move.w #$8201,DMACON(a6)
rts
;──────────────────────────────────────────────────────────────
; check_pixel — Test a single pixel in the bitplane
;──────────────────────────────────────────────────────────────
check_pixel:
lea bitplane,a0
mulu #BYTES_PER_ROW,d1
add.l d1,a0
move.w d0,d2
lsr.w #3,d2
add.w d2,a0
not.w d0
and.w #7,d0
btst d0,(a0)
sne d0
and.b #1,d0
rts
;──────────────────────────────────────────────────────────────
; draw_rect — Fill a byte-aligned rectangle in the bitplane
;──────────────────────────────────────────────────────────────
draw_rect:
lea bitplane,a0
mulu #BYTES_PER_ROW,d1
add.l d1,a0
lsr.w #3,d0
add.w d0,a0
lsr.w #3,d2
subq.w #1,d3
.row:
move.w d2,d5
subq.w #1,d5
move.l a0,a1
.col:
move.b #$ff,(a1)+
dbra d5,.col
add.w #BYTES_PER_ROW,a0
dbra d3,.row
rts
;══════════════════════════════════════════════════════════════
; FONT — 8x8 digit glyphs (0-9)
;══════════════════════════════════════════════════════════════
font_digits:
; 0
dc.b %00111100
dc.b %01100110
dc.b %01101110
dc.b %01110110
dc.b %01100110
dc.b %01100110
dc.b %00111100
dc.b %00000000
; 1
dc.b %00011000
dc.b %00111000
dc.b %00011000
dc.b %00011000
dc.b %00011000
dc.b %00011000
dc.b %01111110
dc.b %00000000
; 2
dc.b %00111100
dc.b %01100110
dc.b %00000110
dc.b %00001100
dc.b %00110000
dc.b %01100000
dc.b %01111110
dc.b %00000000
; 3
dc.b %00111100
dc.b %01100110
dc.b %00000110
dc.b %00011100
dc.b %00000110
dc.b %01100110
dc.b %00111100
dc.b %00000000
; 4
dc.b %00001100
dc.b %00011100
dc.b %00101100
dc.b %01001100
dc.b %01111110
dc.b %00001100
dc.b %00001100
dc.b %00000000
; 5
dc.b %01111110
dc.b %01100000
dc.b %01111100
dc.b %00000110
dc.b %00000110
dc.b %01100110
dc.b %00111100
dc.b %00000000
; 6
dc.b %00111100
dc.b %01100110
dc.b %01100000
dc.b %01111100
dc.b %01100110
dc.b %01100110
dc.b %00111100
dc.b %00000000
; 7
dc.b %01111110
dc.b %01100110
dc.b %00001100
dc.b %00011000
dc.b %00011000
dc.b %00011000
dc.b %00011000
dc.b %00000000
; 8
dc.b %00111100
dc.b %01100110
dc.b %01100110
dc.b %00111100
dc.b %01100110
dc.b %01100110
dc.b %00111100
dc.b %00000000
; 9
dc.b %00111100
dc.b %01100110
dc.b %01100110
dc.b %00111110
dc.b %00000110
dc.b %01100110
dc.b %00111100
dc.b %00000000
font_slash:
dc.b %00000010
dc.b %00000100
dc.b %00001000
dc.b %00010000
dc.b %00100000
dc.b %01000000
dc.b %10000000
dc.b %00000000
;══════════════════════════════════════════════════════════════
; COPPER LIST
;══════════════════════════════════════════════════════════════
copperlist:
dc.w DIWSTRT,$2c81
dc.w DIWSTOP,$2cc1
dc.w DDFSTRT,$0038
dc.w DDFSTOP,$00d0
dc.w BPLCON0,$1200
dc.w BPLCON1,$0000
dc.w BPLCON2,$0000
dc.w BPL1MOD,$0000
dc.w BPL1PTH
bpl1pth_val:
dc.w $0000
dc.w BPL1PTL
bpl1ptl_val:
dc.w $0000
dc.w SPR0PTH
spr0pth_val:
dc.w $0000
dc.w SPR0PTL
spr0ptl_val:
dc.w $0000
dc.w SPR1PTH
spr1pth_val:
dc.w $0000
dc.w SPR1PTL
spr1ptl_val:
dc.w $0000
dc.w SPR2PTH
spr2pth_val:
dc.w $0000
dc.w SPR2PTL
spr2ptl_val:
dc.w $0000
dc.w COLOR00,COLOUR_SKY_DEEP
dc.w COLOR01,COLOUR_TERRAIN
dc.w COLOR17,COLOUR_SPR0_1
dc.w COLOR18,COLOUR_SPR0_2
dc.w COLOR19,COLOUR_SPR0_3
dc.w $3401,$fffe
dc.w COLOR00,COLOUR_SKY_UPPER
dc.w $4401,$fffe
dc.w COLOR00,COLOUR_SKY_MID
dc.w $5401,$fffe
dc.w COLOR00,COLOUR_SKY_LOWER
dc.w $6001,$fffe
dc.w COLOR00,COLOUR_SKY_HORIZON
dc.w $6801,$fffe
dc.w COLOR00,$0000
; --- Panel screen split ---
; Wait for panel scanline ($2c + 200 = $E4)
dc.w $e401,$fffe
dc.w COLOR00,COLOUR_PANEL_BG
dc.w COLOR01,COLOUR_PANEL_FG
dc.w BPL1PTH
panel_bpl1pth_val:
dc.w $0000
dc.w BPL1PTL
panel_bpl1ptl_val:
dc.w $0000
dc.w $ffff,$fffe
;══════════════════════════════════════════════════════════════
; SPRITE DATA
;══════════════════════════════════════════════════════════════
even
sprite0_data:
dc.w $0000,$0000
dc.w %0000011111100000,%0000000000000000
dc.w %0000111111110000,%0000011111100000
dc.w %0001111111111000,%0000111111110000
dc.w %0001101110111000,%0001111111111000
dc.w %0001111111111000,%0000111111110000
dc.w %0000111001110000,%0000011111100000
dc.w %0000011111100000,%0000000000000000
dc.w %0001111111111000,%0000011111100000
dc.w %0001111111111000,%0000111111110000
dc.w %0001111111111000,%0000111111110000
dc.w %0000110000110000,%0000000000000000
dc.w %0000110000110000,%0000000000000000
dc.w $0000,$0000
even
sprite1_data:
dc.w $0000,$0000
dc.w %0000011111100000,%0000000000000000
dc.w %0000111111110000,%0000011111100000
dc.w %0001111111111000,%0000111111110000
dc.w %0001101110111000,%0001111111111000
dc.w %0001111111111000,%0000111111110000
dc.w %0000111001110000,%0000011111100000
dc.w %0000011111100000,%0000000000000000
dc.w %0001111111111000,%0000011111100000
dc.w %0001111111111000,%0000111111110000
dc.w %0001111111111000,%0000111111110000
dc.w %0000110000110000,%0000000000000000
dc.w %0000110000110000,%0000000000000000
dc.w $0000,$0000
even
sprite2_data:
dc.w $0000,$0000
dc.w %0000011111100000,%0000000000000000
dc.w %0000111111110000,%0000011111100000
dc.w %0001111111111000,%0000111111110000
dc.w %0001101110111000,%0001111111111000
dc.w %0001111111111000,%0000111111110000
dc.w %0000111001110000,%0000011111100000
dc.w %0000011111100000,%0000000000000000
dc.w %0001111111111000,%0000011111100000
dc.w %0001111111111000,%0000111111110000
dc.w %0001111111111000,%0000111111110000
dc.w %0000110000110000,%0000000000000000
dc.w %0000110000110000,%0000000000000000
dc.w $0000,$0000
;══════════════════════════════════════════════════════════════
; STEP SAMPLE
;══════════════════════════════════════════════════════════════
even
step_sample:
dc.b $60,$40,$20,$10,$08,$04,$02,$01
dc.b $fe,$fc,$f8,$f0,$e0,$d0,$c0,$b0
dc.b $50,$30,$18,$0c,$06,$03,$01,$00
dc.b $ff,$fd,$fa,$f4,$e8,$d8,$c8,$b8
STEP_SAMPLE_LEN equ *-step_sample
;══════════════════════════════════════════════════════════════
; VARIABLES
;══════════════════════════════════════════════════════════════
even
creatures:
dcb.b CR_SIZE*NUM_CREATURES,0
saved_count:
dc.w 0
;══════════════════════════════════════════════════════════════
; BITPLANE DATA
;══════════════════════════════════════════════════════════════
even
bitplane:
dcb.b BITPLANE_SIZE,0
even
panel_bitplane:
dcb.b PANEL_SIZE,0
If It Doesn’t Work
- Only one digit shows? Check that all three
bsrcalls use the correct x positions. The saved digit, slash, and total must be at differentPANEL_*_Xvalues. - Slash doesn’t appear? Make sure
font_slashis defined afterfont_digitsand contains exactly 8 bytes. - Total shows wrong number? The total digit draws
NUM_CREATURES, notsaved_count. Check thatNUM_CREATURESis 3.
What You’ve Learnt
- Fall-through subroutines — when one routine’s last action is calling another, skip the
BSRand let execution flow directly. Saves stack operations and keeps code compact. - Generic drawing routines —
draw_panel_glyphhandles any 8x8 glyph. The same code draws digits, slashes, and any future characters. - Multi-glyph displays — combining several glyph draws at different x positions to build a readable status readout.
What’s Next
The score shows progress, but the game never ends. In Unit 14, we’ll add level completion — when every creature has been saved or lost, the result is displayed and the game state changes.