#ifndef VVS_STDLIB_STACK #define VVS_STDLIB_STACK @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ stackrotate @ Description: @ Maximum rotation depth is 14. Stomps on heap[1]-heap[15]. @ Call Stack: @ stack word n @ ... @ stack word 1 @ rotation depth (rd) <-- TOS @ Return Stack (n>rd=3): @ stack word n @ ... @ stack word 1 @ stack word 3 @ stack word 2 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSTSN | Mark: 1010 (stackrotate) @ For the convenience of other functions, modulo the @ rotation depth by the available registers. SSSTTTSN | PUSH 14 TSTT | MODULO @ Use heap[15] for generating register addresses. SSSTTTTN | PUSH 15 (ptr) SSSSN | PUSH 0 TTS | STORE @ Dump one word from stack to heap each pass through the loop. NSSVSSSSTSTSSSSSSSSSN | Mark: 00001010 00000000 SNT | SWAP SSSTN | PUSH 1 (starting register) SSSTTTTN | PUSH 15 (ptr) TTT | LOAD TSSS | ADD SNT | SWAP TTS | STORE @ See if the loop is complete. SNS | DUP SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSSS | ADD TSST | SUBTRACT NTSSSSSTSTSSSSSSSSTN | BRZ > 00001010 00000001 @ Increment the loop counter SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSSS | ADD SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE NSNSSSSTSTSSSSSSSSSN | JMP > 00001010 00000000 @ The correct number of words have been stored to registers. @ Time to read them back in rotated order. @ First, prepare the counter in heap[15] again. @ This consumes 'rd' from the stack. NSSVSSSSTSTSSSSSSSSTN | Mark: 00001010 00000001 SSSTN | PUSH 1 TSST | SUBTRACT SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE @ Second, read in the old TOS manually. SSSTN | PUSH 1 (starting register) TTT | LOAD @ Read one word per pass through this loop. NSSVSSSSTSTSSSSSSSTSN | Mark: 00001010 00000010 SSSTN | PUSH 1 (starting register) SSSTTTTN | PUSH 15 (ptr) TTT | LOAD TSSS | ADD TTT | LOAD @ See if the loop is complete. SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT NTSSSSSTSTSSSSSSSTTN | BRZ > 00001010 00000011 @ Decrement the loop counter and loop again. SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE NSNSSSSTSTSSSSSSSTSN | JMP > 00001010 00000010 @ Return NSSVSSSSTSTSSSSSSSTTN | Mark: 00001010 00000011 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ stackrotatereverse @ Description: @ Maximum rotation depth is 14. Stomps on heap[1]-heap[15]. @ Call Stack: @ stack word n @ ... @ stack word 1 @ rotation depth (rd) <-- TOS @ Return Stack (n>rd=3): @ stack word n @ ... @ stack word 2 @ stack word 1 @ stack word 3 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSTTN | Mark: 1011 (stackrotatereverse) @ For the convenience of other functions, modulo the @ rotation depth by the available registers. SSSTTTSN | PUSH 14 TSTT | MODULO @ Use heap[15] for generating register addresses. SSSTTTTN | PUSH 15 (ptr) SSSSN | PUSH 0 TTS | STORE @ Dump one word from stack to heap each pass through the loop. NSSVSSSSTSTTSSSSSSSSN | Mark: 00001011 00000000 SNT | SWAP SSSTN | PUSH 1 (starting register) SSSTTTTN | PUSH 15 (ptr) TTT | LOAD TSSS | ADD SNT | SWAP TTS | STORE @ See if the loop is complete. SNS | DUP SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSSS | ADD TSST | SUBTRACT NTSSSSSTSTTSSSSSSSTN | BRZ > 00001011 00000001 @ Increment the loop counter SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSSS | ADD SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE NSNSSSSTSTTSSSSSSSSN | JMP > 00001011 00000000 @ The correct number of words have been stored to registers. @ Time to read them back in rotated order. @ First, prepare the counter in heap[15] again. NSSVSSSSTSTTSSSSSSSTN | Mark: 00001011 00000001 SSSTN | PUSH 1 TSST | SUBTRACT SNS | DUP SSSTN | PUSH 1 TSST | SUBTRACT SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE @ Read one word per pass through this loop. @ Store it behind 'rd' on the stack. NSSVSSSSTSTTSSSSSSTSN | Mark: 00001011 00000010 SSSTN | PUSH 1 (starting register) SSSTTTTN | PUSH 15 (ptr) TTT | LOAD TSSS | ADD TTT | LOAD SNT | SWAP @ See if the loop is complete. SSSTTTTN | PUSH 15 (ptr) TTT | LOAD NTSSSSSTSTTSSSSSSTTN | BRZ > 00001011 00000011 @ Decrement the loop counter and loop again. SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE NSNSSSSTSTTSSSSSSTSN | JMP > 00001011 00000010 @ Read in the final value manually and return. NSSVSSSSTSTTSSSSSSTTN | Mark: 00001011 00000011 SSSTN | PUSH 1 (starting register) TSSS | ADD TTT | LOAD NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ deepdup @ Description: @ Duplicates an item deep on the stack, placing the duplicate on TOS. @ By default, maximum depth is 11. @ True maximum depth is (max depth of stackrotate & stackrotatereverse)-3. @ Call Stack: @ stack word n @ ... @ stack word 1 @ dupdepth <-- TOS @ Return Stack: @ stack word n @ ... @ stack word 1 @ copy of stack word 3 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTTSSN | Mark: 1100 (deepdup) @ Copy 'dupdepth' and use it to bring forth the desired stack word. SNS | DUP SSSTN | PUSH 1 TSSS | ADD NSTTSTTN | JSR > 1011 (stackrotatereverse) @ Copy the desired stack word and return it back into the stack. SNS | DUP SSSTTN | PUSH 3 NSTTSTTN | JSR > 1011 (stackrotatereverse) SSSTN | PUSH 1 TSSS | ADD NSTTSTSN | JSR > 1010 (stackrotate) NTN | RTS #endif