-
-
Save rlane/2338617 to your computer and use it in GitHub Desktop.
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
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. 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 | |
0x05-0x3f: reserved | |
====== Interrupts and control register ====== | |
Pending interrupt flag (invisible to user code): Initially 0. | |
Control Register: (16 bits) | |
0: IF - interrupt flag. 1 to turn on interrupts. Initially 0. | |
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 | |
If the pending interrupt flag is set then enabling interrupts will immediately fire an interrupt. | |
== An interrupt occurs | |
When virtual machine receives an interrupt 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, set the pending interrupt flag and skip interrupt handling. | |
If it is 1, set it to 0 and continue interrupt handling | |
2. Clear the pending interrupt flag. | |
3. It reads the handler address from the predefined location in memory | |
4. Pushes the PC onto the stack | |
5. It calls the handler with SET PC, handler | |
The handler performs the action and returns directly to the interrupted code. The handler should set the Interrupt Flag to 1 before returning. | |
=== 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 | |
; vm does the lookup job | |
; jumps to the handler | |
;;;HANDLER | |
:interruptHandler | |
; PC is in [SP] | |
; 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 | |
; 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