#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: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 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: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 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: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include 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: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 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: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 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