Tatara

Chapter 9
Instructions

This chapter describes how the Z80’s instructions, and the two the R800 adds, are written for TATARA: the forms their operands can take, index registers and displacements, relative jumps, and the messages TATARA gives when an operand is wrong. It does not explain what each instruction does. That is the job of the book or course you learn Z80 programming from; appendix B lists the instructions by class, for reference.

9.1 The instruction set

TATARA accepts the Z80 instructions, written the way Zilog writes them, the undocumented instructions that Zilog never published but that every Z80 runs (section 9.5), and the R800’s MULUB and MULUW (section 9.4): 70 mnemonics in all. The source that chapter 6 described puts the mnemonic in the operation field and its operands, separated by commas, in the operand field.

9.2 Operands

An operand is one of the forms in table 9.1. Which forms an instruction takes is set by the Z80, and your Z80 book lists them. The bytes in the table are the ones TATARA writes for each example.

Form Example Bytes
register ld a,b 78
immediate value ld a,5 3E 05
ld hl,1234h 21 34 12
register indirect ld a,(hl) 7E
ex (sp),hl E3
jp (hl) E9
indexed ld a,(ix+5) DD 7E 05
ld a,(ix-1) DD 7E FF
ld a,(iy) FD 7E 00
memory address ld a,(1234h) 3A 34 12
ld hl,(1234h) 2A 34 12
port in a,(98h) DB 98
out (c),a ED 79
condition jr nz,$ 20 FE
bit number set 0,(ix+3) DD CB 03 C6
fixed value rst 38h FF
im 1 ED 56
Table 9.1: Operand forms.

9.2.1 Values and brackets

Wherever an instruction takes a number, an address or a port, the operand can be any expression (chapter 8). An operand without brackets is an immediate value: the number itself goes into the instruction. An operand in brackets is a memory address, or a port for IN and OUT. ld a,5 loads the number 5 into A; ld a,(5) loads the byte stored at address 5.

An immediate value that occupies one byte, as in ld a,5, is the low byte of the expression. TATARA does not check that the value fits: ld a,-1 writes 0FFh, which is what is meant, but ld a,300 writes 2Ch, the low byte of 300, without a message. One byte also cannot hold an address that TANREN still has to finish, so a one-byte value must be absolute (section 8.6). A two-byte value, as in ld hl,msg, can be relocatable or external.

9.2.2 Index registers

An indexed operand is (IX+d) or (IY+d), where d, the displacement, is a signed number from −128 to 127 that is added to the index register. It can be written with + or -, and it can be any absolute expression: (ix-1), (ix+count*2). (IX) alone means (IX+0). A displacement out of range stops TATARA:

DISP.AS(2): ERROR: an index displacement must be -128 to 127.
                                                                    

                                                                    
 

9.3 Relative jumps

JR and DJNZ are relative jumps: the instruction holds the distance to the target, one signed byte, rather than its address. In the source you still write the target, as with JP, and TATARA works out the distance: jr nz,loop, djnz loop.

The distance is measured from the instruction that follows, and must be from −128 to 127 bytes. jr $, which jumps to itself, is a distance of −2 and assembles to 18 FE. A target further away stops TATARA:

JR.AS(2): ERROR: a JR or DJNZ can only reach -128 to 127.
 

The target must be in the same segment as the jump, or be an absolute address, because a distance to code that TANREN places elsewhere is not known until the program is linked. Use JP for a target that is too far away or in another module.

9.4 The R800 instructions

The R800, the processor of the MSX turbo R, adds two multiplication instructions to the Z80’s set. Table 9.2 shows the three forms TATARA accepts.

Instruction Bytes What it does
mulub a,r ED C1+8r A ×r, the result in HL
muluw hl,bc ED C3 HL × BC, the result in DE:HL
muluw hl,sp ED F3 HL × SP, the result in DE:HL
Table 9.2: The R800 instructions.

r is an 8-bit register: mulub a,b is ED C1. TATARA accepts any of them, but the R800’s documentation guarantees the result only for B, C, D and E. The first operand must be A for MULUB and HL for MULUW.

Warning.  TATARA assembles these instructions on any MSX, but a program that uses them runs correctly only on a turbo R. On a Z80 they do not multiply.

9.4.1 R800 mnemonics

Every instruction is stored as a few bytes. The first byte, or the first two when the instruction has a prefix such as DD or ED, says which instruction it is; this part is the opcode. The rest, if there is any, holds the operand: a number, an address or a displacement. The processor reads only the bytes. A mnemonic, such as LD or DJNZ, is a name that people give to an opcode so that they can write programs without learning the numbers.

Because a mnemonic is only a name, the same opcodes can be given more than one set of names. The R800’s documentation from ASCII, reprinted in the MSX-Datapack, gives the whole instruction set new mnemonics: JP is br (branch), DJNZ is dbnz, EX is xch, RES is clr, LDIR is movem. Register names start with a dot, square brackets stand for memory, and the accumulator is always written out: Zilog’s SUB B is sub .a,.b. Apart from the two multiplications, every R800 instruction has the same opcode as the Z80 instruction it renames, and does the same thing.

Table 9.3 shows a short routine, which clears 256 bytes of memory, written both ways. The bytes are the same.

Z80 R800 Bytes
clear: ld hl,buffer ld .hl,buffer 21 nn nn
ld b,0 ld .b,0 06 00
xor a xor .a,.a AF
loop: ld (hl),a ld [.hl],.a 77
inc hl inc .hl 23
djnz loop dbnz loop 10 FC
ret ret C9
Table 9.3: The same routine in Z80 and R800 mnemonics.

ld b,0 makes DJNZ go round 256 times, because B reaches zero only after the 256th decrement.

At the time of writing, TATARA accepts only the Z80 mnemonics. A program written in R800 mnemonics has to be translated to Z80 mnemonics before TATARA can assemble it; the program that results is the same.

9.5 The undocumented instructions

Zilog published the Z80’s instructions, but not all of the opcodes the processor runs. Some of the others do useful things, are the same on every Z80, and have been used in MSX programs for decades. TATARA accepts four groups of them:

Like the R800’s instructions, they are assembled on any MSX, with no option to turn them on. M80 has none of them (appendix J). Table 9.4 shows their forms; appendix B lists all 104 with their bytes.

Form

Bytes

sll r, for B, C, D, E, H, L and A

CB 30+r

sll (hl)

CB 36

sll (ix+d), sll (iy+d)

DD CB d 36, FD CB d 36

ld x,r and ld r,x, for B, C, D, E and A

DD for IX, FD for IY, then the byte of the same instruction with H for a high half and L for a low one: ld ixh,b is DD and the 60 of ld h,b

ld x,y, both halves of the same register

the same: ld ixh,ixl is DD 65

ld x,n

the same: ld ixl,5 is DD 2E 05

inc x, dec x

the same: inc iyh is FD 24

add a,x, adc a,x, sub x, sbc a,x, and x, xor x, or x, cp x

the same: cp ixl is DD BD

in f,(c)

ED 70

out (c),0

ED 71

Table 9.4: The undocumented instructions. r is an 8-bit register, with the codes of appendix B; x and y are index halves.

9.5.1 How the index halves work

There is no opcode for IXH. A DD in front of an instruction makes it use IX where it would use HL, and that applies to the halves too: H becomes IXH and L becomes IXL. ld a,h is 7C, so ld a,ixh is DD 7C. With FD, the same instructions use IY.

The prefix belongs to the whole instruction, not to one operand, and that decides which forms exist (figure 9.1):

PIC

Figure 9.1: One prefix for the whole instruction: what DD does to two instructions.

The halves are also refused wherever the Z80 has no form for them: in the rotations and shifts, in BIT, SET and RES, in IN and OUT, and next to an indexed address, as in ld (ix+5),ixh. In each case TATARA stops with not a form this instruction has.

9.5.2 What a program may not rely on

Warning.  SLL on the MSX turbo R. The R800 runs CB 30 to CB 37, but as SLA: bit 0 is left clear. With B = 81h, sll b leaves 03h on a Z80 and 02h on an R800. The carry is the same on both, so only bit 0 shows the difference. A program that uses SLL does not run the same on a turbo R. The index halves, IN F,(C) and OUT (C),0 work on the R800 as they do on the Z80.

Warning.  OUT (C),0 does not always write 0. The NMOS Z80 writes 0; the CMOS Z80 writes 0FFh, and so do both processors in openMSX. A program cannot rely on the value it writes.

IN F,(C) leaves A alone and sets the flags as IN A,(C) would. Its only use is to test a port’s bits with the flags.

9.5.3 Spellings and names

Each of these instructions has one spelling: SLL, not SL1 or SLIA; IXH and the others, not HX, LX, HY or LY; IN F,(C), not IN (C); and OUT (C),0 with the digit 0 itself, not 00h or an expression. The other spellings give the usual messages for a word TATARA does not know.

IXH, IXL, IYH and IYL are registers, so they can no longer be names. M80 allows them as labels, and in TATARA such a label would silently change what ld a,ixh means, so TATARA refuses it, and refuses them in PUBLIC and EXTRN too:

IXHNAM.AS(2): ERROR: IXH, IXL, IYH and IYL are registers, not names.
 

HX, LX, HY and LY stay ordinary names, so a program that uses them for coordinates assembles as before.

Two other groups of undocumented opcodes are not accepted: the forms such as rlc (ix+2),b, which store the result in a register as well as in memory, and the extra opcodes in the ED group that repeat NEG, RETN and NOP.

9.6 When an operand is wrong

Table 9.5 lists the messages TATARA gives for an operand it cannot use, each with a line that causes it.

Line

Message

ld hl,a

not a form this instruction has.

mulub b,c

not a form this instruction has.

ld a,(ix+200)

an index displacement must be -128 to 127.

jr far

a JR or DJNZ can only reach -128 to 127.

rst 5

RST takes 0, 8, 10h and so on to 38h.

im 3

IM takes 0, 1 or 2.

bit 8,a

a bit number must be 0 to 7.

Table 9.5: Messages about operands.

not a form this instruction has. is the general one: the instruction exists, but not with these operands. ld hl,a is an example, because the Z80 cannot copy an 8-bit register into a 16-bit one. Check the forms the instruction has in your Z80 book, or in appendix B.