Appendix B
Instruction summary
This appendix lists every instruction form that TATARA accepts, grouped by class as in Zilog’s manual, with the bytes TATARA assembles for it and a few words on what it does. Chapter 9 describes how operands are written. What each instruction does in detail, which flags it changes and how long it takes are in the book or course you learn Z80 programming from.
TATARA accepts the documented Z80 instructions, the undocumented ones of section 9.5, and the two multiplications of the R800.
B.1 How to read the tables
Each table has three columns: the form of the instruction, as you write it; the bytes TATARA writes for it, in hexadecimal; and what the instruction does. In the first two columns, a word in italics stands for something that changes from one use to the next:
| Word | What it stands for |
| r, r’ | one of the registers B, C, D, E, H, L and A |
| n | a byte: any expression, of which the low byte is used |
| nn | a word: an address or a 16-bit value |
| lo hi | the two bytes of nn, the low byte first |
| d | the displacement of an indexed operand, from −128 to 127 |
| e | the target of a relative jump; the byte TATARA writes is the distance from the end of the instruction to the target, from −128 to 127 |
| b | a bit number, from 0 to 7 |
| x, x’ | an index half (section B.13) |
Some instructions have a different byte for each register they use. ld r,r’, which copies one register into another, comes in 49 versions, from ld b,b to ld a,a. Instead of a row for each, the table gives a rule for working the byte out. Each register has a number, its register code:
| B | C | D | E | H | L | (HL) | A |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
In the bytes column, 8r means 8 times the code of r, and the numbers are added in hexadecimal. The row for ld r,r’ says 40+8r+r’. For ld d,b, the code of D is 2 and the code of B is 0, so the byte is 40h + 8×2 + 0 = 40h + 10h = 50h. In the same way, add a,r is 80+r, so add a,e is 80h + 3 = 83h, and bit b,r is CB 40+8b+r, so bit 7,a is CB, then 40h + 8×7 + 7 = 40h + 38h + 7 = 7Fh.
Where an instruction has only a few versions, such as the register pairs of push or the conditions of jp, each one has a row of its own, with its bytes written out.
The instructions that use IX or IY are the ones that use HL, with a prefix byte in front: DD for IX and FD for IY. In the forms with d, the displacement byte follows the opcode; in those that start DD CB or FD CB, it comes before the last byte.
B.2 8-bit loads
| Form | Bytes |
What it does |
| ld r,r’ | 40+8r+r’ |
copies r’ into r |
| ld r,n | 06+8r n |
loads n into r |
| ld r,(hl) | 46+8r |
loads the byte at the address in HL |
| ld r,(ix+d) | DD 46+8r d |
loads the byte at IX+d |
| ld r,(iy+d) | FD 46+8r d |
loads the byte at IY+d |
| ld (hl),r | 70+r |
stores r at the address in HL |
| ld (ix+d),r | DD 70+r d |
stores r at IX+d |
| ld (iy+d),r | FD 70+r d |
stores r at IY+d |
| ld (hl),n | 36 n |
stores n at the address in HL |
| ld (ix+d),n | DD 36 d n |
stores n at IX+d |
| ld (iy+d),n | FD 36 d n |
stores n at IY+d |
| ld a,(bc) | 0A |
loads A from the address in BC |
| ld a,(de) | 1A |
loads A from the address in DE |
| ld a,(nn) | 3A lo hi |
loads A from address nn |
| ld (bc),a | 02 |
stores A at the address in BC |
| ld (de),a | 12 |
stores A at the address in DE |
| ld (nn),a | 32 lo hi |
stores A at address nn |
| ld a,i | ED 57 |
copies the interrupt vector register into A |
| ld a,r | ED 5F |
copies the refresh register into A |
| ld i,a | ED 47 |
copies A into the interrupt vector register |
| ld r,a | ED 4F |
copies A into the refresh register |
B.3 16-bit loads, PUSH and POP
| Form | Bytes |
What it does |
| ld bc,nn | 01 lo hi |
loads nn into BC |
| ld de,nn | 11 lo hi |
loads nn into DE |
| ld hl,nn | 21 lo hi |
loads nn into HL |
| ld sp,nn | 31 lo hi |
loads nn into SP |
| ld ix,nn | DD 21 lo hi |
loads nn into IX |
| ld iy,nn | FD 21 lo hi |
loads nn into IY |
| ld bc,(nn) | ED 4B lo hi |
loads BC from address nn |
| ld de,(nn) | ED 5B lo hi |
loads DE from address nn |
| ld hl,(nn) | 2A lo hi |
loads HL from address nn |
| ld sp,(nn) | ED 7B lo hi |
loads SP from address nn |
| ld ix,(nn) | DD 2A lo hi |
loads IX from address nn |
| ld iy,(nn) | FD 2A lo hi |
loads IY from address nn |
| ld (nn),bc | ED 43 lo hi |
stores BC at address nn |
| ld (nn),de | ED 53 lo hi |
stores DE at address nn |
| ld (nn),hl | 22 lo hi |
stores HL at address nn |
| ld (nn),sp | ED 73 lo hi |
stores SP at address nn |
| ld (nn),ix | DD 22 lo hi |
stores IX at address nn |
| ld (nn),iy | FD 22 lo hi |
stores IY at address nn |
| ld sp,hl | F9 |
copies HL into SP |
| ld sp,ix | DD F9 |
copies IX into SP |
| ld sp,iy | FD F9 |
copies IY into SP |
| push bc | C5 |
puts BC on the stack |
| push de | D5 |
puts DE on the stack |
| push hl | E5 |
puts HL on the stack |
| push af | F5 |
puts AF on the stack |
| push ix | DD E5 |
puts IX on the stack |
| push iy | FD E5 |
puts IY on the stack |
| pop bc | C1 |
takes BC from the stack |
| pop de | D1 |
takes DE from the stack |
| pop hl | E1 |
takes HL from the stack |
| pop af | F1 |
takes AF from the stack |
| pop ix | DD E1 |
takes IX from the stack |
| pop iy | FD E1 |
takes IY from the stack |
B.4 Exchange, block transfer and search
| Form | Bytes |
What it does |
| ex de,hl | EB |
exchanges DE and HL |
| ex af,af’ | 08 |
exchanges AF and the second AF |
| exx | D9 |
exchanges BC, DE and HL with the second set |
| ex (sp),hl | E3 |
exchanges HL and the word at the top of the stack |
| ex (sp),ix | DD E3 |
exchanges IX and the word at the top of the stack |
| ex (sp),iy | FD E3 |
exchanges IY and the word at the top of the stack |
| ldi | ED A0 |
copies a byte from (HL) to (DE), then moves on |
| ldir | ED B0 |
repeats LDI until BC is 0 |
| ldd | ED A8 |
copies a byte from (HL) to (DE), then moves back |
| lddr | ED B8 |
repeats LDD until BC is 0 |
| cpi | ED A1 |
compares A with (HL), then moves on |
| cpir | ED B1 |
repeats CPI until a match or BC is 0 |
| cpd | ED A9 |
compares A with (HL), then moves back |
| cpdr | ED B9 |
repeats CPD until a match or BC is 0 |
B.5 8-bit arithmetic and logic
| Form | Bytes |
What it does |
| add a,r | 80+r |
adds r to A |
| add a,n | C6 n |
adds n to A |
| add a,(hl) | 86 |
adds the byte at (HL) to A |
| add a,(ix+d) | DD 86 d |
adds the byte at IX+d to A |
| add a,(iy+d) | FD 86 d |
adds the byte at IY+d to A |
| adc a,r | 88+r |
adds r and the carry to A |
| adc a,n | CE n |
adds n and the carry to A |
| adc a,(hl) | 8E |
adds the byte at (HL) and the carry to A |
| adc a,(ix+d) | DD 8E d |
adds the byte at IX+d and the carry to A |
| adc a,(iy+d) | FD 8E d |
adds the byte at IY+d and the carry to A |
| sub r | 90+r |
subtracts r from A |
| sub n | D6 n |
subtracts n from A |
| sub (hl) | 96 |
subtracts the byte at (HL) from A |
| sub (ix+d) | DD 96 d |
subtracts the byte at IX+d from A |
| sub (iy+d) | FD 96 d |
subtracts the byte at IY+d from A |
| sbc a,r | 98+r |
subtracts r and the carry from A |
| sbc a,n | DE n |
subtracts n and the carry from A |
| sbc a,(hl) | 9E |
subtracts the byte at (HL) and the carry from A |
| sbc a,(ix+d) | DD 9E d |
subtracts the byte at IX+d and the carry from A |
| sbc a,(iy+d) | FD 9E d |
subtracts the byte at IY+d and the carry from A |
| and r | A0+r |
A AND r |
| and n | E6 n |
A AND n |
| and (hl) | A6 |
A AND the byte at (HL) |
| and (ix+d) | DD A6 d |
A AND the byte at IX+d |
| and (iy+d) | FD A6 d |
A AND the byte at IY+d |
| xor r | A8+r |
A XOR r |
| xor n | EE n |
A XOR n |
| xor (hl) | AE |
A XOR the byte at (HL) |
| xor (ix+d) | DD AE d |
A XOR the byte at IX+d |
| xor (iy+d) | FD AE d |
A XOR the byte at IY+d |
| or r | B0+r |
A OR r |
| or n | F6 n |
A OR n |
| or (hl) | B6 |
A OR the byte at (HL) |
| or (ix+d) | DD B6 d |
A OR the byte at IX+d |
| or (iy+d) | FD B6 d |
A OR the byte at IY+d |
| cp r | B8+r |
compares A with r |
| cp n | FE n |
compares A with n |
| cp (hl) | BE |
compares A with the byte at (HL) |
| cp (ix+d) | DD BE d |
compares A with the byte at IX+d |
| cp (iy+d) | FD BE d |
compares A with the byte at IY+d |
| inc r | 04+8r |
adds 1 to r |
| inc (hl) | 34 |
adds 1 to the byte at (HL) |
| inc (ix+d) | DD 34 d |
adds 1 to the byte at IX+d |
| inc (iy+d) | FD 34 d |
adds 1 to the byte at IY+d |
| dec r | 05+8r |
subtracts 1 from r |
| dec (hl) | 35 |
subtracts 1 from the byte at (HL) |
| dec (ix+d) | DD 35 d |
subtracts 1 from the byte at IX+d |
| dec (iy+d) | FD 35 d |
subtracts 1 from the byte at IY+d |
B.6 General purpose and CPU control
| Form | Bytes |
What it does |
| daa | 27 |
adjusts A after a BCD addition or subtraction |
| cpl | 2F |
inverts every bit of A |
| neg | ED 44 |
negates A |
| ccf | 3F |
inverts the carry flag |
| scf | 37 |
sets the carry flag |
| nop | 00 |
does nothing |
| halt | 76 |
waits for an interrupt |
| di | F3 |
disables interrupts |
| ei | FB |
enables interrupts |
| im 0 | ED 46 |
selects interrupt mode 0 |
| im 1 | ED 56 |
selects interrupt mode 1 |
| im 2 | ED 5E |
selects interrupt mode 2 |
B.7 16-bit arithmetic
| Form | Bytes |
What it does |
| add hl,bc | 09 |
adds BC to HL |
| add hl,de | 19 |
adds DE to HL |
| add hl,hl | 29 |
adds HL to HL |
| add hl,sp | 39 |
adds SP to HL |
| adc hl,bc | ED 4A |
adds BC and the carry to HL |
| adc hl,de | ED 5A |
adds DE and the carry to HL |
| adc hl,hl | ED 6A |
adds HL and the carry to HL |
| adc hl,sp | ED 7A |
adds SP and the carry to HL |
| sbc hl,bc | ED 42 |
subtracts BC and the carry from HL |
| sbc hl,de | ED 52 |
subtracts DE and the carry from HL |
| sbc hl,hl | ED 62 |
subtracts HL and the carry from HL |
| sbc hl,sp | ED 72 |
subtracts SP and the carry from HL |
| add ix,bc | DD 09 |
adds BC to IX |
| add ix,de | DD 19 |
adds DE to IX |
| add ix,ix | DD 29 |
adds IX to IX |
| add ix,sp | DD 39 |
adds SP to IX |
| add iy,bc | FD 09 |
adds BC to IY |
| add iy,de | FD 19 |
adds DE to IY |
| add iy,iy | FD 29 |
adds IY to IY |
| add iy,sp | FD 39 |
adds SP to IY |
| inc bc | 03 |
adds 1 to BC |
| inc de | 13 |
adds 1 to DE |
| inc hl | 23 |
adds 1 to HL |
| inc sp | 33 |
adds 1 to SP |
| inc ix | DD 23 |
adds 1 to IX |
| inc iy | FD 23 |
adds 1 to IY |
| dec bc | 0B |
subtracts 1 from BC |
| dec de | 1B |
subtracts 1 from DE |
| dec hl | 2B |
subtracts 1 from HL |
| dec sp | 3B |
subtracts 1 from SP |
| dec ix | DD 2B |
subtracts 1 from IX |
| dec iy | FD 2B |
subtracts 1 from IY |
B.8 Rotate and shift
| Form | Bytes |
What it does |
| rlca | 07 |
rotates A left |
| rla | 17 |
rotates A left through the carry |
| rrca | 0F |
rotates A right |
| rra | 1F |
rotates A right through the carry |
| rlc r | CB 00+r |
rotates r left |
| rlc (hl) | CB 06 |
rotates the byte at (HL) left |
| rlc (ix+d) | DD CB d 06 |
rotates the byte at IX+d left |
| rlc (iy+d) | FD CB d 06 |
rotates the byte at IY+d left |
| rl r | CB 10+r |
rotates r left through the carry |
| rl (hl) | CB 16 |
rotates the byte at (HL) left through the carry |
| rl (ix+d) | DD CB d 16 |
rotates the byte at IX+d left through the carry |
| rl (iy+d) | FD CB d 16 |
rotates the byte at IY+d left through the carry |
| rrc r | CB 08+r |
rotates r right |
| rrc (hl) | CB 0E |
rotates the byte at (HL) right |
| rrc (ix+d) | DD CB d 0E |
rotates the byte at IX+d right |
| rrc (iy+d) | FD CB d 0E |
rotates the byte at IY+d right |
| rr r | CB 18+r |
rotates r right through the carry |
| rr (hl) | CB 1E |
rotates the byte at (HL) right through the carry |
| rr (ix+d) | DD CB d 1E |
rotates the byte at IX+d right through the carry |
| rr (iy+d) | FD CB d 1E |
rotates the byte at IY+d right through the carry |
| sla r | CB 20+r |
shifts r left |
| sla (hl) | CB 26 |
shifts the byte at (HL) left |
| sla (ix+d) | DD CB d 26 |
shifts the byte at IX+d left |
| sla (iy+d) | FD CB d 26 |
shifts the byte at IY+d left |
| sra r | CB 28+r |
shifts r right, keeping bit 7 |
| sra (hl) | CB 2E |
shifts the byte at (HL) right, keeping bit 7 |
| sra (ix+d) | DD CB d 2E |
shifts the byte at IX+d right, keeping bit 7 |
| sra (iy+d) | FD CB d 2E |
shifts the byte at IY+d right, keeping bit 7 |
| srl r | CB 38+r |
shifts r right, with 0 into bit 7 |
| srl (hl) | CB 3E |
shifts the byte at (HL) right, with 0 into bit 7 |
| srl (ix+d) | DD CB d 3E |
shifts the byte at IX+d right, with 0 into bit 7 |
| srl (iy+d) | FD CB d 3E |
shifts the byte at IY+d right, with 0 into bit 7 |
| rld | ED 6F |
rotates a digit left between A and (HL) |
| rrd | ED 67 |
rotates a digit right between A and (HL) |
B.9 Bit set, reset and test
| Form | Bytes |
What it does |
| bit b,r | CB 40+8b+r |
tests bit b of r |
| bit b,(hl) | CB 46+8b |
tests bit b of the byte at (HL) |
| bit b,(ix+d) | DD CB d 46+8b |
tests bit b of the byte at IX+d |
| bit b,(iy+d) | FD CB d 46+8b |
tests bit b of the byte at IY+d |
| set b,r | CB C0+8b+r |
sets bit b of r |
| set b,(hl) | CB C6+8b |
sets bit b of the byte at (HL) |
| set b,(ix+d) | DD CB d C6+8b |
sets bit b of the byte at IX+d |
| set b,(iy+d) | FD CB d C6+8b |
sets bit b of the byte at IY+d |
| res b,r | CB 80+8b+r |
clears bit b of r |
| res b,(hl) | CB 86+8b |
clears bit b of the byte at (HL) |
| res b,(ix+d) | DD CB d 86+8b |
clears bit b of the byte at IX+d |
| res b,(iy+d) | FD CB d 86+8b |
clears bit b of the byte at IY+d |
B.10 Jumps
| Form | Bytes |
What it does |
| jp nn | C3 lo hi |
jumps to nn |
| jp nz,nn | C2 lo hi |
jumps to nn if not zero |
| jp z,nn | CA lo hi |
jumps to nn if zero |
| jp nc,nn | D2 lo hi |
jumps to nn if no carry |
| jp c,nn | DA lo hi |
jumps to nn if carry |
| jp po,nn | E2 lo hi |
jumps to nn if parity odd |
| jp pe,nn | EA lo hi |
jumps to nn if parity even |
| jp p,nn | F2 lo hi |
jumps to nn if positive |
| jp m,nn | FA lo hi |
jumps to nn if negative |
| jr e | 18 e |
jumps to e |
| jr nz,e | 20 e |
jumps to e if not zero |
| jr z,e | 28 e |
jumps to e if zero |
| jr nc,e | 30 e |
jumps to e if no carry |
| jr c,e | 38 e |
jumps to e if carry |
| jp (hl) | E9 |
jumps to the address in HL |
| jp (ix) | DD E9 |
jumps to the address in IX |
| jp (iy) | FD E9 |
jumps to the address in IY |
| djnz e | 10 e |
subtracts 1 from B and jumps to e if B is not 0 |
B.11 Calls, returns and restarts
| Form | Bytes |
What it does |
| call nn | CD lo hi |
calls the routine at nn |
| call nz,nn | C4 lo hi |
calls the routine at nn if not zero |
| call z,nn | CC lo hi |
calls the routine at nn if zero |
| call nc,nn | D4 lo hi |
calls the routine at nn if no carry |
| call c,nn | DC lo hi |
calls the routine at nn if carry |
| call po,nn | E4 lo hi |
calls the routine at nn if parity odd |
| call pe,nn | EC lo hi |
calls the routine at nn if parity even |
| call p,nn | F4 lo hi |
calls the routine at nn if positive |
| call m,nn | FC lo hi |
calls the routine at nn if negative |
| ret | C9 |
returns from a routine |
| ret nz | C0 |
returns if not zero |
| ret z | C8 |
returns if zero |
| ret nc | D0 |
returns if no carry |
| ret c | D8 |
returns if carry |
| ret po | E0 |
returns if parity odd |
| ret pe | E8 |
returns if parity even |
| ret p | F0 |
returns if positive |
| ret m | F8 |
returns if negative |
| reti | ED 4D |
returns from an interrupt routine |
| retn | ED 45 |
returns from a non-maskable interrupt routine |
| rst 00h | C7 |
calls the routine at 00h |
| rst 08h | CF |
calls the routine at 08h |
| rst 10h | D7 |
calls the routine at 10h |
| rst 18h | DF |
calls the routine at 18h |
| rst 20h | E7 |
calls the routine at 20h |
| rst 28h | EF |
calls the routine at 28h |
| rst 30h | F7 |
calls the routine at 30h |
| rst 38h | FF |
calls the routine at 38h |
B.12 Input and output
| Form | Bytes |
What it does |
| in a,(n) | DB n |
reads port n into A |
| in r,(c) | ED 40+8r |
reads the port in C into r |
| ini | ED A2 |
reads the port in C into (HL), then moves on |
| inir | ED B2 |
repeats INI until B is 0 |
| ind | ED AA |
reads the port in C into (HL), then moves back |
| indr | ED BA |
repeats IND until B is 0 |
| out (n),a | D3 n |
writes A to port n |
| out (c),r | ED 41+8r |
writes r to the port in C |
| outi | ED A3 |
writes (HL) to the port in C, then moves on |
| otir | ED B3 |
repeats OUTI until B is 0 |
| outd | ED AB |
writes (HL) to the port in C, then moves back |
| otdr | ED BB |
repeats OUTD until B is 0 |
B.13 The undocumented instructions
These are the undocumented instructions of section 9.5. In the SLL rows, r is any of the seven registers. In the other rows, x and x’ are IXH or IXL, whose codes are 4 and 5, the codes of H and L; r is B, C, D, E or A; and x’ is a half of the same register as x. The rows give the bytes for IX. For IYH and IYL, FD takes the place of DD: ld iyl,a is FD 6F.
| Form | Bytes |
What it does |
| sll r | CB 30+r |
shifts r left; bit 0 becomes 1 |
| sll (hl) | CB 36 |
the same with the byte at the address in HL |
| sll (ix+d) | DD CB d 36 |
the same with the byte at IX+d |
| sll (iy+d) | FD CB d 36 |
the same with the byte at IY+d |
| ld x,r | DD 40+8x+r |
copies r into x |
| ld r,x | DD 40+8r+x |
copies x into r |
| ld x,x’ | DD 40+8x+x’ |
copies one half of IX into the other, or into itself |
| ld x,n | DD 06+8x n |
loads n into x |
| inc x | DD 04+8x |
adds 1 to x |
| dec x | DD 05+8x |
subtracts 1 from x |
| add a,x | DD 80+x |
adds x to A |
| adc a,x | DD 88+x |
adds x and the carry to A |
| sub x | DD 90+x |
subtracts x from A |
| sbc a,x | DD 98+x |
subtracts x and the carry from A |
| and x | DD A0+x |
A AND x |
| xor x | DD A8+x |
A XOR x |
| or x | DD B0+x |
A OR x |
| cp x | DD B8+x |
compares A with x |
| in f,(c) | ED 70 |
reads the port in C and sets the flags; A is unchanged |
| out (c),0 | ED 71 |
writes 0 or 0FFh to the port in C (section 9.5) |
B.14 The R800 multiplications
| Form | Bytes |
What it does |
| mulub a,r | ED C1+8r |
A times r, the result in HL |
| muluw hl,bc | ED C3 |
HL times BC, the result in DE:HL |
| muluw hl,sp | ED F3 |
HL times SP, the result in DE:HL |
B.15 Forms that are not accepted
Some forms are accepted by other assemblers, or look as if they should work, but are not in Zilog’s list or among the undocumented instructions TATARA accepts. TATARA refuses them (table B.14):
| Written | Message |
Write instead |
| sub a,b | not a form this instruction has. |
sub b |
| and a,b | not a form this instruction has. |
and b |
| cp a,b | not a form this instruction has. |
cp b |
| add b | not a form this instruction has. |
add a,b |
| ex af,af | not a form this instruction has. |
ex af,af’ |
| jp hl | undefined symbol in an expression. |
jp (hl) |
| ld h,ixl | not a form this instruction has. |
none |
| ld ixh,iyl | not a form this instruction has. | none |
| ld ixh,(hl) | not a form this instruction has. |
none |
| rlc ixh | not a form this instruction has. |
none |
| rlc (ix+2),b | not a form this instruction has. |
rlc
(ix+2)
and |
| in (c) | not a form this instruction has. |
in f,(c) |
| sl1 b | not a directive, a macro or an instruction. |
sll b |
| ld a,hx | undefined symbol in an expression. |
ld a,ixh |
SUB, AND, OR, XOR and CP always work on A, so Zilog writes them without it; ADD, ADC and SBC have 16-bit forms too, so their 8-bit forms name A. Without brackets, jp hl is read as jp nn, with hl as the name of an address, which is not defined.
The forms with an index half cannot be written because one prefix governs the whole instruction (section 9.5). rlc (ix+2),b is one of the undocumented forms that store the result in a register as well as in memory, which TATARA does not accept. in (c), sl1 and hx are other assemblers’ spellings of instructions that TATARA writes in one way only.
(IX) and (IY) without a displacement are accepted, and mean (IX+0) and (IY+0): ld a,(ix) is DD 7E 00.