Skip to content

Instantly share code, notes, and snippets.

@0xabad1dea
Created April 5, 2012 19:50
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save 0xabad1dea/2313564 to your computer and use it in GitHub Desktop.
Save 0xabad1dea/2313564 to your computer and use it in GitHub Desktop.
0x10c Programming Notes
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
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.
@judofyr
Copy link

judofyr commented Apr 6, 2012

SET A, [J-1] # Access first local variable

All numbers in DCPU-16 are unsigned; how is this possible?

@jabr
Copy link

jabr commented Apr 6, 2012

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

@jabr
Copy link

jabr commented Apr 6, 2012

Hopefully notch will revise the spec, though, and add a [next word + SP] value code, so we can avoid the "J" overhead.

@digwuren
Copy link

digwuren commented Apr 8, 2012

Because of the 16-bit arithmetics, [J-1] is equivalent to [J+0xFFFF]. SET A, [J-1] is therefore assembled as 5C01 FFFF.

@jabr
Copy link

jabr commented Apr 8, 2012

True, but notch hasn't confirmed (as far as I know) the behavior for memory address overflow. Truncating seems likely, though.

@digwuren
Copy link

digwuren commented Apr 8, 2012

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