CHAPTER 01CPU Architecture — Z80A
Full ISA
Main opcodes (8080 subset + extras) CB prefix — bit/rotate/shift (BIT b,r = CB 40 + 8*b + r) DD prefix (IX) + FD prefix (IY) indexed with displacement ED prefix — extended/block/I/O (LDIR = ED B0, IM n)
RegistersA/F, B/C, D/E, H/L + shadow set (A'/F', BC', DE', HL' via EX AF,AF' / EXX). IX, IY, SP, PC, I (IM2), R (refresh). Addressing modes: register, immediate, (HL), (IX+d), nn, relative (JR), extended.
Interrupt modes (IM n)
IM0device-supplied RST IM1: fixed RST 38h IM2: vectored (I<<8 | vector_byte) (even) Coleco VDP INT wired to NMI (vector 0066h).
T-States Table (common recomp paths)
NOP4T LD r,n: 7T LD r,(IX+d): 19T LDIR: 21T/byte IN r,(C): 12T OUT (C),r: 12T BIT b,(IX+d): 20T (with YF/XF from address high byte)
Key 8080 differencesIX/IY, JR, LDIR/CPIR, BIT/SET/RES, IM2, shadow registers.
Flag Behavior (S Z YF H XF P/V N C + undocumented YF/XF)
Recomp NotePrefix-aware translator + YF/XF tracking; T-state budgeting for busy-wait elimination.
CHAPTER 02VDP — TMS9928A
8 write-only registers (via $BFlow addr, high | 0x80 | reg#):
R0M3 (mode) R1: 4/16K, BLANK, IE, M2/M1, SIZE (16×16), MAG (×2) R2: Name table base <<10 R3: Color table base <<6 R4: Pattern base <<11 R5: Sprite attr base <<7 R6: Sprite pattern base <<11 R7: Text color / backdrop
Display modesGraphics I, Graphics II (3-segment), Multicolor, Text.
VRAM Address Formulas (14-bit)
Name table(R2<<10) + (Y>>3)*32 + (X>>3) Graphics II color/pattern (per section):SECTION = Y >> 6 PATTERN_ADDR = (R4<<11) + (SECTION<<11) + (NAME<<3) + (Y&7) COLOR_ADDR = (R3<<6) + (SECTION<<11) + ((Y&0x38)<<2) + (X>>3)
Sprite System32 sprites, hard 4-per-scanline limit (5th sets bit6 + index). Priority = SAT table order. Attribute table (4 bytes):
Byte 0Y (208=off) Byte 1: X Byte 2: Pattern Byte 3: Color (0-15) + bit7 = early-clock (X -= 32)
Size/Mag (R1)
8×8 or 16×16 (even pattern = TL) MAG=1 → ×2 (32×32 effective)
Status Register ($BF read)bit7=VINT (cleared immediately), bit6=5S, bit5=C (collision). Access Protocol: $BE data, $BF command. Two-byte address set must be atomic (NMI semaphore). Graphics II Dual-Fetch Timing: Name + color every scanline (~3 µs contention). Safe window requires 24T+ padding: di; out $BF,low; out $BF,high|0x40; nop×6; in/out $BE; ei Sprite Collision / 5S Per-Pixel Timing: Evaluated during HBLANK; collision latched on first pixel overlap. Recomp host renderer must simulate SAT-order scanline queue.
CHAPTER 03Memory Map
Z80 Space
$0000–$1FFF- 8KB BIOS ROM
$6000–$63FF- 1KB SRAM (mirrored ×8 to $7FFF)
$8000–$FFFF- Cart ROM (header at $8000)
I/O
$BE/$BF- VDP
$FF- SN76489
$80–$9F- Keypad strobe
$C0–$DF- Joystick strobe
$E0–$FF- Controller read
Adam Expansion
$7F- Bankswitch (D0-D1 lower, D2-D3 upper; 4 options each)
64KB intrinsic RAM shadow AdamNet DCB at $FFxx
Expansion Port $2000–$5FFFOpen bus (base) or Adam RAM.
CHAPTER 04Audio — SN76489
3 square + 1 noise channels. Write $FF. Latch1 ccc t dddd (t=0 freq / 1 volume). Frequency: $ f = \frac{3579545}{32 \times n} $ (10-bit n).
0 = 0 dB … 14 = -28 dB … 15 = off (binary-weighted 2/4/8/16 dB). Noise: FB (periodic/white), NF (512/1024/2048/tone3). 15-bit LFSR init 0x4000.
Full State Machine (per-clock)
void psg_clock_tick() { // tone reload on latch, toggle on zero // noise: fb = lfsr&1 ^ ((lfsr>>1)&white); lfsr = (fb<<14)|(lfsr>>1) } DC-offset PCM: period=1 + rapid volume writes (125 kHz).
VGM Converter (with T-state budget)
if (vgm[pc] == 0x50) { ld a,val; out ($FF),a; budget += 19T; }
CHAPTER 05BIOS
8KB OS7 ($0000) + optional EOS (Adam).
Startup Sequence (~220T base, +720T Adam)
Reset → VDP init → copyright → cart sig ($8000 AA55/55AA) → jump $800A or title screen. Adam detection via $7F + signature.
Key Jump Table (selected)
$1F76- CONTROLLER_SCAN (~68T)
$1FEB- POLLER (~142T)
$1F61- PLAY_SONGS
$1FF4- SOUND_MAN (~110T/frame)
$1FEE- SOUND_INIT
$1FF1- PLAY_IT
Cart Header ($8000)
AA55/55AA, pointers, program start $800A, RST trampolines $800C+, NMI $8021. Sound Format (PLAY_SONGS): pointer table → count → command bytes (freq/vol/delay/sweep). Parser inlined in recomp. Required? Heavily used; recomp can stub or preserve calls. EOS HARD_INIT (~850T): AdamNet sync + device scan.
CHAPTER 06I/O & Controllers
Protocol
Strobe $80–$9F (keypad) or $C0–$DF (joystick) 5× IN $FF (raw matrix) after 4µs delay BIOS POLLER/DECODER → bitflags in $73D7+
Super Action / Roller / Steering
Extra fires (bits 6-7) Quadrature INT → signed delta ($73EB/$73EC) Debounce: 4-frame moving average
Host Mapping Table (with curves)
Roller/Steeringclamp(analog 3.5 (1 + |analog|*0.2), -3, 3) Extra fires: digital with debounce filter Deadzone 0.08
CHAPTER 07Recompilation Notes
Core Strategy
Trap every IN/OUT ($BE/$BF/$FF/$80–$DF/$7F) → host callbacks with exact T-state delta NMI semaphore for two-byte VDP address setup Cart header patching (RST/NMI vectors → host stubs) BIOS RAM overlays ($7020–$702A sound, $73EB spinner, $73EE raw) resolved via static data-flow graph Flag preservation (YF/XF on BIT/ADD/etc.) Sprite renderer: SAT-order queue + 4/line drop + early-clock + SIZE/MAG Sound: full parser + VGM converter + LFSR/PCM exact
Adam expansionbankswitch state machine + AdamNet packet/DMA traps + 64KB intrinsic RAM shadow VDP contention/GII timing: 24T+ padding or blank-window only Controller/roller: quadrature delta injection + debounce filter
Example I/O Trap
void vdp_safe_addr(uint16_t a) { di(); out($BF,low); out($BF,high|0x40); ei(); }
AdamNet DCB + Packet Trap
DCB structure at fixed RAM PacketLEN/CMD/DATA/CHECKSUM DMA memcpy for READ_BLOCK/SEND_BLOCK
Binary patcher for all BIOS calls + I/O + headers Host MMU for mirrors/banking Cycle-accurate PSG + VDP + input emulation Overlay conflict resolver + priority graph (sound vs NMI)