You can move values, compare them, loop, branch, point and call — and yet you’ve never done the most ordinary thing a program does: arithmetic. Before you build a game, the last pieces of plain fluency. This one is the most everyday of all: LET x=x+1.
On the Z80 that’s a single instruction:
inc a— add 1 toA.dec atakes 1 away.add a, n— addntoA.sub ntakesnaway.add a, b— add registerBtoA(add two values together).
There’s a catch you already half-know: A holds eight bits, 0–255. Add past 255 and it can’t hold the answer — it wraps round and sets the carry flag: 255 + 1 gives 0, 255 + 2 gives 1. That’s the carry we borrowed in Test, Then Jump; here’s where it comes from. (More in the Try this.)
What you’ll see by the end

A cyan border — colour 5. But we never loaded 5; we computed it: start at 2, count up twice, add one. In a real game the numbers are a score or a position you don’t know ahead of time. Here they’re constants so you can check the sum yourself.
Computing a value
; ============================================================================
; PRIMER — Beat 12: Adding and Taking Away
; ============================================================================
; You've moved values, compared them, looped and branched -- but never done
; the most ordinary thing of all: maths. BASIC's `LET x = x + 1` becomes one
; instruction here.
;
; inc a -- add 1 to A (dec a takes 1 away)
; add a, n -- add n to A (sub n takes n away)
; add a, b -- add register B to A
;
; A holds 8 bits, 0-255. Add past 255 and it wraps round to 0 and sets the
; CARRY flag -- the machine's "it overflowed" signal (the carry we borrowed
; back in Test, Then Jump). We meet it properly in the Try this.
;
; Here we COMPUTE the border colour rather than just loading it: start at 2,
; count up twice, add one -- 5, cyan. In a game the numbers are a score or a
; position you don't know in advance; here they're constants so you can check.
; ============================================================================
org 32768
start:
ld a, 2 ; start at 2
inc a ; + 1 -> 3
inc a ; + 1 -> 4
add a, 1 ; + 1 -> 5 (cyan)
out ($FE), a ; show the computed result
.loop:
halt
jr .loop
end start2, inc to 3, inc to 4, add a, 1 to 5 — then show it. Same shape as loading the border, but the value is worked out instead of written down. That’s the whole difference between a constant and a calculation.
Assemble and run
asm198x --dialect pasmo --cpu z80 --tapbas arithmetic.asm -o primer.tapA cyan border, arrived at by adding.
Try this: past the edge of a byte
Replace the body with ld a, 255 then add a, 1, and watch A in the register view: it reads 0, not 256. A byte can’t hold 256, so it wraps to 0 — and the carry flag is set, the machine flagging “that overflowed.” A jr c would fire on it. This is how you’d catch a score rolling over, and how numbers bigger than a byte are built (next unit but one).
Try this: taking away
Swap in sub: ld a, 6 then sub 2 leaves 4 (green). sub past zero wraps the other way — ld a, 0 then sub 1 gives 255, and sets carry again (this time as a “borrow”). Predict each before you run it.
When it’s wrong, see why
- The assembler errors on
add 1. The 8-bit add names its target: it’sadd a, 1, notadd 1. (sub, oddly, is justsub 1—Ais assumed.) - The border colour is “wrong”. It isn’t — the border shows only the low 3 bits, so any result is shown mod 8. Check the value in the register view for the true answer.
- You expected 256 and got 0. That’s the lesson, not a bug: a byte stops at 255.
What you’ve learnt
inc/add add and dec/sub take away. All four wrap a result past 255 or below 0, but only add and sub set the carry flag, the machine’s overflow signal — inc and dec leave it alone.
What’s next
Sometimes you don’t want to change a whole number — just one bit of it. Next — Working With Bits — and, or and xor let you set, clear and flip individual bits, like switching a single attribute’s BRIGHT on without touching its colour.
Sources
Zilog, Z80 CPU User Manual, UM008011-0816: ADD A, n and SUB s, which set the carry flag on a carry or borrow out of bit 7, and INC r and DEC r, which leave the carry flag unaffected. Sinclair Research, ZX Spectrum BASIC Programming, chapter 23, IN and OUT: the border colour from bits 0–2 of port 254.
Run it here
This unit's program, built for you.
- Program
- primer.tap
- Machine
- ZX Spectrum 48K (PAL)