Skip to content

Instantly share code, notes, and snippets.

@Jarvix
Created April 8, 2012 11:44
Show Gist options
  • Save Jarvix/2336793 to your computer and use it in GitHub Desktop.
Save Jarvix/2336793 to your computer and use it in GitHub Desktop.
Dear Notch,
I'm writing to you on behalf of #0x10c-std community at Freenode IRC. We have been discussing various ideas for DCPU-16
for a couple of days now and in the process devised much improved DCPU-16 specification. Our rationale for changes is to
keep emulation complexity minimal, yet enable DCPU to be as flexible as possible for people to be able to do really cool
stuff with it.
As you see we also propose very simple interrupts mechanisim. We believe that it is vital for DCPU to become really
general-purpose processor since interrupts allow among many things: flexible timers or preemptive task-switching to
happen. However we kept the complexity minimal so DCPU is capable of only one interrupt handler and no interrupt
queues or priorities. We believe the gains to DCPU capabilites are worth increased emulation cost.
Please reconsider implementing this simple interrupt system. :)
As closing words I'd like you to know that we think you're doing great job with 0x10c!
We never had this much fun with game that isn't even released yet. Keep up the good work!
- The #0x10c-std community.
*** DCPU16 SPECIFICATION CHANGES FOLLOWS ***
====== Changes to opcodes (changes are idented) ======
Values: (6 bits)
0x00-0x07: register (A, B, C, X, Y, Z, I, or J, in that order)
0x08-0xf: [register]
0x10-0x17: [next word + register]
0x18: SP
0x19: [SP]
0x1a: [next word + SP]
0x1b: CR - a control register: 16 control bits, usable for a lot of things like IO.
0x1c: PC
0x1d: O
0x1e: [next word]
0x1f: next word (literal)
0x20-0x3f: literal value 0x00-0x1f (literal)
Non-basic opcodes: (6 bits)
0x00: reserved for future expansion
0x01: JSR a - pushes the address of the next instruction to the stack, then sets PC to a
0x02: PUSH a - effectively the same as SET [--SP],a but one cycle
0x03: POP a - effectively the same as SET a,[SP++] but one cycle
0x04: INT a - in case of an implementation of interrupts, this fires an interrupt with
the given interrupt code. No argument can be passed to the handler. A is an unsigned integer.
0x05-0x3f: reserved
====== Interrupts and control register ======
Control Register: (16 bits)
0: IF - interrupt flag. 1 to turn on interrupts
1-15: Reserved
== Enabling interrupts
To enable interrupts, the address of your handler and the interrupt flag have to be set.
The address of the handler should be put into a -to-be-defined-location-.
The program will do something along the lines:
SET [0xFFFE], myHandler ; set the address of the handler into the predefined location (0xFFFE is an example)
XOR CR, 1 ; enable the interrupt flag
== An interrupt occurs
The virtual machine received an interrupt (or creates one).
The VM will do the following:
1. Verify the Interrupt Flag is 1 by AND-ing CR with 1 and comparing.
If it is 0, skip interrupt handling
If it is 1, set it to 0 and continue interrupt handling
2. It reads the handler address from the predefined location in memory
3. If the address equals 0xFFFF, handling the interrupts is skipped
5. Pushes the PC onto the stack
6. Pushes the argument onto the stack
7. Pushes the interrupt number onto the stack
8. It calls the handler with SET PC,handler
The handler performs the action and returns directly to the interrupted code
The INT opcode does the same as a hardware interrupt. argument 2 is 0, argument 1 is the interrupt code.
=== Example that would be possible with this system
; Code by Jarvix
;There was an interrupt by the timer!
;;;VM
; check the CR IF
; This is how the stack looks
PUSH PC ; is current PC
PUSH 0 ; timer has no argument
PUSH 1 ; timer is interrupt 1
; vm does the lookup job
; jumps to the handler
;;;HANDLER
:interruptHandler
; arg is in [SP]
; arg2 is in [SP+1]
; PC is in [SP+2]
; Save all registers
PUSH O
PUSH A
PUSH B
PUSH C
PUSH X
PUSH Y
PUSH I
PUSH J
; Get new stack address somehow
; Each program has its own stack.
; Switching the stack pointer continues running
; the next program
; Set new stack address
SET SP, newStack
; We now are on the new stack of another task,
; that also pushed their registers
POP J
POP I
POP Y
POP X
POP C
POP B
POP A
POP O
; We restore the program
; Remove the interrupt info without clobbering
SUB SP,2
; Turn on interrupts
OR CR, 1
; in notch-code this is SET PC,POP
POP PC
; We now run not in the VM but the actual code again, skipping thus the VM.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment