Skip to content

AZM Book 2 — Z80 Fundamentals99

Exercise Notes

These notes provide the expected result for each chapter exercise.

Chapter 1: The Computer

Parts of the system

ActionActive partsData transferAddress selection
Fetch opcode at $0120CPU and memoryOpcode byte from memory to CPU$0120 selects a memory byte
Read RAM at $8004CPU and memoryStored byte from RAM to CPU$8004 selects a memory byte
Write $3C to port $10CPU and I/O$3C from CPU to peripheralLow address byte $10 selects the port
Add B to ACPUB and A are used internally; the result returns to ANo external address is selected during the arithmetic operation

Instruction fetches still use memory even when the operation itself, such as add a, b, works entirely inside the CPU.

Chapter 2: Machine Code

Decode a byte stream

AddressBytesInstruction
$00003E 12ld a, $12
$000247ld b, a
$00033E 05ld a, $05
$000580add a, b
$000632 10 80ld ($8010), a
$000976halt

The final A is $17, B is $12, and $8010 contains $17.

Chapter 3: Assembly Language

Register trace

Instruction completedABC
ld a, $10$10unchangedunchanged
ld b, a$10$10unchanged
ld a, $06$06$10unchanged
add a, b$16$10unchanged
ld c, a$16$10$16

No instruction in the sequence refers to HL, so HL retains its incoming value.

Chapter 4: Memory Access and Data

Memory form identification

InstructionLD formMemory actionAddress source
ld a, (hl)reg8 ← (HL)Read one byteHL
ld (hl), b(HL) ← reg8Write one byteHL
ld a, (bc)A ← (BC)Read one byteBC
ld ($8010), a(nn) ← AWrite one byteFixed address $8010
ld de, ($8020)reg16 ← (nn)Read two bytesFixed address $8020

The final form reads the low byte from $8020 and the high byte from $8021.

Chapter 5: Flags, Comparisons and Jumps

Flag prediction

SequenceFinal AZC
ld a, 5 / cp 55SetClear
ld a, 5 / cp 65ClearSet
ld a, 5 / cp 35ClearClear
ld a, 0 / xor a0SetClear
Previous sequence followed by dec a$FFClearClear

cp preserves A. dec changes Z but leaves the carry state supplied by xor a.

Chapter 6: Counting Loops and DJNZ

The zero-count case

Runtime countIterationsFinal BFinal byte counter
025600 after wrapping through 256 increments
1101
2552550255

The guard tests A before copying it to B. A zero result branches around the body; a non-zero result loads B and enters the loop. The test cases should then produce 0, 1 and 255 iterations.

Chapter 7: Data Tables and Indexed Access

Address, value and final pointer

ld hl, scores loads $8000; ld a, (scores) loads 10 ($0A). Six increments leave HL at $8006. The next byte is $01, the first byte of records, and is outside scores.

Chapter 8: Stack and Subroutines

Stack trace

InstructionSP afterwardStack transfer
push af$BFFE$34 to $BFFE, $12 to $BFFF
push bc$BFFC$78 to $BFFC, $56 to $BFFD
pop de$BFFEDE receives $5678
pop hl$C000HL receives $1234

The final values are DE = $5678, HL = $1234 and SP = $C000.

Chapter 9: I/O and Ports

Flag behaviour of in

The immediate form needs an explicit test:

asm
in a, (IN_PORT)
or a
jr z, is_zero

Starting with Z clear and carry set, the immediate read leaves both flags unchanged. Reading $00 therefore leaves Z clear and carry set until or a sets Z and clears carry. Reading $80 also leaves the initial flags after in; or a leaves Z clear and clears carry.

The register-addressed form can branch directly:

asm
in a, (C)
jr z, is_zero

Reading $00 sets Z; reading $80 clears Z. The carry flag remains set in both tests because in r, (C) preserves it.

Chapter 10: A Complete Program

A find_max trace

IterationCA before cpCarryUpdateA after
1230SetYes23
24723SetYes47
39147SetYes91
4591ClearNo91
56791ClearNo91
61291ClearNo91
78891ClearNo91
83491ClearNo91

The routine returns A = 91, B = 0 and HL = $8008. max_val receives 91 ($5B).

Chapter 11: Subroutine Conventions

Push/pop order

The matching epilogue is:

asm
pop af
pop hl
pop bc

It restores AF = $3344, HL = $2222, BC = $1111 and SP = $C000. Using pop bc / pop hl / pop af also balances SP, but produces BC = $3344, HL = $2222 and AF = $1111.