← back to zenas

Z80 instruction-set coverage

zenas covers three classes of instructions, verified by encoding a representative of every instruction family and comparing the bytes against established reference assemblers:

Class Forms Reference
Documented Z80 468 pasmo and sjasmplus
Undocumented IX/IY half registers (IXH/IXL/IYH/IYL) 48 pasmo and sjasmplus
Z80N (ZX Spectrum Next extensions) 29 sjasmplus
Total 545

The documented and half-register forms (516 together) assemble byte-for-byte identically to both pasmo and sjasmplus. The 29 Z80N instructions assemble identically to sjasmplus, the de facto ZX Spectrum Next assembler and the reference implementation of the Z80N encoding. Z80N is off by default and enabled with --next / --cpu=Z80N.

The checks are reproducible:

The instruction lists are generated by tools/gen_instr_coverage.py (tools/instr_coverage_list.txt) and held in tools/z80n_coverage.txt.

Covered families

Family Examples Status
8-bit load, register/immediate/(HL) LD A,B, LD A,5, LD A,(HL), LD (HL),A, LD (HL),5 complete
8-bit load, extended addressing LD A,(BC), LD A,(DE), LD A,(nn), LD (nn),A complete
16-bit load LD BC,nn, LD HL,(nn), LD (nn),HL, LD SP,HL complete
Stack PUSH/POP BC/DE/HL/AF complete
ALU register/immediate/(HL) ADD A,r, ADC A,n, SUB (HL), AND r, XOR r, OR r, CP (HL) complete
INC/DEC 8-bit and 16-bit INC r, DEC (HL), INC BC, DEC SP complete
16-bit arithmetic ADD HL,rr, ADC HL,rr, SBC HL,rr complete
Rotates / shifts RLC/RRC/RL/RR/SLA/SRA/SRL r/(HL), RLCA/RRCA/RLA/RRA, RLD/RRD complete
Accumulator/flags DAA, CPL, NEG, CCF, SCF complete
Bit ops BIT/RES/SET b,r, BIT/RES/SET b,(HL) complete
Jumps / calls / returns JP nn, JP cc,nn, JP (HL)/(IX)/(IY), JR e, JR cc,e, DJNZ e, CALL nn, CALL cc,nn, RET, RET cc, RETI, RETN complete
Restart / interrupt mode RST n, IM 0/1/2 complete
Exchange EX DE,HL, EX AF,AF', EXX, EX (SP),HL complete
Block transfer / search LDI/LDD/LDIR/LDDR, CPI/CPD/CPIR/CPDR complete
Block I/O INI/IND/INIR/INDR, OUTI/OUTD/OTIR/OTDR complete
Port I/O IN A,(n), OUT (n),A, IN r,(C), OUT (C),r complete
Interrupt/refresh registers LD A,I, LD A,R, LD I,A, LD R,A complete
IX/IY 16-bit LD IX,nn, ADD IX,rr, INC/DEC IX, PUSH/POP IX, LD SP,IX, JP (IX) complete
IX/IY indexed LD r,(IX+d), LD (IX+d),r, LD (IX+d),n, ADD A,(IX+d), INC/DEC (IX+d), CP (IX+d) complete
IX/IY half registers (undocumented) LD IXH,A, LD A,IYH, LD IXH,5, INC IXL, ADD A,IYL, LD IXH,IXL complete
Z80N extensions (--next) SWAPNIB, MIRROR, TEST n, BSLA/BSRA/BSRL/BSRF/BRLC DE,B, MUL, ADD rr,A, ADD rr,nn, PUSH nn, OUTINB, NEXTREG, PIXELDN/PIXELAD/SETAE, JP (C), LDIX/LDWS/LDDX/LDIRX/LDPIRX/LDDRX complete (opt-in)

Index displacements accept a constant expression, including symbols ((IX+OFFSET)), evaluated at assembly time and range-checked to a signed byte.

Not implemented

The undocumented CB-prefixed indexed bit/shift forms with a register copy (e.g. RLC (IX+d),B) and the duplicate SLL/SL1 shift are not encoded; no target depends on them. Everything in the documented set is covered.

Undocumented IX/IY half registers

IXH/IXL/IYH/IYL are the high and low bytes of the index registers, accessed via the DD/FD prefix that reinterprets H/L in the following instruction. Because the single prefix governs the whole instruction, two combinations are illegal and are rejected (matching a conforming assembler):

All legal forms - 8-bit load (register/immediate/half-to-half within one index), INC/DEC, and the ALU group - are encoded with the correct DD/FD prefix.