Added printf and stackrotate functions to VVS stdlib.
[vvhitespace] / stdlib / heap.pvvs
#ifndef VVS_STDLIB_HEAP
#define VVS_STDLIB_HEAP
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ memset (11000)
@ Description:
@ Writes 'pattern' in memory locations 'startaddr' to 'startaddr+count'.
@ Call Stack:
@ pattern
@ startaddr
@ count <-- TOS
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTSSSN | Mark: 11000 (memset)
SSSTTN | PUSH 3
NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Store 'pattern' into one memory location on each pass through this loop.
NSSVSSSTTSSSSSSSSSSSN | Mark: 00011000 00000000
SSSTN | PUSH 1 (ptr)
TTT | LOAD
SSSTSN | PUSH 2 (ptr)
TTT | LOAD
TSSS | ADD
SSSTTN | PUSH 3 (ptr)
TTT | LOAD
TTS | STORE
@ Decrement and check for loop end condition 'count == 0'.
SSSTN | PUSH 1 (ptr)
TTT | LOAD
SNS | DUP
NTSSSSTTSSSSSSSSSSTN | BRZ > 00011000 00000001
SSSTN | PUSH 1
TSST | SUBTRACT
SSSTN | PUSH 1 (ptr)
SNT | SWAP
TTS | STORE
NSNSSSTTSSSSSSSSSSSN | JMP > 00011000 00000000
@ Clean up and return
NSSVSSSTTSSSSSSSSSSTN | Mark: 00011000 00000001
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ memcpy (11001)
@ Description:
@ Copies 'count+1' words from 'source' to 'destination'.
@ Call Stack:
@ source
@ destination
@ count <-- TOS
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTSSTN | Mark: 11001 (memcpy)
SSSTTN | PUSH 3
NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Copy one word on each pass through this loop.
NSSVSSSTTSSTSSSSSSSSN | Mark: 00011001 00000000
SSSTSN | PUSH 2 (ptr)
TTT | LOAD
SSSTN | PUSH 1 (ptr)
TTT | LOAD
TSSS | ADD
SSSTTN | PUSH 3 (ptr)
TTT | LOAD
SSSTN | PUSH 1 (ptr)
TTT | LOAD
TSSS | ADD
TTT | LOAD
TTS | STORE
@ Decrement and check for loop end conditions.
SSSTN | PUSH 1 (ptr)
TTT | LOAD
SNS | DUP
NTSSSSTTSSTSSSSSSSTN | BRZ > 00011001 00000001
SSSTN | PUSH 1
TSST | SUBTRACT
SSSTN | PUSH 1 (ptr)
SNT | SWAP
TTS | STORE
NSNSSSTTSSTSSSSSSSSN | JMP > 00011001 00000000
@ Clean up and return
NSSVSSSTTSSTSSSSSSSTN | Mark: 00011001 00000001
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ memrand (11010)
@ Description:
@ Writes random words into memory locations 'startaddr' to 'startaddr+count'.
@ Call Stack:
@ count
@ startaddr <-- TOS
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#include <math.pvvs>
NSSVTTSTSN | Mark: 11010 (memrand)
SSSTN | PUSH 1
NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Store random word into one memory location on each pass through this loop.
NSSVSSSTTSTSSSSSSSSSN | Mark: 00011010 00000000
SNS | DUP
SSSTN | PUSH 1 (ptr)
TTT | LOAD
TSSS | ADD
NSTTSSSSN | JSR > 10000 (random)
TTS | STORE
@ Decrement and check loop end conditions
SNS | DUP
NTSSSSTTSTSSSSSSSSTN | BRZ > 00011010 00000001
SSSTN | PUSH 1
TSST | SUBTRACT
NSNSSSTTSTSSSSSSSSSN | JMP > 00011010 00000000
@ Clean up and return
NSSVSSSTTSTSSSSSSSSTN | Mark: 00011010 00000001
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ memcmp (11011)
@ Description:
@ Compares two blocks of memory:
@ blk1ptr -> blk1ptr+count
@ -- versus --
@ blk2ptr -> blk2ptr+count
@ The return value is zero if the blocks are identical, otherwise non-zero.
@ Call Stack:
@ count
@ blk1ptr
@ blk2ptr <-- TOS
@ Return Stack:
@ retvalue <-- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTSTTN | Mark: 11011 (memcmp)
SSSTSN | PUSH 2
NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Compare one word on each pass through this loop.
NSSVSSSTTSTTSSSSSSSSN | Mark: 00011011 00000000
SNS | DUP
SNS | DUP
SSSTN | PUSH 1 (ptr)
TTT | LOAD
TSSS | ADD
TTT | LOAD
SNT | SWAP
SSTSN | PUSH 2 (ptr)
TTT | LOAD
TSSS | ADD
TTT | LOAD
TSST | SUBTRACT
NTSSSSTTSTTSSSSSSTSN | BRZ > 00011011 00000010 (jump if words match)
@ Return 'match? = false'
SNN | DROP
SSSTN | PUSH 1
NTN | RTS
@ Decrement and loop again if loop is not complete.
NSSVSSSTTSTTSSSSSSTSN | Mark: 00011011 00000010
SNS | DUP
NTSSSSTTSTTSSSSSSSTN | BRZ > 00011011 00000001 (jump if loop is complete)
SSSTN | PUSH 1
TSST | SUBTRACT
NSNSSSTTSTTSSSSSSSSN | JMP > 00011011 00000000
@ Return 'match? = true'
NSSVSSSTTSTTSSSSSSSTN | Mark: 00011011 00000001
SNN | DROP
SSSSN | PUSH 0
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ memsrch (11100)
@ Description:
@ Searches the heap from 'address' to 'address+count'.
@ If 'pattern' is found, the return value is a pointer to the matching word.
@ If not found, the return value is a null pointer.
@ Call Stack:
@ pattern
@ count
@ address <-- TOS
@ Return Stack:
@ pointer <-- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTTSSN | Mark: 11100 (memsrch)
SSSTTN | PUSH 3
NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Compare one word on each pass through this loop.
NSSVSSSTTTSSSSSSSSSSN | Mark: 00011100 00000000
SNS | DUP
SSSTN | PUSH 1 (ptr)
TTT | LOAD
TSSS | ADD
TTT | LOAD
SSSTTN | PUSH 3 (ptr)
TTT | LOAD
TSST | SUBTRACT
NTSSSSTTTSSSSSSSSSTN | BRZ > 00011100 00000001
SNS | DUP
SSSTSN | PUSH 2 (ptr)
TTT | LOAD
TSST | SUBTRACT
NTSSSSTTTSSSSSSSSTSN | BRZ > 00011100 00000010
SSSTN | PUSH 1
TSSS | ADD
NSNSSSTTTSSSSSSSSSSN | JMP > 00011100 00000000
@ Found a match. Clean up and return.
NSSVSSSTTTSSSSSSSSSTN | Mark: 00011100 00000001
SSSTN | PUSH 1 (ptr)
TTT | LOAD
TSSS | ADD
NTN | RTS
@ No match found. Clean up and return.
NSSVSSSTTTSSSSSSSSTSN | Mark: 00011100 00000010
SNN | DROP
SSSSN | PUSH 0
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ slurpreg (1000000)
@ Description:
@ Reads 'count' values from heap to stack in complementary order to 'spewreg'.
@ Call Stack:
@ count
@ Return Stack:
@ heap[count]
@ ...
@ heap[2]
@ heap[1] <-- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSSSSSSN | Mark: 1000000 (slurpreg)
@ Load one word from heap on each pass.
NSSVSTSSSSSSSSSSSSSSN | Mark: 01000000 00000000
SNS | DUP
TTT | LOAD
SNT | SWAP
@ Check for loop completion.
@ As a side effect, prepare the next address.
SSSTN | PUSH 1
TSST | SUBTRACT
SNS | DUP
NTSSTSSSSSSSSSSSSSTN | BRZ > 01000000 00000001
NSNSTSSSSSSSSSSSSSSN | JMP > 01000000 00000000
NSSVSTSSSSSSSSSSSSSTN | Mark: 01000000 00000001
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ spewreg (1000001)
@ Description:
@ Writes 'count' values from stack to heap in this order:
@ TOS -> heap[1]
@ TOS+1 -> heap[2]
@ ...
@ TOS+n -> heap[count]
@ This function uses heap[15] for temporary storage, thus limiting the total
@ registers to 14 since heap[0] is reserved. Since this function populates
@ the registers, encoding the value here seems a natural location to document
@ the limit. TODO: Should this be turned into a CPP define?
@ Call Stack:
@ data-words
@ ...
@ data-words
@ count <-- TOS
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSSSSSTN | Mark: 1000001 (spewreg)
@ To simplify other functions, sprewreg shall accept 0 as a valid count value.
SNS | DUP
NTSSTSSSSSTSSSSSSSTN | BRZ > 01000001 00000001
@ Create a counter in heap[15] that doubles as a destination pointer generator.
SSSTTTTN | PUSH 15 (ptr)
SSSTN | PUSH 1
TTS | STORE
@ Store one word to heap on each pass.
NSSVSTSSSSSTSSSSSSSSN | Mark: 01000001 00000000
SNT | SWAP
SSSTTTTN | PUSH 15 (ptr)
TTT | LOAD
SNT | SWAP
TTS | STORE
@ Check for loop completion.
SNS | DUP
SSSTTTTN | PUSH 15 (ptr)
TTT | LOAD
TSST | SUBTRACT
NTSSTSSSSSTSSSSSSSTN | BRZ > 01000001 00000001
@ Increment heap[15] if continuing.
SSSTTTTN | PUSH 15 (ptr)
SNS | DUP
TTT | LOAD
SSSTN | PUSH 1
TSSS | ADD
TTS | STORE
NSNSTSSSSSTSSSSSSSSN | JMP > 01000001 00000000
@ Clean up and return.
NSSVSTSSSSSTSSSSSSSTN | Mark: 01000001 00000001
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ slurp (11110)
@ Description:
@ Reads values from heap to stack in complementary order to 'spew'.
@ Call Stack:
@ address
@ count <-- TOS
@ Return Stack:
@ heap[address+count]
@ ...
@ heap[address+1]
@ heap[address] <-- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTTTSN | Mark: 11110 (slurp)
@ Load one word from heap on each pass.
SNS | DUP
SSSTTN | PUSH 3
NSTTSTSN | JSR > 1010 (stackrotate)
SNT | SWAP
SNS | DUP
SSSTTN | PUSH 3
NSTTSTSN | JSR > 1010 (stackrotate)
TSSS | ADD
TTT | LOAD
SSSTTN | PUSH 3
NSTTSTSN | JSR > 1010 (stackrotate)
SNT | SWAP
@ Check for loop completion.
SNS | DUP
NTSSSSTTTTSSSSSSSSSN | BRZ > 00011110 00000000
SSSTN | PUSH 1
TSST | SUBTRACT
NSNTTTTSN | JMP > 11110 (slurp)
@ Clean up and return.
NSSVSSSTTTTSSSSSSSSSN | Mark: 00011110 00000000
SNN | DROP
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ spew (11111)
@ Description:
@ Writes values from stack to heap in this order:
@ TOS -> heap[address]
@ TOS+1 -> heap[address+1]
@ ...
@ TOS+n -> heap[address+count]
@ Call Stack:
@ data-words
@ ...
@ data-words
@ address
@ count <-- TOS
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTTTTN | Mark: 11111 (spew)
SSSTSN | PUSH 2
NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Create a counter in heap[3] that doubles as a dest. pointer offset generator.
SSSTTN | PUSH 3 (ptr)
SSSSN | PUSH 0
TTS | STORE
@ Store one word to heap on each pass.
NSSVSSSTTTTTSSSSSSSSN | Mark: 00011111 00000000
SSSTSN | PUSH 2 (ptr)
TTT | LOAD
SSSTTN | PUSH 3 (ptr)
TTT | LOAD
TSSS | ADD
SNT | SWAP
TTS | STORE
@ Check for loop completion.
SSSTN | PUSH 1 (ptr)
TTT | LOAD
SSSTTN | PUSH 3 (ptr)
TTT | LOAD
TSST | SUBTRACT
NTSSSSTTTTTSSSSSSSTN | BRZ > 00011111 00000001
@ Increment heap[3] if continuing.
SSSTTN | PUSH 3 (ptr)
SNS | DUP
TTT | LOAD
SSSTN | PUSH 1
TSSS | ADD
TTS | STORE
NSNSSSTTTTTSSSSSSSSN | JMP > 00011111 00000000
@ Clean up and return.
NSSVSSSTTTTTSSSSSSSTN | Mark: 00011111 00000001
NTN | RTS
#endif