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 - 01
On 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 - FF
Four 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 - 00
This 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 memory
Even 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
Relative
Many 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
FF
Sometimes 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
00
This 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
8B
Then if we want to load A from location FE00 we can say
Load A from DP+0 LDA <$00 96
00
or if we want to store B in FE01
Store B in DP+01 STB <$01 D7
01
So 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
2B
Note 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 ++ | |||