11101 ----- <empty>
11110 ----- slurp (heap.pvvs)
11111 ----- spew (heap.pvvs)
- 100xxx - unassigned
+ 100xxx - string functions
+ 100000 ----- strlen (string.pvvs)
101xxx - unassigned
110xxx - conversion functions
111xxx - debug functions
111000 ----- dump heap (debug.pvvs)
+ 111001 ----- dump stack (debug.pvvs)
1xxxxxx - reserved for less common entry points
- 1000000 ----- print sign of number (stdio.pvvs)
- 1000001 ----- print magnitude of number (stdio.pvvs)
+ 1000000 ----- slurp registers (heap.pvvs)
+ 1000001 ----- spew registers (heap.pvvs)
+ 1000010 ----- print sign of number (stdio.pvvs)
+ 1000011 ----- print magnitude of number (stdio.pvvs)
# Misc #
The stdlib uses heap[1] to heap[15] as registers.
-The `slurp` and `spew` functions facilitate this by `spew`ing the stack onto
-the heap's pseudo-registers or `slurp`ing the pseudo-registers back to the
+The `slurpreg` and `spewreg` functions facilitate this by `spew`ing the stack
+onto the heap's pseudo-registers or `slurp`ing the pseudo-registers back to the
stack. The functions preserve order in complementary fashion.
-The `spew` function uses `heap[0]` for storage.
+The `spewreg` function uses `heap[0]` for storage.
SNT | SWAP
@ Print output line for this memory location
-NSTTSSSSSTN | JSR>1000001 (print absolute value of number)
+NSTTSSSSTTN | JSR>1000011 (print absolute value of number)
SSSTTTSTSN | PUSH ASCII ':'
SSSTSSTN | PUSH ASCII '\t'
TNSS | PUTC
SNN | DROP
NTN | RTS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@ dumpstack (111001)
+@ Description:
+@ Dumps 'count' entries from the stack.
+@ Call Stack:
+@ count <-- TOS
+@ Return Stack:
+@ <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+NSSVTTTSSTN | Mark: 111001 (dump stack)
+
+@ Print output line for the current TOS.
+SNS | DUP
+NSTTSSSSTTN | JSR>1000011 (print absolute value of number)
+SSSTTTSTSN | PUSH ASCII ':'
+SSSTSSTN | PUSH ASCII '\t'
+TNSS | PUTC
+TNSS | PUTC
+SNT | SWAP
+NSTTSTSN | JSR>1010 (print number from stack)
+SSSTSTSN | PUSH ASCII '\n'
+TNSS | PUTC
+
+@ Figure out if the loop is complete.
+SNS | DUP
+NTSSSTTTSSTSSSSSSSSN | BRZ > 00111001 00000000
+SSSTN | PUSH 1
+TSST | SUBTRACT
+NSNTTTSSTN | JMP>111001 (dump stack)
+
+@ Clean up and return
+NSSVSSTTTSSTSSSSSSSSN | Mark: 00111001 00000000
+SNN | DROP
+NTN | RTS
+
#endif
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTSSSN | Mark: 11000 (memset)
SSSTTN | PUSH 3
-NSTTTTTTN | JSR > 11111 (spew)
+NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Store 'pattern' into one memory location on each pass through this loop.
NSSVSSSTTSSSSSSSSSSSN | Mark: 00011000 00000000
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTSSTN | Mark: 11001 (memcpy)
SSSTTN | PUSH 3
-NSTTTTTTN | JSR > 11111 (spew)
+NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Copy one word on each pass through this loop.
NSSVSSSTTSSTSSSSSSSSN | Mark: 00011001 00000000
#include <math.pvvs>
NSSVTTSTSN | Mark: 11010 (memrand)
SSSTN | PUSH 1
-NSTTTTTTN | JSR > 11111 (spew)
+NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Store random word into one memory location on each pass through this loop.
NSSVSSSTTSTSSSSSSSSSN | Mark: 00011010 00000000
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTSTTN | Mark: 11011 (memcmp)
SSSTSN | PUSH 2
-NSTTTTTTN | JSR > 11111 (spew)
+NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Compare one word on each pass through this loop.
NSSVSSSTTSTTSSSSSSSSN | Mark: 00011011 00000000
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTTTSSN | Mark: 11100 (memsrch)
SSSTTN | PUSH 3
-NSTTTTTTN | JSR > 11111 (spew)
+NSTTSSSSSTN | JSR > 1000001 (spewreg)
@ Compare one word on each pass through this loop.
NSSVSSSTTTSSSSSSSSSSN | Mark: 00011100 00000000
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
-@ slurp (11110)
+@ slurpreg (1000000)
@ Description:
-@ Reads 'count' values from heap to stack in complementary order to 'spew'.
+@ Reads 'count' values from heap to stack in complementary order to 'spewreg'.
@ Call Stack:
@ count
@ Return Stack:
@ heap[2]
@ heap[1] <-- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTTTTSN | Mark: 11110 (slurp)
+NSSVTSSSSSSN | Mark: 1000000 (slurpreg)
@ Load one word from heap on each pass.
-NSSVSSSTTTTSSSSSSSSSN | Mark: 00011110 00000000
+NSSVSTSSSSSSSSSSSSSSN | Mark: 01000000 00000000
SNS | DUP
TTT | LOAD
SNT | SWAP
SSSTN | PUSH 1
TSST | SUBTRACT
SNS | DUP
-NTSSSSTTTTSSSSSSSSTN | BRZ > 00011110 00000001
-NSNSSSTTTTSSSSSSSSSN | JMP > 00011110 00000000
-NSSVSSSTTTTSSSSSSSSTN | Mark: 00011110 00000001
+NTSSTSSSSSSSSSSSSSTN | BRZ > 01000000 00000001
+NSNSTSSSSSSSSSSSSSSN | JMP > 01000000 00000000
+NSSVSTSSSSSSSSSSSSSTN | Mark: 01000000 00000001
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
-@ spew (11111)
+@ spewreg (1000001)
@ Description:
@ Writes 'count' values from stack to heap in this order:
@ TOS -> heap[1]
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTTTTTN | Mark: 11111 (spew)
+NSSVTSSSSSTN | Mark: 1000001 (spewreg)
@ Create a counter in heap[0] that doubles as a destination pointer generator.
SSSSN | PUSH 0 (ptr)
TTS | STORE
@ Store one word to heap on each pass.
-NSSVSSSTTTTTSSSSSSSSN | Mark: 00011111 00000000
+NSSVSTSSSSSTSSSSSSSSN | Mark: 01000001 00000000
SNT | SWAP
SSSSN | PUSH 0 (ptr)
TTT | LOAD
SSSSN | PUSH 0 (ptr)
TTT | LOAD
TSST | SUBTRACT
-NTSSSSTTTTTSSSSSSSTN | BRZ > 00011111 00000001
+NTSSTSSSSSTSSSSSSSTN | BRZ > 01000001 00000001
@ Increment heap[0] if continuing.
SSSSN | PUSH 0 (ptr)
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)
+SSSTSN | PUSH 2
+NSTTSSSSSTN | JSR > 1000001 (spewreg)
+
+@ Load one word from heap on each pass.
+NSSVSSSTTTTSSSSSSSSSN | Mark: 00011110 00000000
+SSSTN | PUSH 1 (ptr)
+TTT | LOAD
+SSSTSN | PUSH 2 (ptr)
+TTT | LOAD
+TSSS | ADD
+TTT | LOAD
+
+@ Check for loop completion.
+@ As a side effect, prepare the next address.
+SSSTN | PUSH 1 (ptr)
+SNS | DUP
+TTT | LOAD
+SNS | DUP
+NTSSSSTTTTSSSSSSSSTN | BRZ > 00011110 00000001
+SSSTN | PUSH 1
+TSST | SUBTRACT
+TTS | STORE
+NSNSSSTTTTSSSSSSSSSN | JMP > 00011110 00000000
+NSSVSSSTTTTSSSSSSSSTN | Mark: 00011110 00000001
+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
-SNN | DROP
NTN | RTS
#endif
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTSN | Mark: 1010 (print number from stack)
SNS | DUP
-NSTTSSSSSSN | JSR > 1000000
-NSTTSSSSSTN | JSR > 1000001
+NSTTSSSSTSN | JSR > 1000010
+NSTTSSSSTTN | JSR > 1000011
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
-@ printstacknumbersign (1000000)
+@ printstacknumbersign (1000010)
@ Description:
@ Prints the sign of 'number' from the stack.
@ Call Stack:
@ Return Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSSSSN | Mark: 1000000 (print sign of number from stack)
-NTTSTSSSSSSSSSSSSSTN | BMI > 010000000 00000001
+NSSVTSSSSTSN | Mark: 1000010 (print sign of number from stack)
+NTTSTSSSSTSSSSSSSSTN | BMI > 01000010 00000001
SSSTSTSTTN | PUSH ASCII '+'
-NSNSTSSSSSSSSSSSSTSN | JMP > 010000000 00000010
-NSSVSTSSSSSSSSSSSSSTN | Mark: 010000000 00000001
+NSNSTSSSSTSSSSSSSTSN | JMP > 01000010 00000010
+NSSVSTSSSSTSSSSSSSSTN | Mark: 01000010 00000001
SSSTSTTSTN | PUSH ASCII '-'
-NSSVSTSSSSSSSSSSSSTSN | Mark: 010000000 00000010
+NSSVSTSSSSTSSSSSSSTSN | Mark: 01000010 00000010
TNSS | PUTC
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
-@ printstacknumbermagnitude (1000001)
+@ printstacknumbermagnitude (1000011)
@ Description:
@ Prints the magnitude of 'number' from the stack.
@ Call Stack:
@ <empty>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#include <math.pvvs>
-NSSVTSSSSSTN | Mark: 1000001 (print magnitude of number from stack)
+NSSVTSSSSTTN | Mark: 1000011 (print magnitude of number from stack)
NSTTSSSTN | JSR > 10001 (absolute value)
SSSSN | PUSH ASCII '\0'
SNT | SWAP
@ Pick off one digit on each pass through this loop.
-NSSVSTSSSSSTSSSSSSSSN | Mark: 01000001 00000000
+NSSVSTSSSSTTSSSSSSSSN | Mark: 01000011 00000000
SNS | DUP
@ Mod-off a digit, convert to ASCII, store on stack as part of the string.
SSSTSTSN | PUSH +10
TSTS | DIVIDE
SNS | DUP
-NTSSTSSSSSTSSSSSSSTN | BRZ > 01000001 00000001
-NSNSTSSSSSTSSSSSSSSN | JMP > 01000001 00000000
+NTSSTSSSSTTSSSSSSSTN | BRZ > 01000011 00000001
+NSNSTSSSSTTSSSSSSSSN | JMP > 01000011 00000000
@ Print the string we have built on the stack.
-NSSVSTSSSSSTSSSSSSSTN | Mark: 01000001 00000001
+NSSVSTSSSSTTSSSSSSSTN | Mark: 01000011 00000001
SNN | DROP
NSTTSSSN | JSR > 1000 (print string from stack)
NTN | RTS
--- /dev/null
+#ifndef VVS_STDLIB_STRING
+#define VVS_STDLIB_STRING
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@ strlen (100000)
+@ Description:
+@ Counts number of words in a null-terminated string.
+@ Returned number does not include the null-terminator.
+@ Call Stack:
+@ pointer to first character <-- TOS
+@ Return Stack:
+@ number of words in string <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSSSN | Mark: 100000 (strlen)
+
+@ Create a length counter.
+SSSSN | PUSH 0
+SNT | SWAP
+
+@ Increment the counter (and pointer) on each pass through the loop.
+NSSVSSTSSSSSSSSSSSSSN | Mark: 00100000 00000000
+SNS | DUP
+TTT | LOAD
+NTSSSTSSSSSSSSSSSSTN | BRZ > 00100000 00000001
+SNT | SWAP
+SSSTN | PUSH 1
+TSSS | ADD
+SNT | SWAP
+SSSTN | PUSH 1
+TSSS | ADD
+NSNSSTSSSSSSSSSSSSSN | JMP > 00100000 00000000
+
+@ Clean up and return.
+NSSVSSTSSSSSSSSSSSSTN | Mark: 00100000 00000001
+SNN | DROP
+NTN | RTS
+
+#endif