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

RdDestination Register
Rs, Rs2Source Registers
PRProgram Counter
CConstant Number
Addr16Memory Address (16 bit)
Addr24Memory Address (24 bit)
STStack Pointer
FFlag bit
MSBMost Significant Bit
LSBLeast 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)

CommandMnemonicOperationOpcodeOpTypeAffected Flags
Load Direct Localldl Rd, Addr16Rd <= Memory[Addr16]0b00001000/0x085None
Load Direct Globalldg Rd, Addr24Rd <= Memory[Addr24]0b00001001/0x098None
Load Indirectldi RdRd <= Memory[Z]0b00001010/0x0A2None
Load Constantldc Rd, CRd <= C (PC+1)0b00001100/0x0C5None
Store Direct Localstl Rs, Addr16Memory[Addr16] <= Rs0b00010000/0x102None
Load Direct Globalstg Rs, Adr24Memory[Addr24] <= Rs0b00010001/0x118None
Store Indirectsti RsMemory[Z] <= Rs0b00010010/0x122None
Movemv Rd, RsRd <= Rs0b00100000/0x203None

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)

CommandMnemonicOperationOpcodeOpTypeAffected Flags
Addadd Rd, RsRd <= Rd + Rs0b01000101/0x453C, QC, HC, TC, Z, N, O
Incrementinc RdRd <= Rd + 10b01010101/0x552C, QC, HC, TC, Z, N, O
Substractsub Rd, RsRd <= Rd – Rs0b01100101/0x653C, QC, HC, TC, Z, N, O
Decrementdec RdRd <= Rd – 10b01110101/0x752C, QC, HC, TC, Z, N, O
Bitwise ANDand Rd, RsRd <= Rd & Rs0b01000010/0x423Z
Bitwise ORor Rd, RsRd <= Rd | Rs0b01000011/0x433Z
Bitwise XORxor Rd, RsRd <= Rd ^ Rs0b01000001/0x413Z
Bitwise NOTnot RdRd <= ~Rd0b01000000/0x402Z
Logical Shift Leftlsl RdRd <= Rd << 1
LSB <= Carry
Carry <= MSB
0b01000110/0x462C, Z
Logical Shift Rightlsr RdRd <= Rd >> 1
MSB <= Carry
Carry <= LSB
0b01000111/0x472C, Z
Logical Rotate Leftlrl RdRd <= Rd << 1
LSB <= MSB
0b01010110/0x562None
Logical Rotate Rightlrr RdRd <= Rd >> 1
MSB <= LSB
0b01010111/0x572None
Logical Switch Bytelsb RdRd[Low] <= Rd[High]
Rd[High] <= Rd[Low]
0b01001000/0x482None

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)

CommandMnemonicOperationOpcodeOpTypeAffected Flags
Branch local if Flagblf F, Addr16if (F == 0): PCL <= Addr160b10000000/0x804None
Branch if not Flagbnf F, Addr16if (F != 0): PCL <= Addr160b10000001/0x814None
Branch if Bitbb B, Addr16if (B == 0): PC <= Addr160b10000010/0x824None
Branch if not Bitbnb B, Addr16if (B !=0): PC <= Addr160b10000011/0x834None
Branch if Zero, Decrementbzd Rd, Addr16if (Rd == 0): PCL <= Addr16
else Rd <= Rd – 1
0b10000100/0x844C, Z, N
Branch if not Zero, Decrementbnzd Rd, Addr16if (Rd != 0): PCL <= Addr16
else Rd <= Rd – 1
0b10000101/0x854C, Z, N
Branch if Registers Equalbreq Rs, Rs2, Addr16 if (Rs == Rs2): PCL <= Addr160b10000110/0x865C, Z, N
Branch if Registers not Equalbrne Rs, Rs2, Addr16if (Rs != Rs2): PCL <= Addr160b10000111/0x875C, Z, N
Branch if greater thenbgt Rs, Rs2, Addr16if (Rs > Rs2): PCL <= Addr160b10001000/0x885C, Z, N
Branch if greater then or equalbge Rs, Rs2, Addr16if (Rs >= Rs2): PCL <= Addr160b10001001/0x895C, 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)

CommandMnemonicOperationOpcodeOpTypeAffected Flags
Jump Local Directjpl Addr16PCL <= Addr160b11000000/0xC04None
Jump Global Directjpg Addr24PC <= Addr240b11000001/0xC17None
Jump Local IndirectjpliPCL <= Z0b11000010/0xC21None
Jump to Local
Subroutine
jpls Addr16ST <= PC + 1;
PCL <= Addr16
0b11000100/0xC44None
Jump to Global
Subroutine
jpgs Addr24ST <= PC + 1:
PC <= Addr24
0b11000101/0XC56None
ReturnretPC <= ST0b11001000/0xC81None
Return from InterruptretiPC <= ST (see post)0b11001001/0xC91Any
Push to Stackpush RsST <= Rs0b11010000/0xD02None, Any
Pop from Stackpop RdRd <= ST0b11010001/0xD12None, Any
Set Flagsf FF <= 10b11100000/0xE02Any
Reset Flagrf FF <= 00b11100001/0xE12Any
Set Bitsb BR08[B] <= 10b11100010/0xE22None
Reset Bitrb BR08[B] <= 00b11100011/0xE32None
No operationnopNo operation0b11111111/0xFF1None

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.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.