# vim: noet ts=4 sw=4 ft=yaml : [metadata] name: z80 bits: 8 endianness: little signedness: twos-complement cache: none pipeline: none [attributes] imm[8]: cycles +3 imm[16]: cycles +6 *: cycles +3 [registers] AF: 16; special A: 8; accumulator F: 8; flags, offset 8;; flag _C: 1 _N: 1; offset 1 _PV: 1; offset 2 _3: 1; offset 3, undocumented _H: 1; offset 4 _5: 1; offset 5, undocumented _Z: 1; offset 6 _S: 1; offset 7 BC: 16 B: 8 C: 8; offset=8 DE: 16 D: 8 E: 8; offset=8 HL: 16 H: 8 L: 8; offset=8 SP: 16; stack PC: 16; program # Index registers IX: 16 IXH: 8; undocumented IXL: 8; undocumented, offset 8 IY: bits=16 IYH: 8; undocumented IYL: 8; undocumented, offset 8 # Interrupt and memory refresh register I: 8; special, volatile R: 8; special, volatile # Shadow registers, can be swapped with the main set via ex/exx "AF'": 16; special "BC'": 16; special "DE'": 16; special "HL'": 16; special [macros] flags_zc: ;; imply[conditional] NZ: 00; imply[uses _Z] Z: 01; imply[uses _Z] NC: 10; imply[uses _C] C: 11; imply[uses _C] flags: ;; imply[conditional] NZ: 000; imply[uses _Z] Z: 001; imply[uses _Z] NC: 010; imply[uses _C] C: 011; imply[uses _C] PO: 100; imply[uses _PV] PE: 101; imply[uses _PV] P: 110; imply[uses _S] M: 111; imply[uses _S] reg_8: A: 111; imply[uses A] B: 000; imply[uses B] C: 001; imply[uses C] D: 010; imply[uses D] E: 011; imply[uses E] H: 100; imply[uses H] L: 101; imply[uses L] *HL: 110; imply[uses HL] reg_BCDE: BC: 0; imply[uses BC] DE: 1; imply[uses DE] reg_IR: I: 0; imply[uses I] R: 1; imply[uses R] reg_BCDEHLSP: BC: 00; imply[uses BC] DE: 01; imply[uses DE] HL: 10; imply[uses HL] SP: 11; imply[uses SP] reg_BCDEHLAF: BC: 00; imply[uses BC] DE: 01; imply[uses DE] HL: 10; imply[uses HL] AF: 11; imply[uses AF] reg_BCDEIXSP: BC: 00; imply[uses BC] DE: 01; imply[uses DE] IX: 10; imply[uses IX] SP: 11; imply[uses SP] reg_BCDEIYSP: BC: 00; imply[uses BC] DE: 01; imply[uses DE] IY: 10; imply[uses IY] SP: 11; imply[uses SP] reg_index: IX: 11011101; imply[uses IX, cycles +4] IY: 11111101; imply[uses IY, cycles +4] # on z80, you can offset indirect references to certain registers by an # immediate value reg_index_ind: *(reg_index @imm[8; signed, name offset]); imply[cycles +8] # on z80, you can access the low and high octets of index registers through # some undocumented instructions reg_ihl: ;; imply[undocumented] IXH: 100; define[ireg=11011101], imply[uses IXH] IXL: 101; define[ireg=11011101], imply[uses IXL] IYH: 100; define[ireg=11111101], imply[uses IYH] IYL: 101; define[ireg=11111101], imply[uses IYL] [instructions] .load: ld: ;; load[dest, source], cycles +4 @reg_8, @reg_8: 01 $1 $2 @reg_8, @imm[8]: 00 $1 110 $2 %A, *@reg_BCDE: 000 $2 1010 %A, *@imm[16]: 000 $2 1010 *@reg_BCDE, %A: 000 $1 0010 *@imm[16], %A: 00110010 $1 %A, @reg_IR: 11101101 0101 $2 111; cycles 9, flags[_S,_Z,_H:0,_N:0,_PV:?] @reg_IR, %A: 11101101 0100 $1 111; cycles 9 @reg_BCDEHLSP, @imm[16]: 00 $1 0001 $2 %HL, *@imm[16]: 00101010 $2; cycles 16 @reg_BCDEHLSP, *@imm[16]: 11101101 01 $1 1011 $2; cycles 20 *@imm[16], %HL: 00100010 $1; cycles 16 *@imm[16], @reg_BCDEHLSP: 11101101 01 $2 0011 $1; cycles 20 %SP, %HL: 1111001; cycles +2 .copy: ldd: 11101101 10101000; uses[HL, DE], \ affects[HL[--], DE[--], BC[--]], \ flags[_H:0,_N:0,_PV:[BC == 0]], cycles 16 lddr: 11101101 10111000; uses[HL, DE, BC], \ affects[HL[-BC], DE[-BC], BC[0]], \ flags[_H:0,_N:0,_PV:0], cycles[16 + BC * 5] ldi: 11101101 10100000; uses[HL, DE], \ affects[HL[++], DE[++], BC[--]], \ flags[_H:0,_N:0,_PV:[BC == 0]], cycles 16 ldir: 11101101 10110000; uses[HL, DE, BC], \ affects[HL[+BC], DE[+BC], BC[0]], \ flags[_H:0,_N:0,_PV:0], cycles[16 + BC * 5] .index: ld: ;; load[dest, source], cycles +4 @reg_index, @imm[16]: $1 00100001 $2 @reg_8, @reg_index_ind: $2 01 $1 110 $offset @reg_index_ind, @reg_8: $1 01110 $2 $offset @reg_index_ind, @imm[8]: $1 00110110 $offset $2 @reg_index, *@imm[16]: $1 00101010 $2; cycles 20 *@imm[16], @reg_index: $2 00100010 $1; cycles 20 %SP, @reg_index: $2 1111001; cycles +2, uses SP @reg_ihl, @reg_8: $ireg 01 $1 $2 @reg_ihl, @imm[8]: $ireg 00 $1 110 $2 .z80: ex: ;; reversible %DE, %HL: 11101011; cycles 4 %AF, %"AF'": 00001000; cycles 4 *%SP, %HL: 11100011; cycles 19 *%SP, @reg_index: $1 11100011; cycles 23 exx: 11011001; cycles 4