|
| ||||
|
|
|
|
|
|
This is the R.O.M.E.68000 Manual version 0.51.
This is an experimental version.
Copyright © 1997 by G. Mezzetti; last update: January 1, 1999.
In the descriptions of the instructions given in the previous sections, one piece of information was labelled Instruction Key: this is the key that identifies an instruction at the machine code level.
We spoke of instruction keys in Section 7 of Chapter I, and if you recall the description given there, you will see that 7 bits are set aside in the opcode to hold such keys;
but if you look at the keys given in the description of the instructions of this chapter, you will note that they run from $02 (MOVE) to $FE (CMPRBW), so they seem to be--and in fact they are!--8-bits-wide numbers.
We want now to explain this apparent inconsistency.
All numbers given as instruction keys in the previous descriptions are even, so they are bytes whose less significant bit is always 0. Strictly speaking, this 0 bit to the right does not belong to the instruction key, but is added to it in the descriptions to simplify the task of coding 68000 programs by hand. In other words, it is used to left-justify the actual, 7-bits-wide instruction key into the most significant byte of the opcode (which is also the most significant byte of the whole instruction word).
We want to avoid any ambiguity about this point, so we shall now repeat, with more precision, what we have just said. Recall fig. 3, which illustrates the general format of instructions, and compare it with fig. 26 below:
Like fig. 3, the upper part of fig. 26 shows the general format of an instruction word; in the middle the 16-bits-wide opcode field is enlarged; below this, you can see a byte whose less significant bit is zero: this represent an 8-bits-wide instruction key, such as those given in the descriptions of the instructions. Fig. 26 indicates without ambiguity how these 8-bits-wide instruction keys should be interpreted: you should ignore the less significant bit (i.e., bit number 0, the one which is always zero) and put bits 7-1 in bits 64-57 of the instruction word.
You will be asking why on earth we adopt this whimsical scheme instead of simply writing 7-bits-wide instruction keys also in the description of instructions! As already mentioned, we want to simplify in this way the task of coding 68000 programs by hand; indeed, the whole structure of the instruction word was designed keeping this concept in mind. We believe that the instructione keys are more easily recognizable if they are already given as they appear when they are left-justified in the most significant byte of the opcode. Let us explain this with great care.
Comparing fig. 3 and fig. 26, you will note that the less significant bit of the 8-bits-wide instruction key corresponds to the bit that codifies the addressing mode for the register page in the instruction word; now, ``fixed register'' mode is used much more frequently than ``movable registers mode'', so the corresponding bit will be also cleared to zero in most instructions (recall that instructions which do not use registers have this bit cleared to zero too); in this case, the byte written in the description of the instruction as the instruction key will coincide with the most significant byte of the opcode. Let us see an example: suppose you want to code the following instruction
MOVE #0,R4;16
where, as you can see, the register page lies 16 locations beyond the one containing the instruction (toward higher addresses) and is addressed using ``fixed registers mode''.
If we look at the (8-bits-wide) instruction key given in the description of the MOVE instruction, we find the hexadecimal number 02;
following the process outlined in fig. 26, we should divide this number by 2 and place the (7-bits-wide) result into bits 64-57 of the instruction word;
but then we should clear to zero bit 56 to signal ``fixed registers mode'', so it is much more straightforward to copy the 8-bits-wide instruction key, as it is given in the description of the instruction, into the most significant byte of the object code.
Next, we have to write the keys for the addressing modes: this is easy, because each key, which is 4 bits wide, corresponds exactly to one hexadecimal digit;
indeed, in Chapter II a key for a 4-bits mode was precisely an hexadecimal digit, and if we look there we find the keys we need: 1 for ``direct to register mode'' and C for ``immediate'' mode.
We have to write the mode for operand B in bits 55-52, and that for operand A in bits 51-48 (remember: in the object code, operand B is to the left and operand A is to the right, the opposite of the order in which you find them in the source code), so we get the opcode 021C.
Then the base of the register page comes, as a relative displacement from the location containing the instruction: this displacement is 16, or, in 16-bits hexadecimal form, 0010.
We now have to assemble the address field of operand B; to do this, we return to Chapter II and have a look at Section 5 and fig. 17, as well as at the description of ``direct to register'' mode.
We must place in the 16-bits-wide address field some ``tiles'' which represent elementary components;
only one elementary component is needed for this mode, and it is the displacement of the register from the base of the register page--in other words, the number of the register, which in this case is 4;
bits in the address field that are not used to hold elementary components must be cleared to zero, so the field is assembled as 4000.
Finally, we do the same thing for operand A: ``immediate'' mode, again, has only one elementary component, which occupies all 16 bits of the address field and contains the immediate value of the operand; we write hence 0000.
Putting it all together, our instruction is assembled as follows (source code to the left, object code to the right):
MOVE #0,R4;16 021C001040000000
If ``movable registers mode'' is required, you simply add 1 to the 8-bits-wide instruction key given in the description of the instruction itself. For instance, a very complex program, performing complicated operations which involve cross controls among co-operating units, could contain an instruction like this:
JMNZ [3[R2]],[[R6][RB]]12
Here we suppose that the base of the register page is specified using USEREGS, and that ``movable registers mode'' has been prescribed.
The effect of this instruction is to jump to an address chosen using R2 as an index in a table which starts 3 locations beyond the one containing the instruction itself, if a certain variable addressed in a complex mode is not zero.
Since ``movable registers mode'' is required, we add 1 to the key of the JMNZ instruction, which is 64, so we obtain 65;
adding (in the correct order!) the keys of the addressing modes, we have the opcode 657B.
Suppose that the pointer to the base of the register page lies, say, 37 locations beyond the current one; in hexadecimal digits, 37 reads 0025, and this is the value to place in bits 47-32 of the instruction word.
We now carefully assemble the address field of operand B; we have three elementary components: the number of the base register (6), the number of the index register (B) and the outer displacement (0C);
we learn how to place them in the address field from the description of ``double indirect to register with inner index and outer displacement'' mode, and we get 6B0C.
For operand A the mode is ``indirect to memory (short) with inner index'',
the elementary components are the base address, relative to current location (03),
and the number of the index register (2),
so finally the assembled address field is 0320
(remember that the last 4 bits of the address field, which are not used to hold any elementary component, must be cleared to zero).
Collecting these pieces, we obtain the object code of the whole instruction:
JMNZ [3[R2]],[[R6][RB]]12 657B00256B0C0320
Isn't it nice?
|
|
|
|
|
|