Skip to content

Instantly share code, notes, and snippets.

@Longor1996
Last active September 7, 2020 17:15
Show Gist options
  • Save Longor1996/6425450 to your computer and use it in GitHub Desktop.
Save Longor1996/6425450 to your computer and use it in GitHub Desktop.
Experimental DCPU-32 Specification
(formatting may be messed up!)
DCPU-MK2 Specification
Copyright 2013 Longor1996
Version 1.0
NOTE THAT THIS SPECIFICATION IS STILL PARTIALLY ERROR-PRONE!
THERE MAY BE FATAL LOGICAL MISTAKES IN IT!
READ AND USE WITH CAUTION AND TAKE EVERYTHING WITH A GRAIN OF SALT!
On another note, please note that this DCPU tries to get close enough to a real CPU emulation-wise, but also tries to not be complicated, while also trying not to be too restricted.
-------{ }------------------------------------------------------------------------------------------------------
-------{ MAIN INFO }------------------------------------------------------------------------------------------------------
-------{ }------------------------------------------------------------------------------------------------------
* UNSIGNED BYTE BASE
\ Two datatypes.
| Unsigned Byte [0 / 255]
| Signed Int [-2'147'483'648 / +2'147'483'647]
// WILL BE CHANGED INTO A IN/OUT SYSTEM TO EMULATE A REAL CPU MORE CLOSELY
* DIRECT (INTERNAL-)HARDWARE SLOTS
| 12 ports (indexed 0-11)
| Can be changed while system is running, but causes unexpected behavior while doing so.
| 'HWT a' instruction can be used to look if there is something in the slots.
* CPU-STACK:
| Stack can hold signed-32bit-integer values
| Read/Write Access over the PUSH/POP/PEEK instructions.
* REGISTERS:
| 32bit signed integers
| Read/Write Access
| Named: AA BB CC XX YY ZZ II JJ RR SS TT
| Indexes: 0-N
* PROGRAM-COUNTER: PC
| 32bit signed integer
| Read/Write Access
* STACK-POINTER: SP
| Implementation depending size
| Read Only Access
* INTERRUPT-ADDRESS: IA
| 32bit signed integer
| Read/Write Access
* ACCUMULATOR DESTINATION REGISTER: ADR | ACCUM_DEST_REG
| Nibble, 0-15.
| Initial Value: 0 (AA Register Index)
| Read/Write Access
* ERROR-FLAG: EF
| Bit-Flag
| Initial Value: 0
| Read Only Access
The opcode (The first Byte of a instruction) says everything about the entire instruction,
including the information about its parameters and the time it needs.
Data Read-Access Examples:
* MOV 0x111, AA | Moves ? to AA (D-LITERAL 000) OUT_VAL = next();
* MOV BB, AA | Moves BB to AA (D-REG 001) OUT_VAL = REG[?]
* MOV [BB], AA | Moves from RAM[REGISTER[BB]] to AA (ID-RAM-OR 010) OUT_VAL = RAM[REG[?]]
* MOV [0x111], AA | Moves from RAM[0x111] to AA (D-RAM 011) OUT_VAL = RAM[?]
* MOV [*0x111], AA | Moves RAM[RAM[0x111]] to AA (ID-RAM 100) OUT_VAL = RAM[RAM[?]]
Data Write-Access Examples:
* MOV BB, AA | Moves BB to ?? (D-REG 001) | REG[?] = VAL
* MOV BB, [AA] | Moves from BB to RAM[REGISTER[??]] (ID-RAM-OR 010) | RAM[REG[?]] = VAL
* MOV BB, [??] | Moves from BB to RAM[??] (D-RAM 011) | RAM[?] = VAL
* MOV BB, [*??] | Moves from BB to RAM[RAM[??]] (ID-RAM 100) | RAM[RAM[?]] = VAL
-------{ }------------------------------------------------------------------------------------------------------
-------{ ASSEMBLER OPCODES }------------------------------------------------------------------------------------------------------
-------{ }------------------------------------------------------------------------------------------------------
------------------+---------------------------------------------------------------------------------------------------------------
DAT_I textualData | Stores the given integer(s) at the current assembler-pointer position
DAT_B textualData | Stores the given byte(s) at the current assembler-pointer position
DAT_S textualData | Stores the given string at the current assembler-pointer position, and post-fixes it with a null-byte.
------------------+---------------------------------------------------------------------------------------------------------------
-------{ }----------------------------------------------------------------------------------------------------------------
-------{ OPCODES }----------------------------------------------------------------------------------------------------------------
-------{ }----------------------------------------------------------------------------------------------------------------
C = The amount of cycles it takes. ? means that it fully depends on how the opcode is used.
CODE = The hexadecimal representation of the bytecode identifier for the opcode.
SYNTAX = How the opcode is written out.
DESCRIPTION = A description on what the opcode does.
n/a = Empty/Unknown/Undefined
+X = X plus cycles to complete.
* = Nothing.
Instructions are defined as:
* Write OOOOOOOO (OpCode Identifier Byte)
* For each Parameter:
* If it is a register Parameter, write RRRRAAAA.
* If it is a ram Parameter, write 0000AAAA IIIIIIII-IIIIIIII-IIIIIIII-IIIIIIII
Bit-Info:
A being the address-information bits,
R being the register-index bits,
I being the ram-index bits,
0 being zero-bits.
---+------+------------------+----------------------------------------------------------------------------------------------------
C | CODE | SYNTAX | DESCRIPTION
---+------+------------------+----------------------------------------------------------------------------------------------------
* | 0x00 | HLT | Shuts down the system. Every/Any-thing running will be shutdown without warning.
? | 0x01 | MOV b, a | Moves (copies) b to a. (32bit signed integer operation)
? | 0x02 | MVB b, a | Moves (copies) b to a. (8bit unsigned byte operation)
---+------+------------------+----------------------------------------------------------------------------------------------------
+1 | 0x03 | JSR b | Jump (to) Sub-Routine at b (PUSH PC, MOV A PC)
+1 | 0x04 | RSR | Return (from) Sub-Routine (POP PC)
+1 | 0x05 | PUSH b | Puts b onto the systems stack.
0 | 0x06 | POP b | Pops the topmost element from the CPU's stack into b. If the stack is empty, the system will crash.
0 | 0x07 | PEEK b | Copies the topmost element of the CPU's stack into b. If the stack is empty, the system will crash.
0 | 0x08 | SLEEP c | Let's the DCPU sleep for the given amount of cycles.
0 | 0x09 | n/a |
---+------+------------------+----------------------------------------------------------------------------------------------------
1 | 0x0A | HW? b, a | IGNORE NOT_IMPLEMENTED Sends b to the hardware at port a.
1 | 0x0B | HW? b, a | IGNORE NOT_IMPLEMENTED Tries to read a value from the hardware at port a into b. This will crash if there is nothing connected.
1HP| 0x0C | HWN | Sets [ACCUM_DEST_REG] to the amount of hardware ports.
4 | 0x0D | HWQ b | Tries to query hardware-port b for information of the hardware.
1 | 0x0E | HWI b, a | Sends an interrupt message b to hardware-port a. (if nothing is connected, the error-flag is set to 1)
1 | 0x0F | HWT b | Tests if there is hardware connected at hardware-port b and sets the [ACCUM_DEST_REG] register to 1 if there is.
---+------+------------------+----------------------------------------------------------------------------------------------------
? | 0x10 | ADD b, a | Sets [ACCUM_DEST_REG] to b+a (b and a = signed 32bit integers)
? | 0x11 | SUB b, a | Sets [ACCUM_DEST_REG] to b-a (b and a = signed 32bit integers)
? | 0x12 | MUL b, a | Sets [ACCUM_DEST_REG] to b*a (b and a = signed 32bit integers)
? | 0x13 | DIV b, a | Sets [ACCUM_DEST_REG] to b/a (b and a = signed 32bit integers)
? | 0x14 | MOD b, a | Sets [ACCUM_DEST_REG] to b%a (b and a = signed 32bit integers)
? | 0x15 | ADDB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b+a (b and a = unsigned bytes)
? | 0x16 | SUBB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b-a (b and a = unsigned bytes)
? | 0x17 | MULB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b*a (b and a = unsigned bytes)
? | 0x18 | DIVB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b/a (b and a = unsigned bytes)
? | 0x19 | MODB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b%a (b and a = unsigned bytes)
? | 0x1A | AND b, a | Sets [ACCUM_DEST_REG] to b&a (b and a = signed 32bit integers)
? | 0x1B | BOR b, a | Sets [ACCUM_DEST_REG] to b|a (b and a = signed 32bit integers)
? | 0x1C | XOR b, a | Sets [ACCUM_DEST_REG] to b^a (b and a = signed 32bit integers)
? | 0x1D | ANDB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b&a (b and a = unsigned bytes)
? | 0x1E | BORB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b|a (b and a = unsigned bytes)
? | 0x1F | XORB b, a | NOT_IMPLEMENTED Sets [ACCUM_DEST_REG] to b^a (b and a = unsigned bytes)
? | 0x20 | SHR b, a | Sets [ACCUM_DEST_REG] to b>>>a (b and a = signed 32bit integers)
? | 0x21 | ASR b, a | Sets [ACCUM_DEST_REG] to b>>a (b and a = signed 32bit integers)
? | 0x22 | SHL b, a | Sets [ACCUM_DEST_REG] to b<<a (b and a = signed 32bit integers)
0 | 0x23 | n/a |
0 | 0x24 | n/a |
0 | 0x25 | n/a |
0 | 0x26 | n/a |
0 | 0x27 | n/a |
0 | 0x28 | n/a |
0 | 0x29 | n/a |
0 | 0x2A | n/a |
0 | 0x2B | n/a |
0 | 0x2C | n/a |
0 | 0x2D | n/a |
0 | 0x2E | INCR b | Increases (register!) b by one. (Register-only operation)
0 | 0x2F | DECR b | Decreases (register!) b by one. (Register-only operation)
---+------+------------------+----------------------------------------------------------------------------------------------------
+2 | 0x30 | IFB b, a | NOT_IMPLEMENTED Only executes next instruction if: (b&a) != 0
+2 | 0x31 | IFC b, a | NOT_IMPLEMENTED Only executes next instruction if: (b&a) == 0
+2 | 0x32 | IFE b, a | Only executes next instruction if: b == a
+2 | 0x33 | IFN b, a | Only executes next instruction if: b != a
+2 | 0x34 | IFG b, a | Only executes next instruction if: b > a
+2 | 0x35 | IFA b, a | NOT_IMPLEMENTED Only executes next instruction if: b > a (signed?!)
+2 | 0x36 | IFL b, a | Only executes next instruction if: b < a
+2 | 0x37 | IFU b, a | NOT_IMPLEMENTED Only executes next instruction if: b < a (signed?!)
+2 | 0x38 | IFGE b, a | Only executes next instruction if: b >= a
+2 | 0x39 | IFLE b, a | Only executes next instruction if: b <= a
0 | 0x3A | n/a |
0 | 0x3B | n/a |
0 | 0x3C | n/a |
0 | 0x3D | n/a |
0 | 0x3E | n/a |
0 | 0x3F | n/a |
---+------+------------------+----------------------------------------------------------------------------------------------------
0 | 0x40 | n/a |
0 | 0x41 | n/a |
0 | 0x42 | n/a |
0 | 0x43 | n/a |
0 | 0x44 | n/a |
0 | 0x45 | n/a |
0 | 0x46 | n/a |
0 | 0x47 | n/a |
0 | 0x48 | n/a |
0 | 0x49 | n/a |
0 | 0x4A | n/a |
0 | 0x4B | INT b | Triggers a software interrupt with message b.
0 | 0x4C | IAG b | Sets b to IA.
0 | 0x4D | IAS b | Sets IA to b.
0 | 0x4E | RFI ???????????? | Disables interrupt queueing, pops A from the stack, then pops PC from the stack.
0 | 0x4F | IAQ b | If b is nonzero, interrupts will be added to the queue instead of triggered. If else, interrupts will be triggered as normal again.
---+------+------------------+----------------------------------------------------------------------------------------------------
0 | 0x50 | n/a |
0 | 0x51 | n/a |
0 | 0x52 | n/a |
0 | 0x53 | n/a |
0 | 0x54 | n/a |
0 | 0x55 | n/a |
0 | 0x56 | n/a |
0 | 0x57 | n/a |
0 | 0x58 | n/a |
0 | 0x59 | n/a |
0 | 0x5A | n/a |
0 | 0x5B | n/a |
0 | 0x5C | n/a |
0 | 0x5D | n/a |
0 | 0x5E | n/a |
0 | 0x5F | n/a |
0 | 0x60 | n/a |
0 | 0x61 | n/a |
0 | 0x62 | n/a |
0 | 0x63 | n/a |
0 | 0x64 | n/a |
0 | 0x65 | n/a |
0 | 0x66 | n/a |
0 | 0x67 | n/a |
0 | 0x68 | n/a |
0 | 0x69 | n/a |
0 | 0x6A | n/a |
0 | 0x6B | n/a |
0 | 0x6C | n/a |
0 | 0x6D | n/a |
0 | 0x6E | n/a |
0 | 0x6F | n/a |
0 | 0x70 | n/a |
0 | 0x71 | n/a |
0 | 0x72 | n/a |
0 | 0x73 | n/a |
0 | 0x74 | n/a |
0 | 0x75 | n/a |
0 | 0x76 | n/a |
0 | 0x77 | n/a |
0 | 0x78 | n/a |
0 | 0x79 | n/a |
0 | 0x7A | n/a |
0 | 0x7B | n/a |
0 | 0x7C | n/a |
0 | 0x7D | n/a |
0 | 0x7E | n/a |
0 | 0x7F | n/a |
---+------+------------------+----------------------------------------------------------------------------------------------------
0 | 0x80 | n/a |
0 | 0x81 | n/a |
0 | 0x82 | n/a |
0 | 0x83 | n/a |
0 | 0x84 | n/a |
0 | 0x85 | n/a |
0 | 0x86 | n/a |
0 | 0x87 | n/a |
0 | 0x88 | n/a |
0 | 0x89 | n/a |
0 | 0x8A | n/a |
0 | 0x8B | n/a |
0 | 0x8C | n/a |
0 | 0x8D | n/a |
0 | 0x8E | n/a |
0 | 0x8F | n/a |
0 | 0x90 | n/a |
0 | 0x91 | n/a |
0 | 0x92 | n/a |
0 | 0x93 | n/a |
0 | 0x94 | n/a |
0 | 0x95 | n/a |
0 | 0x96 | n/a |
0 | 0x97 | n/a |
0 | 0x98 | n/a |
0 | 0x99 | n/a |
0 | 0x9A | n/a |
0 | 0x9B | n/a |
0 | 0x9C | n/a |
0 | 0x9D | n/a |
0 | 0x9E | n/a |
0 | 0x9F | n/a |
0 | 0xA0 | n/a |
0 | 0xA1 | n/a |
0 | 0xA2 | n/a |
0 | 0xA3 | n/a |
0 | 0xA4 | n/a |
0 | 0xA5 | n/a |
0 | 0xA6 | n/a |
0 | 0xA7 | n/a |
0 | 0xA8 | n/a |
0 | 0xA9 | n/a |
0 | 0xAA | n/a |
0 | 0xAB | n/a |
0 | 0xAC | n/a |
0 | 0xAD | n/a |
0 | 0xAE | n/a |
0 | 0xAF | n/a |
0 | 0xB0 | n/a |
0 | 0xB1 | n/a |
0 | 0xB2 | n/a |
0 | 0xB3 | n/a |
0 | 0xB4 | n/a |
0 | 0xB5 | n/a |
0 | 0xB6 | n/a |
0 | 0xB7 | n/a |
0 | 0xB8 | n/a |
0 | 0xB9 | n/a |
0 | 0xBA | n/a |
0 | 0xBB | n/a |
0 | 0xBC | n/a |
0 | 0xBD | n/a |
0 | 0xBE | n/a |
0 | 0xBF | n/a |
0 | 0xC0 | n/a |
0 | 0xC1 | n/a |
0 | 0xC2 | n/a |
0 | 0xC3 | n/a |
0 | 0xC4 | n/a |
0 | 0xC5 | n/a |
0 | 0xC6 | n/a |
0 | 0xC7 | n/a |
0 | 0xC8 | n/a |
0 | 0xC9 | n/a |
0 | 0xCA | n/a |
0 | 0xCB | n/a |
0 | 0xCC | n/a |
0 | 0xCD | n/a |
0 | 0xCE | n/a |
0 | 0xCF | n/a |
0 | 0xD0 | n/a |
0 | 0xD1 | n/a |
0 | 0xD2 | n/a |
0 | 0xD3 | n/a |
0 | 0xD4 | n/a |
0 | 0xD5 | n/a |
0 | 0xD6 | n/a |
0 | 0xD7 | n/a |
0 | 0xD8 | n/a |
0 | 0xD9 | n/a |
0 | 0xDA | n/a |
0 | 0xDB | n/a |
0 | 0xDC | n/a |
0 | 0xDD | n/a |
0 | 0xDE | n/a |
0 | 0xDF | n/a |
0 | 0xE0 | n/a |
0 | 0xE1 | n/a |
0 | 0xE2 | n/a |
0 | 0xE3 | n/a |
0 | 0xE4 | n/a |
0 | 0xE5 | n/a |
0 | 0xE6 | n/a |
0 | 0xE7 | n/a |
0 | 0xE8 | n/a |
0 | 0xE9 | n/a |
0 | 0xEA | n/a |
0 | 0xEB | n/a |
0 | 0xEC | n/a |
0 | 0xED | n/a |
0 | 0xEE | n/a |
0 | 0xEF | n/a |
0 | 0xF0 | n/a |
0 | 0xF1 | n/a |
0 | 0xF2 | n/a |
0 | 0xF3 | n/a |
0 | 0xF4 | n/a |
0 | 0xF5 | n/a |
0 | 0xF6 | n/a |
0 | 0xF7 | n/a |
0 | 0xF8 | n/a |
0 | 0xF9 | n/a |
0 | 0xFA | n/a |
0 | 0xFB | n/a |
0 | 0xFC | n/a |
0 | 0xFD | n/a |
0 | 0xFE | n/a |
0 | 0xFF | n/a |
---+------+------------------+----------------------------------------------------------------------------------------------------
@Sanae6
Copy link

Sanae6 commented Sep 7, 2020

In hindsight, 'Undefined Behaviour' is actually correct!
Not that anybody cares...

I care though 😔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment