Skip to content

Instantly share code, notes, and snippets.

@Longor1996
Last active September 7, 2020 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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 |
---+------+------------------+----------------------------------------------------------------------------------------------------
@tomgalvin594
Copy link

On line 20, do you mean "undefined behaviour" instead of "unexpected behavior"?

@Longor1996
Copy link
Author

No. It is "unexpected behavior".

If you plug-out a hardware component, anything could happen, but most of the time nothing will happen at all, and the component will simply be gone, the port won't react to interrupts anymore, and some more 'random' things.

@Longor1996
Copy link
Author

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

@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