Skip to content

DWMC-16: Instruction Set V0.4 - Deprecated

With my emulator going strong in its development and me already thinking about the Control Logic and how I want to deal with it... I think that I need another list of operations.

Which will have a few modifications and additions that come with another set of types of memory access/addressing. Such as a difference between local and global addressing. Local Addressing can only access the local 64kWords sector of memory, while the global memory can access the entirety of the memory.

Legend

Rd Destination Register
Rs, Rs2 Source Registers
PR Program Counter
C Constant Number
Addr16 Memory Address (16 bit)
Addr24 Memory Address (24 bit)
ST Stack Pointer
F Flag bit
MSB Most Significant Bit
LSB Least Significent Bit

OpCode Encoding

I will also add a list of opcode designs

MSBLSB
1514131211109876543210
Word 0Opcode00000000

Type 1: One word opcodes without registers

MSBLSB
1514131211109876543210
Word 0OpcodeRegister/Flag0000

Type 2: One word opcodes with one register

MSBLSB
1514131211109876543210
Word 0OpcodeDestination
Register
Source
Register

Type 3: One word opcodes with two registers

MSBLSB
1514131211109876543210
Word 0Opcode00000000
Word 1Address Low Word

Type 4: Two word opcodes with address for local memory sector

MSBLSB
1514131211109876543210
Word 0OpcodeRegister/Flag0000
Word 1Address Low Word

Type 5: Two word opcodes with one register and address for local memory sector

MSBLSB
1514131211109876543210
Word 0OpcodeDestination
Register
Source
Register
Word 1Address Low Word

Type 6: Two word opcodes with two registers and address for local memory sector

MSBLSB
1514131211109876543210
Word 0Opcode00000000
Word 1Address High Word
Word 2Address Low Word

Type 7: Three word opcodes with address for global memory access

MSBLSB
1514131211109876543210
Word 0OpcodeRegister/Flag0000
Word 1Address High Word
Word 2Address Low Word

Type 8: Three word opcodes with one register and address for global memory access

Data Transfer Operations (8 Operations)

Command Mnemonic Operation Opcode OpType Affected Flags
Load Direct Local ldl Rd, Addr16 Rd <= Memory[Addr16] 0b00001000/0x08 5 None
Load Direct Global ldg Rd, Addr24 Rd <= Memory[Addr24] 0b00001001/0x09 8 None
Load Indirect ldi Rd Rd <= Memory[Z] 0b00001010/0x0A 2 None
Load Constant ldc Rd, C Rd <= C (PC+1) 0b00001100/0x0C 5 None
Store Direct Local stl Rs, Addr16 Memory[Addr16] <= Rs 0b00010000/0x10 2 None
Load Direct Global stg Rs, Adr24 Memory[Addr24] <= Rs 0b00010001/0x11 8 None
Store Indirect sti Rs Memory[Z] <= Rs 0b00010010/0x12 2 None
Move mv Rd, Rs Rd <= Rs 0b00100000/0x20 3 None

The Load Constant is the new operation, meant to directly load any 16 bit constant into a register, allowing to get around any Z register shenanigans.

Arythmic Logical Operations (13 Operations)

Command Mnemonic Operation Opcode OpType Affected Flags
Add add Rd, Rs Rd <= Rd + Rs 0b01000101/0x45 3 C, QC, HC, TC, Z, N, O
Increment inc Rd Rd <= Rd + 1 0b01010101/0x55 2 C, QC, HC, TC, Z, N, O
Substract sub Rd, Rs Rd <= Rd - Rs 0b01100101/0x65 3 C, QC, HC, TC, Z, N, O
Decrement dec Rd Rd <= Rd - 1 0b01110101/0x75 2 C, QC, HC, TC, Z, N, O
Bitwise AND and Rd, Rs Rd <= Rd & Rs 0b01000010/0x42 3 Z
Bitwise OR or Rd, Rs Rd <= Rd Rs 0b01000011/0x43 3
Bitwise XOR xor Rd, Rs Rd <= Rd ^ Rs 0b01000001/0x41 3 Z
Bitwise NOT not Rd Rd <= ~Rd 0b01000000/0x40 2 Z
Logical Shift Left lsl Rd Rd <= Rd << 1
LSB <= Carry
Carry <= MSB 0b01000110/0x46 2 C, Z
Logical Shift Right lsr Rd Rd <= Rd >> 1
MSB <= Carry
Carry <= LSB 0b01000111/0x47 2 C, Z
Logical Rotate Left lrl Rd Rd <= Rd << 1
LSB <= MSB 0b01010110/0x56 2 None
Logical Rotate Right lrr Rd Rd <= Rd >> 1
MSB <= LSB 0b01010111/0x57 2 None
Logical Switch Byte lsb Rd Rd[Low] <= Rd[High]
Rd[High] <= Rd[Low] 0b01001000/0x48 2 None

The Opcodes for the Arythmic Logic Operations look a bit strange, but that is mostly because I want to push the lowest three bits of the Opcode directly into the ALU and the other three bits can then be used to distinguish between the other operations that are similar.

Like Addition, Sustraction making use of the same logic circuits, for example. I also just realised that I can use two of those bits to directly push into the ALU to set the type of 'addition'. Bit 5 for indicating whether or not the operation is a substractive operation , while Bit 4 indicated of the operation is an increment/decrement.

The same is true for the Shift and Rotate operations, as they make use of the same logic, with the only difference being whether the shift happens through the carry bit or not.

The Logic Switch Byte is meant to switch the two bytes of the 16 bit words used by the DWMC-16 quickly, an operation useful if a program needs to push/pul data from an 8 bit IO device.

Conditional Branch Instructions (10 Operations)

Command Mnemonic Operation Opcode OpType Affected Flags
Branch local if Flag blf F, Addr16 if (F == 0): PCL <= Addr16 0b10000000/0x80 4 None
Branch if not Flag bnf F, Addr16 if (F != 0): PCL <= Addr16 0b10000001/0x81 4 None
Branch if Bit bb B, Addr16 if (B == 0): PC <= Addr16 0b10000010/0x82 4 None
Branch if not Bit bnb B, Addr16 if (B !=0): PC <= Addr16 0b10000011/0x83 4 None
Branch if Zero, Decrement bzd Rd, Addr16 if (Rd == 0): PCL <= Addr16
else Rd <= Rd - 1 0b10000100/0x84 4 C, Z, N
Branch if not Zero, Decrement bnzd Rd, Addr16 if (Rd != 0): PCL <= Addr16
else Rd <= Rd - 1 0b10000101/0x85 4 C, Z, N
Branch if Registers Equal breq Rs, Rs2, Addr16 if (Rs == Rs2): PCL <= Addr16 0b10000110/0x86 5 C, Z, N
Branch if Registers not Equal brne Rs, Rs2, Addr16 if (Rs != Rs2): PCL <= Addr16 0b10000111/0x87 5 C, Z, N
Branch if greater then bgt Rs, Rs2, Addr16 if (Rs > Rs2): PCL <= Addr16 0b10001000/0x88 5 C, Z, N
Branch if greater then or equal bge Rs, Rs2, Addr16 if (Rs >= Rs2): PCL <= Addr16 0b10001001/0x89 5 C, Z, N

Even with the new global addressing, I believe that the vast majority (>99%) of branches happen locally, so for the moment, I do not see a need for global branching.

Also added the new Brach if (not) Bit operations for Test Register R08.

Other Operations (12 Operations)

Command Mnemonic Operation Opcode OpType Affected Flags
Jump Local Direct jpl Addr16 PCL <= Addr16 0b11000000/0xC0 4 None
Jump Global Direct jpg Addr24 PC <= Addr24 0b11000001/0xC1 7 None
Jump Local Indirect jpli PCL <= Z 0b11000010/0xC2 1 None
Jump to Local
Subroutine jpls Addr16 ST <= PC + 1;
PCL <= Addr16 0b11000100/0xC4 4 None
Jump to Global
Subroutine jpgs Addr24 ST <= PC + 1:
PC <= Addr24 0b11000101/0XC5 6 None
Return ret PC <= ST 0b11001000/0xC8 1 None
Return from Interrupt reti PC <= ST (see post) 0b11001001/0xC9 1 Any
Push to Stack push Rs ST <= Rs 0b11010000/0xD0 2 None, Any
Pop from Stack pop Rd Rd <= ST 0b11010001/0xD1 2 None, Any
Set Flag sf F F <= 1 0b11100000/0xE0 2 Any
Reset Flag rf F F <= 0 0b11100001/0xE1 2 Any
Set Bit sb B R08[B] <= 1 0b11100010/0xE2 2 None
Reset Bit rb B R08[B] <= 0 0b11100011/0xE3 2 None
No operation nop No operation 0b11111111/0xFF 1 None

The Return from Interrupt operation does what it says on the tin, and was discussed in this post.

I've also decided to have the hardware of Test Register R08 and the Flag Register to be identical, which will allow me to set/reset single bits in the Test Register without need to use an OR operation and a mask.

Conclusion

With that, the number of instructions raises to 45 operations again.