cpuver = 6
\ | 0x Flow | 1x Memory | 2x Math | 3x Logic |
---|---|---|---|---|
x0 | halt | lit:val | add:n a b | eq:bool a b |
x1 | sleep ms | get:val index | sub:n a b | lt:bool a b |
x2 | vsync | stackptr:negadr | mult:n a b | gt:bool a b |
x3 | load:val adr | div:n a b | eqz:bool a | |
x4 | jump adr | load8u:val adr | rem:n a b | and:n a b |
x5 | jumpifz adr val | setread adr chsize | load8s:val adr | or:n a b |
x6 | skipread chunks | load16s:val adr | xor:n a b | |
x7 | endcall | read:val | itof:float int | rot:n a b |
x8 | call:result adr params | drop val | fadd:n a b | feq:bool a b |
x9 | return result | set index val | fsub:n a b | flt:bool a b |
xA | exec:err adr params | inc index delta | fmult:n a b | fgt:bool a b |
xB | break | store adr val | fdiv:n a b | |
xC | reset | store8 adr val | ffloor:n a | |
xD | absadr:absadr adr | setwrite adr chsize | ||
xE | cpuver:ver | skipwrite chunks | store16 adr val | |
xF | noop | write val | ftoi:int float |
- All instructions are 1 byte, except for literals (read below)
- Instruction parameters are popped in specified order and thus must be pushed in reverse order
- All values are stored as little endian
Specific values are pushed onto the stack using literals. Smaller numbers can be compressed into fewer bytes as described in the following table.
Type | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
---|---|---|---|---|---|
32bit lit eral |
0001 0000 | bbbb aaaa | dddd cccc | ffff eeee | hhhh gggg |
4bit positive relative | 0100 aaaa | ||||
4bit positive absolute | 0101 aaaa | ||||
4bit negative relative | 0110 aaaa | ||||
4bit negative absolute | 0111 aaaa | ||||
12bit positive relative | 1000 aaaa | cccc bbbb | |||
12bit positive absolute | 1001 aaaa | cccc bbbb | |||
12bit negative relative | 1010 aaaa | cccc bbbb | |||
12bit negative absolute | 1011 aaaa | cccc bbbb | |||
20bit positive relative | 1100 aaaa | cccc bbbb | eeee dddd | ||
20bit positive absolute | 1101 aaaa | cccc bbbb | eeee dddd | ||
20bit negative relative | 1110 aaaa | cccc bbbb | eeee dddd | ||
20bit negative absolute | 1111 aaaa | cccc bbbb | eeee dddd |
aaaa
= least significant nibblehhhh
= most significant nibblepositive
= rest of nibbles are0000
negative
= rest of nibbles are1111
absolute
= second most significant bit (2^30) is flipped (for absolute addresses from either beginning(+) or end(-) of memory)
Each instruction will pop the required number of parameters off of the stack.
Some will push a result (prefixed in the documentation with a :
) back onto the stack.
adr
parameters can be given as either a relative or absolute address as described above.
Relative addresses are relative to the end of the instruction byte that operates on that address.
Pause the cpu indefinitely (and open a debugger?).
Pause the cpu for ms
milliseconds.
Pause the cpu until next screen refresh.
Jump to adr
.
Jump to adr
if val
is zero.
Clear the current stack and jump back to where the current function was called from. If this brings us back to the safe state (if one is stored), the safe state will be cleared.
Start a new stack, move paramcount
values over to the new stack in reverse order and jump to adr
.
(Note that a result
might not be returned.)
Like endcall
, but push result
onto the previous stack.
Like call
, but store the current stack and program counter as a safe state to return to, if a break
is invoked by a program or user interrupt.
Useful for running untrusted programs.
If there was already a safe state stored, this will just behave like a call
.
If a safe state is stored, this will return
-1
to the safe state and clear it.
If no safe state is stored, this will act as a reset
.
Clear all stacks and safe state and set the program counter to the 32bit address stored at 8 bytes before end of memory.
Return adr
as a positive absolute address.
Return the version number of the current cpu isa.
Waste one cpu cycle doing nothing.
Return and jump the next 4 bytes.
Return the value at the given index
of the current stack.
Positive index
counts from the top of the stack.
Negative index
counts from the bottom of the stack, useful for accessing function parameters and local variables.
Return the negative absolute address of the stack pointer.
Load a 32bit value from adr
and return it.
Load a 8bit value from adr
and return it as an unsigned integer.
Prepare reading chunks of chsize
bits, starting from adr
.
Skip reading the next chunk
number of chunks.
Read the next chunk of bits and return it as a unsigned integer.
Do nothing with val
.
Like get
, but overwrites the value in the stack with val
without returning it.
Like set
, but increments the integer in stack by delta
.
Store a 32bit val
at adr
.
Store a 8bit val
at adr
.
Prepare writing chunks of chsize
bits, starting from adr
.
Skip writing the next chunk
number of chunks.
Write val
as the next chunk of bits.
Return the result of adding a
and b
.
Return the result of subtracting b
from a
.
Return the result of multiplying a
and b
.
Return the result of integer dividing a
by b
.
Return the remainder of integer dividing a
by b
.
Return int
as a floating point number.
Like add
, but for floating point numbers.
Like sub
, but for floating point numbers.
Like mult
, but for floating point numbers.
Like div
, but for floating point numbers. (and doing actual division, not integer division.)
Return the largest integer (as a float) that is not larger than a
.
Return float
as an integer.
Return 1 if a
is equal to b
, else return 0.
Return 1 if a
is less than b
, else return 0.
Return 1 if a
is greater than b
, else return 0.
Return 1 if a
is zero, else return 0.
Return the result of bitwise and
ing a
and b
.
Return the result of bitwise or
ing a
and b
.
Return the result of bitwise xor
ing a
and b
.
Return the result of rotating a
b
bits to the left.
Like eq
, but for floating point numbers.
Like lt
, but for floating point numbers.
Like gt
, but for floating point numbers.