Modified stdlib to use stack rotations to timeshare heap registers.
[vvhitespace] / stdlib / stack.pvvs
CommitLineData
23d17247
AT
1#ifndef VVS_STDLIB_STACK
2#define VVS_STDLIB_STACK
3
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5@ Name:
6@ stackrotate
7@ Description:
6cb31a3e 8@ Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
23d17247
AT
9@ Call Stack:
10@ stack word n
11@ ...
12@ stack word 1
13@ rotation depth (rd) <-- TOS
14@ Return Stack (n>rd=3):
15@ stack word n
16@ ...
17@ stack word 1
18@ stack word 3
19@ stack word 2 <-- TOS
20@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
21NSSVTSTSN | Mark: 1010 (stackrotate)
22
23@ For the convenience of other functions, modulo the
24@ rotation depth by the available registers.
6cb31a3e 25SSSTTTSN | PUSH 14
23d17247
AT
26TSTT | MODULO
27
6cb31a3e
AT
28@ Use heap[15] for generating register addresses.
29SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
30SSSSN | PUSH 0
31TTS | STORE
32
33@ Dump one word from stack to heap each pass through the loop.
34NSSVSSSSTSTSSSSSSSSSN | Mark: 00001010 00000000
35SNT | SWAP
6cb31a3e
AT
36SSSTN | PUSH 1 (starting register)
37SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
38TTT | LOAD
39TSSS | ADD
40SNT | SWAP
41TTS | STORE
42
43@ See if the loop is complete.
44SNS | DUP
6cb31a3e 45SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
46TTT | LOAD
47SSSTN | PUSH 1
48TSSS | ADD
49TSST | SUBTRACT
50NTSSSSSTSTSSSSSSSSTN | BRZ > 00001010 00000001
51
52@ Increment the loop counter
6cb31a3e 53SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
54TTT | LOAD
55SSSTN | PUSH 1
56TSSS | ADD
6cb31a3e 57SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
58SNT | SWAP
59TTS | STORE
60NSNSSSSTSTSSSSSSSSSN | JMP > 00001010 00000000
61
62@ The correct number of words have been stored to registers.
63@ Time to read them back in rotated order.
64
6cb31a3e 65@ First, prepare the counter in heap[15] again.
23d17247
AT
66@ This consumes 'rd' from the stack.
67NSSVSSSSTSTSSSSSSSSTN | Mark: 00001010 00000001
68SSSTN | PUSH 1
69TSST | SUBTRACT
6cb31a3e 70SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
71SNT | SWAP
72TTS | STORE
73
74@ Second, read in the old TOS manually.
6cb31a3e 75SSSTN | PUSH 1 (starting register)
23d17247
AT
76TTT | LOAD
77
78@ Read one word per pass through this loop.
79NSSVSSSSTSTSSSSSSSTSN | Mark: 00001010 00000010
6cb31a3e
AT
80SSSTN | PUSH 1 (starting register)
81SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
82TTT | LOAD
83TSSS | ADD
84TTT | LOAD
85
86@ See if the loop is complete.
6cb31a3e 87SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
88TTT | LOAD
89SSSTN | PUSH 1
90TSST | SUBTRACT
91NTSSSSSTSTSSSSSSSTTN | BRZ > 00001010 00000011
92
93@ Decrement the loop counter and loop again.
6cb31a3e 94SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
95TTT | LOAD
96SSSTN | PUSH 1
97TSST | SUBTRACT
6cb31a3e 98SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
99SNT | SWAP
100TTS | STORE
101NSNSSSSTSTSSSSSSSTSN | JMP > 00001010 00000010
102
103@ Return
104NSSVSSSSTSTSSSSSSSTTN | Mark: 00001010 00000011
105NTN | RTS
106
a67867ae
AT
107@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
108@ Name:
109@ stackrotatereverse
110@ Description:
6cb31a3e 111@ Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
a67867ae
AT
112@ Call Stack:
113@ stack word n
114@ ...
115@ stack word 1
116@ rotation depth (rd) <-- TOS
117@ Return Stack (n>rd=3):
118@ stack word n
119@ ...
120@ stack word 2
121@ stack word 1
122@ stack word 3 <-- TOS
123@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
124NSSVTSTTN | Mark: 1011 (stackrotatereverse)
125
126@ For the convenience of other functions, modulo the
127@ rotation depth by the available registers.
6cb31a3e 128SSSTTTSN | PUSH 14
a67867ae
AT
129TSTT | MODULO
130
6cb31a3e
AT
131@ Use heap[15] for generating register addresses.
132SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
133SSSSN | PUSH 0
134TTS | STORE
135
136@ Dump one word from stack to heap each pass through the loop.
137NSSVSSSSTSTTSSSSSSSSN | Mark: 00001011 00000000
138SNT | SWAP
6cb31a3e
AT
139SSSTN | PUSH 1 (starting register)
140SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
141TTT | LOAD
142TSSS | ADD
143SNT | SWAP
144TTS | STORE
145
146@ See if the loop is complete.
147SNS | DUP
6cb31a3e 148SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
149TTT | LOAD
150SSSTN | PUSH 1
151TSSS | ADD
152TSST | SUBTRACT
153NTSSSSSTSTTSSSSSSSTN | BRZ > 00001011 00000001
154
155@ Increment the loop counter
6cb31a3e 156SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
157TTT | LOAD
158SSSTN | PUSH 1
159TSSS | ADD
6cb31a3e 160SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
161SNT | SWAP
162TTS | STORE
163NSNSSSSTSTTSSSSSSSSN | JMP > 00001011 00000000
164
165@ The correct number of words have been stored to registers.
166@ Time to read them back in rotated order.
167
6cb31a3e 168@ First, prepare the counter in heap[15] again.
a67867ae
AT
169NSSVSSSSTSTTSSSSSSSTN | Mark: 00001011 00000001
170SSSTN | PUSH 1
171TSST | SUBTRACT
172SNS | DUP
173SSSTN | PUSH 1
174TSST | SUBTRACT
6cb31a3e 175SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
176SNT | SWAP
177TTS | STORE
178
179@ Read one word per pass through this loop.
180@ Store it behind 'rd' on the stack.
181NSSVSSSSTSTTSSSSSSTSN | Mark: 00001011 00000010
6cb31a3e
AT
182SSSTN | PUSH 1 (starting register)
183SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
184TTT | LOAD
185TSSS | ADD
186TTT | LOAD
187SNT | SWAP
188
189@ See if the loop is complete.
6cb31a3e 190SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
191TTT | LOAD
192NTSSSSSTSTTSSSSSSTTN | BRZ > 00001011 00000011
193
194@ Decrement the loop counter and loop again.
6cb31a3e 195SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
196TTT | LOAD
197SSSTN | PUSH 1
198TSST | SUBTRACT
6cb31a3e 199SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
200SNT | SWAP
201TTS | STORE
202NSNSSSSTSTTSSSSSSTSN | JMP > 00001011 00000010
203
204@ Read in the final value manually and return.
205NSSVSSSSTSTTSSSSSSTTN | Mark: 00001011 00000011
6cb31a3e 206SSSTN | PUSH 1 (starting register)
a67867ae
AT
207TSSS | ADD
208TTT | LOAD
209NTN | RTS
210
f0499c77
AT
211@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
212@ Name:
213@ deepdup
214@ Description:
215@ Duplicates an item deep on the stack, placing the duplicate on TOS.
216@ By default, maximum depth is 11.
217@ True maximum depth is (max depth of stackrotate & stackrotatereverse)-3.
218@ Call Stack:
219@ stack word n
220@ ...
221@ stack word 1
222@ dupdepth <-- TOS
223@ Return Stack:
224@ stack word n
225@ ...
226@ stack word 1
227@ copy of stack word 3 <-- TOS
228@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
229NSSVTTSSN | Mark: 1100 (deepdup)
230
231@ Copy 'dupdepth' and use it to bring forth the desired stack word.
232SNS | DUP
233SSSTN | PUSH 1
234TSSS | ADD
235NSTTSTTN | JSR > 1011 (stackrotatereverse)
236
237@ Copy the desired stack word and return it back into the stack.
238SNS | DUP
239SSSTTN | PUSH 3
240NSTTSTTN | JSR > 1011 (stackrotatereverse)
241SSSTN | PUSH 1
242TSSS | ADD
243NSTTSTSN | JSR > 1010 (stackrotate)
244NTN | RTS
245
23d17247 246#endif
a67867ae 247