DWMC-16: Instruction Set v0.5.1 - Deprecated
And again... Here I am, doing another revision of the Instruction set, this time very much centered around the Addressing modes.
Legend¶
| Rd | Destination Register |
|---|---|
| Rs, Rs2 | Source Registers |
| PR | Program Counter |
| C | Constant Number |
| Addr | Memory Address |
| ST | Stack Pointer |
| F | Flag bit |
| MSB | Most Significant Bit |
| LSB | Least Significent Bit |
Addressing Modes¶
Since I have eight bits of opcode available, I want to leave six bits for 64 instructions.
Previously, I worried about adding other Addressing modes, compared to the modes in v0.5 with only two bits available, before I realised I can do variable length. I can encode up two addressing modes with two bits, and any more addressing modes with more than two, say four bit. I just have to move the register/flag of Type 2 operations to the lowest four bits of the word.
| Adressing Mode | Example | Bitcode | Comment |
|---|---|---|---|
| Register | add R00, R01 |
0b00 |
|
| Indirect (Register) | ld R00, @R01 |
0b01 |
|
| Immediate (Constants) | ld R00, 0x0F0F |
0b1000 |
|
| Direct Sector | ld R00, [0x0F0F] |
0b1001 |
|
| Direct Absolute | ld R00, [0x0F0F0F] |
0b1010 |
|
| Indirect (Z) | ld R00 |
0b1011 |
|
| Indexed (Z) | ld R00, +0x000F |
0b1100 |
Adds the second operant to the Z-Index Register |
| General Adressing Modes |
This means that I have seven addressing modes available.
But... Not for all Operations. Going through the list, I did realise that this kind of variable length Addressing mode will not work for four of the branch operations breq/brneq and bgt/bge, as these branch operations need two Registers to compare, which makes it necessary that I put their Addressing modes into its own list...
| Adressing Mode | Example | Bitcode |
|---|---|---|
| Direct Sector | bre R00, R01, [0x0F0F] |
0b00 |
| Direct Absolute | bre R00, R01, [0x0F0F0F] |
0b01 |
| Indirect (Z) | bre R00, R01 |
0b10 |
| Indexed (Z) | bre R00, R01, 0x000F |
0b11 |
| Addressing Modes for Branch Operations |
I certainly dislike having to do it this way, but for the time being, I do not have an idea how to integrate both sides together and keep 6 bits of opcode.
OpCode Encoding¶
The change of the addressing modes does change the opcode encoding, again, as this time, Type 2 and Type 3 encoded operations are possible with the same operation, depending on the addressing mode. The new Branch Address Modes also make it necessary to add a Type 4 for opcode design.
| MSB | LSB | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | |
| Type 1: One word, no registers | ||||||||||||||||
| Word 1 | Opcode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||||
| Type 2: One Word, one register | ||||||||||||||||
| Word 1 | Opcode | Address Mode | 0 | 0 | Register/Flag | |||||||||||
| Type 3: One Word, two registers | ||||||||||||||||
| Word 1 | Opcode | Address Mode | Source Register | Destination Register | ||||||||||||
| Type 4: One Word, one Register, Branch Operation | ||||||||||||||||
| Word1 | Opcode | Address Mode | 0 | 0 | 0 | 0 | Register | |||||||||
| Addressing Mode: Direct Local/Constants/Indexed | ||||||||||||||||
| Word 2 | Low Address Word (16 bit)/Constants/Indexed | |||||||||||||||
| Addressing Mode: Direct (Global) | ||||||||||||||||
| Word 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | High Address Word (8 bit) | |||||||
| Word 3 | Low Address Word (16 bit) |
Data Transfer Operations (3 Operations)¶
| Command | Mnemonic | Operation | Opcode | Address Modes | OpType | Affected Flags |
|---|---|---|---|---|---|---|
| Load | ld Rd, Adr/C |
Rd <= Memory[Addr]/C | 0b000010 |
all Address |
2 | None |
| Store | st Rs, Addr16 |
Memory[Addr] <= Rs | 0b000100 |
`all Address` |
2 | None |
| Move | mv Rd, Rs |
Rd <= Rs | 0b001000 |
N.A. |
3 | None |
The Load and Store operations certainly allow the use of all Address Modes.
Arythmic Logical Operations (13 Operations)¶
| Command | Mnemonic | Operation | Opcode | Address Modes | OpType | Affected Flags |
|---|---|---|---|---|---|---|
| Add | add Rd, Rs/C |
Rd <= Rd + Rs/C | 0b010001 |
`all Address` |
3 | C, QC, HC, TC, Z, N, O |
| Increment | inc Rd |
Rd <= Rd + 1 | 0b010010 |
N.A. |
2 | C, QC, HC, TC, Z, N, O |
| Substract | sub Rd, Rs/C |
Rd <= Rd - Rs/C | 0b010011 |
`all Address` |
3 | C, QC, HC, TC, Z, N, O |
| Decrement | dec Rd |
Rd <= Rd - 1 | 0b010100 |
N.A. |
2 | C, QC, HC, TC, Z, N, O |
| Bitwise AND | and Rd, Rs/C |
Rd <= Rd & Rs/C | 0b010101 |
`all Address` |
3 | Z |
| Bitwise OR | or Rd, Rs/C |
Rd <= Rd | Rs/C | 0b010110 |
`all Address` |
3 |
| Bitwise XOR | xor Rd, Rs/C |
Rd <= Rd ^ Rs/C | 0b010111 |
``` `` `all Address` `` ``` |
3 | Z |
| Bitwise NOT | not Rd |
Rd <= ~Rd | 0b011000 |
N.A. |
2 | Z |
| Logical Shift Left | lsl Rd |
Rd <= Rd << 1 | ||||
| LSB <= Carry | ||||||
| Carry <= MSB | 0b011001 |
N.A. |
2 | C, Z | ||
| Logical Shift Right | lsr Rd |
Rd <= Rd >> 1 | ||||
| MSB <= Carry | ||||||
| Carry <= LSB | 0b011010 |
N.A. |
2 | C, Z | ||
| Logical Rotate Left | lrl Rd |
Rd <= Rd << 1 | ||||
| LSB <= MSB | 0b011011 |
N.A. |
2 | None | ||
| Logical Rotate Right | lrr Rd |
Rd <= Rd >> 1 | ||||
| MSB <= LSB | 0b011100 |
N.A. |
2 | None | ||
| Logical Switch Byte | lsb Rd |
Rd[Low] <= Rd[High] | ||||
| Rd[High] <= Rd[Low] | 0b011101 |
N.A. |
2 | None |
Here, of course, all operations with two operants allow the use of all conventional addressing modes.
Conditional Branch Instructions (10 Operations)¶
| Command | Mnemonic | Operation | Opcode | Address Modes | OpType | Affected Flags |
|---|---|---|---|---|---|---|
| Branch local if Flag | blf F, Addr |
if (F == 0): PCL <= Addr/Z | 0b100000 |
All Branch Address Modes |
2 | None |
| Branch if not Flag | bnf F, Addr |
if (F != 0): PCL <= Addr/Z | 0b100001 |
`` `All Branch Address Modes` `` |
2 | None |
| Branch if Bit | bb B, Addr |
if (B == 0): PC <= Addr/Z | 0b100010 |
`` `All Branch Address Modes` `` |
2 | None |
| Branch if not Bit | bnb B, Addr |
if (B !=0): PC <= Addr/Z | 0b100011 |
`` `All Branch Address Modes` `` |
2 | None |
| Branch if Zero, Decrement | bzd Rd, Addr |
if (Rd == 0): PCL <= Addr/Z | ||||
| else Rd <= Rd - 1 | 0b100100 |
`` `All Branch Address Modes` `` |
2 | C, Z, N | ||
| Branch if not Zero, Decrement | bnzd Rd, Addr |
if (Rd != 0): PCL <= Addr/Z | ||||
| else Rd <= Rd - 1 | 0b100101 |
`` `All Branch Address Modes` `` |
2 | C, Z, N | ||
| Branch if Registers Equal | breq Rs, Rs2, Addr |
if (Rs == Rs2): PCL <= Addr/Z | 0b100110 |
`All Branch Address Modes` |
4 | C, Z, N |
| Branch if Registers not Equal | brne Rs, Rs2, Addr |
if (Rs != Rs2): PCL <= Addr/Z | 0b100111 |
`All Branch Address Modes` |
4 | C, Z, N |
| Branch if greater then | bgt Rs, Rs2, Addr |
if (Rs > Rs2): PCL <= Addr/Z | 0b101000 |
`All Branch Address Modes` |
4 | C, Z, N |
| Branch if greater then or equal | bge Rs, Rs2, Addr |
if (Rs >= Rs2): PCL <= Addr/Z | 0b101001 |
`All Branch Address Modes` |
4 | C, Z, N |
I like to repeat again that I dislike the need to use a separate table for Branch Address Modes, but for the moment it is how it is.
Other Operations ( 11 Operations)¶
| Command | Mnemonic | Operation | Opcode | Address Modes | OpType | Affected Flags |
|---|---|---|---|---|---|---|
| Jump | jp Addr |
PCL <= Addr/Z | 0b110000 |
`0b1001, 0b1010, 0b1011, 0x1100` |
1 | None |
| Jump to Subroutine | jls Addr |
ST <= PC + 1; | ||||
| PCL <= Addr | 0b110001 |
`0b1001, 0b1010, 0b1011, 0x1100` |
1 | None | ||
| Return | ret |
PC <= ST | 0b110010 |
N.A. |
1 | None |
| Return from Interrupt | reti |
PC <= ST (see post) | 0b110011 |
N.A. |
1 | Any |
| Push to Stack | push Rs |
ST <= Rs | 0b110100 |
N.A. |
2 | None, Any |
| Pop from Stack | pop Rd |
Rd <= ST | 0b110101 |
N.A. |
2 | None, Any |
| Set Flag | sf F |
F <= 1 | 0b110101 |
N.A. |
2 | Any |
| Reset Flag | rf F |
F <= 0 | 0b110111 |
N.A. |
2 | Any |
| Set Bit | sb B |
R08[B] <= 1 | 0b111000 |
N.A. |
2 | None |
| Reset Bit | rb B |
R08[B] <= 0 | 0b111001 |
N.A. |
2 | None |
| No operation | nop |
No operation | 0xFF |
N.A. |
1 | None |
With the two jump operations being the only operations that really need and Address modes, it does not really make any sense to give them all address modes, so I am limiting them to the the two Direct modes, as well as Indirect and Indexed via the Z Index Register.
Conclusions¶
The number of operations does not change here, but hopefully makes the addressing more powerful.
And I really hope that I find some way to get rid of that damned additional Branch Addressing Mode Table...