-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding the newest version of the DCPU-16 specification by Notch
- Loading branch information
1 parent
f009f75
commit 61348f2
Showing
1 changed file
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,195 @@ | |||
DCPU-16 Specification | |||
Copyright 1985 Mojang | |||
Version 1.1 | |||
|
|||
|
|||
|
|||
=== SUMMARY ==================================================================== | |||
|
|||
* 16 bit words | |||
* 0x10000 words of ram | |||
* 8 registers (A, B, C, X, Y, Z, I, J) | |||
* program counter (PC) | |||
* stack pointer (SP) | |||
* extra/excess (EX) | |||
* interrupt address (IA) | |||
|
|||
In this document, anything within [brackets] is shorthand for "the value of the | |||
RAM at the location of the value inside the brackets". For example, SP means | |||
stack pointer, but [SP] means the value of the RAM at the location the stack | |||
pointer is pointing at. | |||
|
|||
Whenever the CPU needs to read a word, it reads [PC], then increases PC by one. | |||
Shorthand for this is [PC++]. In some cases, the CPU will modify a value before | |||
reading it, in this case the shorthand is [++PC]. | |||
|
|||
For stability and to reduce bugs, it's strongly suggested all multi-byte | |||
operations use little endian in all DCPU-16 programs, wherever possible. | |||
|
|||
|
|||
|
|||
=== INSTRUCTIONS =============================================================== | |||
|
|||
Instructions are 1-3 words long and are fully defined by the first word. | |||
In a basic instruction, the lower five bits of the first word of the instruction | |||
are the opcode, and the remaining eleven bits are split into a five bit value b | |||
and a six bit value a. | |||
b is always handled by the processor after a, and is the lower five bits. | |||
In bits (in LSB-0 format), a basic instruction has the format: aaaaaabbbbbooooo | |||
|
|||
In the tables below, C is the time required in cycles to look up the value, or | |||
perform the opcode, VALUE is the numerical value, NAME is the mnemonic, and | |||
DESCRIPTION is a short text that describes the opcode or value. | |||
|
|||
|
|||
|
|||
--- Values: (5/6 bits) --------------------------------------------------------- | |||
C | VALUE | DESCRIPTION | |||
---+-----------+---------------------------------------------------------------- | |||
0 | 0x00-0x07 | register (A, B, C, X, Y, Z, I or J, in that order) | |||
0 | 0x08-0x0f | [register] | |||
1 | 0x10-0x17 | [register + next word] | |||
0 | 0x18 | (PUSH / [--SP]) if in b, or (POP / [SP++]) if in a | |||
0 | 0x19 | [SP] / PEEK | |||
0 | 0x1a | [SP + next word] / PICK n | |||
0 | 0x1b | SP | |||
0 | 0x1c | PC | |||
0 | 0x1d | EX | |||
1 | 0x1e | [next word] | |||
1 | 0x1f | next word (literal) | |||
0 | 0x20-0x3f | literal value 0xffff-0x1e (-1..30) (literal) (only for a) | |||
--+-----------+---------------------------------------------------------------- | |||
|
|||
* "next word" means "[PC++]". Increases the word length of the instruction by 1. | |||
* By using 0x18, 0x19, 0x1a as PEEK, POP/PUSH, and PICK there's a reverse stack | |||
starting at memory location 0xffff. Example: "SET PUSH, 10", "SET X, POP" | |||
|
|||
|
|||
|
|||
--- Basic opcodes (5 bits) ---------------------------------------------------- | |||
C | VAL | NAME | DESCRIPTION | |||
---+------+----------+-------------------------------------------------------- | |||
- | 0x00 | n/a | special instruction - see below | |||
1 | 0x01 | SET b, a | sets b to a | |||
2 | 0x02 | ADD b, a | sets b to b+a, sets EX to 0x0001 if there's an overflow, | |||
| | | 0x0 otherwise | |||
2 | 0x03 | SUB b, a | sets b to b-a, sets EX to 0xffff if there's an underflow, | |||
| | | 0x0 otherwise | |||
2 | 0x04 | MUL b, a | sets b to b*a, sets EX to ((b*a)>>16)&0xffff (treats b, | |||
| | | a as unsigned) | |||
2 | 0x05 | MLI b, a | like MUL, but treat b, a as signed | |||
3 | 0x06 | DIV b, a | sets b to b/a, sets EX to ((b<<16)/a)&0xffff. if a==0, | |||
| | | sets b and EX to 0 instead. (treats b, a as unsigned) | |||
3 | 0x07 | DVI b, a | like DIV, but treat b, a as signed | |||
3 | 0x08 | MOD b, a | sets b to b%a. if a==0, sets b to 0 instead. | |||
1 | 0x09 | AND b, a | sets b to b&a | |||
1 | 0x0a | BOR b, a | sets b to b|a | |||
1 | 0x0b | XOR b, a | sets b to b^a | |||
2 | 0x0c | SHR b, a | sets b to b>>>a, sets EX to ((b<<16)>>a)&0xffff | |||
| | | (logical shift) | |||
2 | 0x0d | ASR b, a | sets b to b>>a, sets EX to ((b<<16)>>>a)&0xffff | |||
| | | (arithmetic shift) (treats b as signed) | |||
2 | 0x0e | SHL b, a | sets b to b<<a, sets EX to ((b<<a)>>16)&0xffff | |||
- | 0x0f | - | | |||
2+| 0x10 | IFB b, a | performs next instruction only if (b&a)!=0 | |||
2+| 0x11 | IFC b, a | performs next instruction only if (b&a)==0 | |||
2+| 0x12 | IFE b, a | performs next instruction only if b==a | |||
2+| 0x13 | IFN b, a | performs next instruction only if b!=a | |||
2+| 0x14 | IFG b, a | performs next instruction only if b>a | |||
2+| 0x15 | IFA b, a | performs next instruction only if b>a (signed) | |||
2+| 0x16 | IFL b, a | performs next instruction only if b<a | |||
2+| 0x17 | IFU b, a | performs next instruction only if b<a (signed) | |||
- | 0x18 | - | | |||
- | 0x19 | - | | |||
- | 0x1a | - | | |||
- | 0x1b | - | | |||
- | 0x1c | - | | |||
- | 0x1d | - | | |||
- | 0x1e | - | | |||
- | 0x1f | - | | |||
---+------+----------+---------------------------------------------------------- | |||
|
|||
* The branching opcodes take one cycle longer to perform if the test fails | |||
* Signed numbers are represented using two's complement. | |||
|
|||
|
|||
|
|||
Special opcodes always have their lower five bits unset, have one value and a | |||
five bit opcode. In binary, they have the format: aaaaaaooooo00000 | |||
The value (a) is in the same six bit format as defined earlier. | |||
|
|||
--- Special opcodes: (6 bits) -------------------------------------------------- | |||
C | VAL | NAME | DESCRIPTION | |||
---+------+-------+------------------------------------------------------------- | |||
- | 0x00 | n/a | reserved for future expansion | |||
3 | 0x01 | JSR a | pushes the address of the next instruction to the stack, | |||
| | | then sets PC to a | |||
- | 0x02 | - | | |||
- | 0x03 | - | | |||
- | 0x04 | - | | |||
- | 0x05 | - | | |||
- | 0x06 | - | | |||
- | 0x07 | - | | |||
4 | 0x08 | INT a | triggers a software interrupt with message a | |||
1 | 0x09 | ING a | sets a to IN | |||
1 | 0x0a | INS a | sets IN to a | |||
- | 0x0b | - | | |||
- | 0x0c | - | | |||
- | 0x0d | - | | |||
- | 0x0e | - | | |||
- | 0x0f | - | | |||
2 | 0x10 | HWN a | sets a to number of connected hardware devices | |||
4 | 0x11 | HWQ a | sets A, B, C, X, Y registers to information about hardware a | |||
| | | a+b is a 32 bit word identifying the hardware type | |||
| | | c is the hardware revision | |||
| | | x+y is a 32 bit word identifying the manufacturer | |||
4+| 0x12 | HWI a | sends an interrupt to hardware a | |||
- | 0x13 | - | | |||
- | 0x14 | - | | |||
- | 0x15 | - | | |||
- | 0x16 | - | | |||
- | 0x17 | - | | |||
- | 0x18 | - | | |||
- | 0x19 | - | | |||
- | 0x1a | - | | |||
- | 0x1b | - | | |||
- | 0x1c | - | | |||
- | 0x1d | - | | |||
- | 0x1e | - | | |||
- | 0x1f | - | | |||
---+------+-------+------------------------------------------------------------- | |||
|
|||
|
|||
|
|||
=== INTERRUPTS ================================================================= | |||
|
|||
When IA is set to something other than 0, interrupts triggered on the DCPU-16 | |||
will push PC to the stack, followed by pushing A to the stack, then set the PC | |||
to IA, and A to the interrupt message. A well formed interrupt handler must pop | |||
A from the stack before returning (popping PC from the stack) | |||
|
|||
If IA is set to 0, a triggered interrupt does nothing. | |||
|
|||
The DCPU-16 will attempt to perform one clock interrupt 60 times per second, | |||
with the A message being 0. | |||
|
|||
|
|||
|
|||
=== HARDWARE =================================================================== | |||
|
|||
The DCPU-16 supports up to 65536 connected hardware devices. These devices can | |||
be anything from additional storage, sensors, monitors or speakers. | |||
How to control the hardware is specified per hardware device, but the DCPU-16 | |||
supports a standard enumeration method for detecting connected hardware via | |||
the HWN, HWQ and HWI instructions. | |||
|
|||
Interrupts sent to hardware can't contain messages, can take additional cycles, | |||
and can read or modify any registers or memory adresses on the DCPU-16. This | |||
behavior changes per hardware device and is documented in the hardware | |||
documentation. | |||
|
|||
Hardware must NOT start modifying registers or ram on the DCPU-16 before at | |||
least one HWI call has been made to the hardware. | |||
|
|||
The DPCU-16 does not support hot swapping hardware. The behavior of connecting | |||
or disconnecting hardware while the DCPU-16 is undefined. |