Skip to content

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...