Take for example the instruction 'Load accumulator A with the contents of memory location $2A01'. The instruction code has to contain information about the type of instruction 'Load accumulator', which register is involved 'Accumulator A' and the address from which data is to be fetched 'Memory location 2A01'.
There is no way that all this can be coded in 8 bits, although there are some tricks as we shall see for condensing the length of instructions. The only solution is to make the instruction longer so that we have an 8 bit code meaning 'Load accumulator A with the contents of memory register' (B6 for the 6809 - I shall use hex notation but remember it is only a short-hand for a binary code) and then specify which memory register by including the address in full in two further instruction words. Thus we have a three byte instruction in three consecutive memory locations.
memory location n - B6 n+1 - 2A n+2 - 01On the other hand some instructions can be fitted into a single byte; usually where no reference to a memory address is required. For example 'Decrement Acc A'. This has the single byte instruction code 4A.
Instructions, therefore, are variable in length and included in the first byte must be information about how many bytes are in the instruction. In other words 4A is always a single byte instruction and B6 is always a 3 byte instruction. In the 6809 instructions can be 1,2,3 or 4 bytes in length. We have seen how 1 and 3 byte ones come about. Two byte instructions result from using a shortened version of the address or include 8 bit data in the instruction e.g. 'Load Acc A with the number FF'
memory location n - 86 n+1 - FFFour byte instructions are really illogical and result largely from the fact that when Motorola designed the 6809 they wanted it to be compatible with previous processors the 6800 and 6802. These had fewer instructions (no general transfer instruction and fewer indexing modes for example) and fewer registers (no Index register Y and no Stack pointer U and no D register). Nevertheless the vast majority of the 256 different instruction codes had already been used. To allow the extra instructions and in particular those to handle the extra registers they used the few unused codes to access an extended set of instructions (e.g. 1E, 10 & 11). Thus the instruction 'Load Index register Y with the number $FE00' is -
memory location n - 10 n+1 - 8E n+2 - FE n+3 - 00This problem of maintaining compatibility with ealier processors is a very serious one. As a microprocessor manufacturer you cannot expect your users to rewrite all their software when you bring out a new processor. There are two alternative approaches.
Load H with 2A Load L with 01 Load Acc from memoryEven processors such as the 80486 retain H and L registers and the instructions for using them in this way!
Motorola retained compatibility in its range of 8 bit processors but when it brought out the 16 bit processor, 68000 some years ago it dropped all attempt at compatibility and tried to design a logical processor and instruction format.
Many of the instructions in most processors can be used with a variety of addressing modes. Generally the more sophisticated the processor the greater the number of these modes. There are six main addressing modes in the 6809:-
Immediate Direct Extended Indexed Indirect RelativeMany of the data movement instructions can use all of these modes whilst others such as branch instructions can only use a few.
Load Acc A with FF LDA #$FF 86 FFSometimes people say 'There isn't any address specified so its not really an addressing mode at all'. This is not really correct - the address of the data is the location following the instruction and in order to get the data the processor has to output the address contained in the program counter on the address bus and read the data that comes back on the data bus into the appropriate register. So although no address is specified in the instruction, there is an address and it can be deduced by the processor from the address of the instruction itself. It is really a special case of relative addressing which we shall look at later.
The processor will automatically read the correct number of bytes of data for the size of register into which data is being transferred. The accumulators are 8 bits and require one byte of data but the index registers are 16 bits and so require two bytes. e.g.
Load IR X with 2000 LDX #$2000 8E 20 00This is an important point to remember and which which often catches you out in the lab. If you forget to supply two bytes the processor can't detect this, it will just take the next byte which you intend to be an instruction and put it into the IR. The processor is then out of step with your instructions which can have disastrous effects.
This name is a little confusing because it is not very direct at all - but Motorola call it this so we will have to stick with it.
The purpose of this mode is to allow an address to be specified using only 8 bits rather than 16. This leads not only to shorter instructions and shorter programs but also faster instructions because the extra byte does not have to fetched from memory. The way it works is that the address byte specified in the program is the least significant byte. The most significant byte is supplied by the DP or Direct Page register in the processor. Suppose in our program we are going to access a lot of data in the range FE00 to FE10, then we could load DP with FE and then use direct addressing throughout. Unfortunately there is no instruction for loading DP easily, we have to load A or B with the appropriate value and transfer it into DP-
Load A with FE LDA #$FE 86 FE Transfer A to DP TFR A,DP 1F 8BThen if we want to load A from location FE00 we can say
Load A from DP+0 LDA <$00 96 00or if we want to store B in FE01
Store B in DP+01 STB <$01 D7 01So once we have loaded DP with the appropriate page value or base value we can easily refer to addresses within that page of 256 memory locations.
This is an example of Effective Address calculation. The processor does not use the address part of the instruction immediately, it calculates the address by taking the DP value, shifting it right 8 places and then adding the address given in the instruction. This is a useful term and we will come across it quite a lot in future.
Store B in FE01 STB $FE01 F7 FE 01 Load IRX from 102B LDX $102B BE 10 2BNote with this last example, since IRX is a 16 bit register two bytes of data are needed. These are taken from 102B AND 102C which are copied into the high and low bytes of X respectively.
| instruction description | mnemonic | op-code |Where the instruction description refers to M (e.g. A=A+M) this always refers to the contents of the effective address (EA) of the data.
The mnemonic given is the basic one; if you want to distinguish between immediate data and an address, then you will have to add a hash (#) after the mnemonic to indicate immediate data.
Most of the op-codes given are single bytes. The two (or four) letters after the op-code (e.g. dd) are to help you decide how many bytes of data are required, and whether this is data (dd), address (mm/nn) or an offset (bb).
dd indicates a byte of immediate data mm nn are two bytes of a full address nn is the low byte, used in direct addressing bb is a 2's complement offset to PC which allows the program to branch ++ is the postbyte (and offset) for indexed mode
OPERATION | MNEMONIC | OP-CODE (+ bytes) | ||||
---|---|---|---|---|---|---|
Immediate | Extended | Indexed | Inherent | Relative | ||
Add with carry A=A+M+C | ADCA | 89 dd | B9 mm nn | A9 ++ | ||
Add A=A+M | ADDA | 8B dd | BB mm nn | AB ++ | ||
Add B=B+M | ADDB | CB dd | FB mm nn | EB ++ | ||
And A=A AND M | ANDA | 84 dd | B4 mm nn | A4 ++ | ||
Clear accumulator A=0 | CLRA | 4F | ||||
Clear accumulator B=0 | CLRB | 5F | ||||
Compare (A-M) set flags | CMPA | 81 dd | B1 mm nn | A1 ++ | ||
Or A=A OR M | ORA | 8A dd | BA mm nn | AA ++ | ||
Load accumulator A=M | LDA | 86 dd | B6 mm nn | A6 ++ | ||
Store accumulator M=A | STA | B7 mm nn | A7 ++ | |||
Load double accumulator D=M:M+1 | LDD | CC dd dd | FC mm nn | EC ++ | ||
Store double accumulator M:M+1=D | STD | FD mm nn | EC ++ | |||
Load X register X=M:M+1 | LDX | 8E dd dd | BE mm nn | AE ++ | ||
Branch if zero flag Z=1 | BEQ | 27 bb | ||||
Branch if not zero flag Z=0 | BNE | 26 bb | ||||
Branch if minus flag N=1 | BMI | 2B bb | ||||
Jump PC=M:M+1 | JMP | 7E mm nn | ||||
Software Interrupt End program | SWI | 3F | ||||
No operation PC=PC+1 | NOP | 12 | ||||
Increment Memory M=M+1 | INC | 7C mm nn | 6C ++ | |||
Decrement Memory M=M-1 | DEC | 7A mm nn | 6A ++ |