-
-
Save 0xabad1dea/2313564 to your computer and use it in GitHub Desktop.
0x10c Programming Notes
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
On April 5 2012, #0x10c-dev agreed to the following standard ABI: | |
- Registers A, B, C are clobberable across calls | |
- Registers I, J, X, Y, Z are preserved across calls | |
- Return in A | |
- J is used for base stack pointer (preserving the value of SP before allocating | |
data for locals) | |
- Function local variables are kept on the stack | |
- Caller cleans stack | |
- First three arguments to A, B, C, remaining arguments pushed right-to-left onto | |
the stack | |
-------------------------------------------------------------------------------- | |
For example: myfunc(foo,bar,baz,flee,fuzz) A = foo, B = bar, C = baz, top of | |
stack = flee, next on stack = fuzz | |
- Varargs: follow normal rules, except the entire "..." must go on the stack | |
even if it's one of the first three arguments | |
- No stupid tricks with the overflow flag | |
EXAMPLE FUNCTION CALL: | |
# func(1, 2, 3, 4, 5); | |
# first 3 arguments are passed via registers | |
SET A, 1 | |
SET B, 2 | |
SET C, 3 | |
# 4 and 5 are pushed to stack in reverse order | |
SET PUSH, 5 | |
SET PUSH, 4 | |
JSR func | |
ADD SP, 2 # callers cleans up the stack (two passed words) | |
EXAMPLE FUNCTION PROLOGUE/EPILOGUE: | |
# Prologue: | |
SET PUSH, J | |
SET J, SP | |
SUB SP, 5 # Reserve 5 words for function locals | |
# Function body: | |
SET A, [J-1] # Access first local variable | |
SET B, [J+1] # Access 3rd function argument | |
SET C, [J+2] # Access 4th function argument | |
# etc ... | |
# Epilogue: | |
SET A, return_value | |
SET SP, J | |
SET J, POP | |
SET PC, POP # return | |
Last updated for DCPU16v11 | |
example by masterm |
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
String type suggestions | |
pstring (Pascal-style): | |
string[0] is length in words | |
string[1..n] is characters | |
cstring (C-style): | |
string[0..n-1] is characters | |
string[n] is 0x0000 | |
pbyte: | |
string[0] is length in bytes | |
string[1..n] is two packed bytes per word - high is the even byte (bytes 0, 2, | |
4, 6...), low is the odd (1, 3, 7...) | |
ASCII data should be stored in a pstring or cstring and graphical color data may | |
be stored separately in a pbyte and merged through a library routine. There | |
should also be a routine to zero out the high bytes in a pstring/cstring to | |
remove the color data. | |
A char in C is a word, not a byte. The cstring as defined above is what the | |
standard C library uses. | |
Suggestion: | |
A pstring may be allocated immediately followed with a single word set to 0x0000 | |
after it, and hence may be used as a cstring simply by moving the pointer forward | |
one. Such a dual-purpose string should not contain embedded nulls. |
Hopefully notch will revise the spec, though, and add a [next word + SP] value code, so we can avoid the "J" overhead.
Because of the 16-bit arithmetics, [J-1] is equivalent to [J+0xFFFF]. SET A, [J-1] is therefore assembled as 5C01 FFFF.
True, but notch hasn't confirmed (as far as I know) the behavior for memory address overflow. Truncating seems likely, though.
Losing the extra bits is the default behaviour, the way almost all two's complement machines have handled this kind of situation. Weird tricks like PC's A20 gate are the exception, and if any applied, it would be explicitly stated.
Besides, consider the construct of [J+(-1)].
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just subtract the local stack size from J at the beginning, and add it back before resetting SP. So the function implementation becomes:
Prologue:
SET PUSH, J
SET J, SP
SUB J, 5 # Reserve 5 words for function locals
SET SP, J
Function body:
SET A, [J+4] # Access first local variable
SET A, [J+3] # Access second local variable
SET A, [J+2] # Access third local variable
SET A, [J+1] # Access fourth local variable
SET A, [J+0] # Access fifth local variable
J+5 is the original, saved J
SET B, [J+6] # Access 3rd function argument
SET C, [J+7] # Access 4th function argument
etc ...
Epilogue:
SET A, return_value
ADD J, 5 # account for local variables
SET SP, J
SET J, POP
SET PC, POP # return