Score and Turn Display
Count cells, display scores, show whose turn it is. The game gets a proper UI.
Players need to know the score. They need to know whose turn it is.
This unit adds a proper user interface: score display showing how many cells each player owns, and a turn indicator that changes colour with each move. The game starts to feel complete.
Run It
pasmonext --sna inkwar.asm inkwar.sna

Above the board you’ll see:
- P1:00 with a score (red background)
- P2:00 with a score (blue background)
- TURN indicator in the current player’s colour
Claim some cells. Watch the scores update. Watch the turn indicator change colour.
Counting Cells
To display scores, we first need to count them:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
This iterates through all 64 cells of board_state, counting how many belong to each player. The djnz instruction (Decrement and Jump if Not Zero) is perfect for loops - it decrements B and jumps back if B isn’t zero yet.
We store the counts in p1_count and p2_count for display.
Printing Characters
Rather than wrestling with the ROM’s print routines (which need careful system variable setup), we write our own character printing routine. This gives us complete control and teaches more about how the Spectrum works.
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The routine:
- Looks up the character’s pixel data in the ROM character set at $3C00
- Calculates where on screen to draw it using the Spectrum’s quirky display layout
- Copies 8 bytes (one per pixel row) to the display file
The Spectrum’s Screen Layout
The Spectrum’s display file at $4000 has a complex layout. For each character position at row R, column C:
; High byte = $40 + (row/8)*8 + pixel_line
; Low byte = (row%8)*32 + column
The screen is divided into thirds (rows 0-7, 8-15, 16-23), with each pixel row 256 bytes apart. Our print_char routine handles this complexity.
Converting Numbers to Text
Scores are numbers (0-64), but we print characters. To convert:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The conversion is simple: subtract 10 repeatedly to get the tens digit, then add ASCII ‘0’ (48 decimal) to convert digits to printable characters.
For example, the number 23:
- Subtract 10 twice: 23 → 13 → 3 (tens = 2, remainder = 3)
- Tens digit: 2 + ‘0’ = ‘2’ (ASCII 50)
- Units digit: 3 + ‘0’ = ‘3’ (ASCII 51)
The Turn Indicator
A simple “TURN” label that changes colour based on whose turn it is:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
We print the text first, then set the attributes afterwards. The text stays the same - only the background colour changes.
Setting Attribute Ranges
We colour the text by setting attributes for multiple consecutive cells:
set_attr_range:
; A = row, C = start column, B = count, E = attribute
; Calculate address, then write E to B consecutive bytes
This lets us create coloured “badges” for the score labels - red background for P1, blue for P2.
UI Layout Constants
The display positions are defined as constants at the top:
SCORE_ROW equ 2 ; Score display row
P1_SCORE_COL equ 10 ; "P1: nn" column
P2_SCORE_COL equ 18 ; "P2: nn" column
TURN_ROW equ 4 ; Turn indicator row
TURN_COL equ 14 ; Turn indicator column
Changing these moves the entire UI. Want scores at the bottom? Change SCORE_ROW to 20.
Updating After Claims
When a cell is claimed, we update the display:
try_claim:
; ... claim the cell ...
call draw_ui ; Update scores and turn indicator
call update_border
call draw_cursor
The draw_ui routine calls count_cells to recalculate, then redraws the score display and turn indicator. Every claim triggers an update.
The Complete Code
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Try This: Move the UI
Change the position constants:
; Scores at the bottom
SCORE_ROW equ 21
; Turn indicator on the left
TURN_ROW equ 12
TURN_COL equ 2
Try This: Different Colour Scheme
; Green for P1, Magenta for P2
P1_TEXT equ %01100111 ; Green paper, white ink
P2_TEXT equ %01011111 ; Magenta paper, white ink
What You’ve Learnt
- Custom print routine - Direct screen memory access gives full control
- ROM character set - Character data at $3C00, each character is 8 bytes
- Display file layout - Screen memory has complex interleaved addressing
- Number to ASCII - Add ‘0’ (48) to convert a digit to its character code
- Cell counting - Iterate with DJNZ, compare and branch to count categories
- Attribute ranges - Set consecutive attributes to create coloured text backgrounds
What’s Next
In Unit 5, we’ll add proper move validation with feedback - error sounds and visual cues when you try to claim an already-occupied cell.