Commit | Line | Data |
---|---|---|
2da74194 AT |
1 | #ifndef WUMP_GAME |
2 | #define WUMP_GAME | |
3 | ||
4 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
5 | @ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com> | |
6 | @ See LICENSE.txt file for copyright and license details. | |
7 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
8 | ||
9 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
10 | @ Name: | |
11 | @ get_tunnel_destination | |
12 | @ Description: | |
13 | @ Returns the room number corresponding to the destination of a tunnel | |
14 | @ specified by room and slot. | |
15 | @ Call Stack: | |
16 | @ slot | |
17 | @ room_number <-- TOS | |
18 | @ Return Stack: | |
19 | @ dst_room_number <-- TOS | |
20 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
21 | NSSVTSSSTSSSN | MARK: 10001000 (get_tunnel_destination) | |
22 | @ The pointer we seek is: | |
23 | @ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE | |
24 | @ Where the '+2' accounts for the pit and bat booleans. | |
25 | NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size) | |
26 | TSSN | MULTIPLY | |
27 | SSSTSN | PUSH +2 | |
28 | TSSS | ADD | |
29 | TSSS | ADD | |
30 | SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (ROOM_DATA_BASE address) | |
31 | TSSS | ADD | |
32 | TTT | LOAD | |
33 | NTN | RTS | |
34 | ||
35 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
36 | @ Name: | |
37 | @ get_room_struct_size | |
38 | @ Description: | |
39 | @ Returns the size in words of the data structure for a single room. | |
40 | @ For example, with 3 links plus bat and pit booleans, the size is 5 words. | |
41 | @ Call Stack: | |
42 | @ <empty> | |
43 | @ Return Stack: | |
44 | @ size <-- TOS | |
45 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
46 | NSSVTSSSTSTTN | MARK: 10001011 (get_room_struct_size) | |
47 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address) | |
48 | TTT | LOAD | |
49 | SSSTSN | PUSH +2 | |
50 | TSSS | ADD | |
51 | NTN | RTS | |
52 | ||
53 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
54 | @ Name: | |
55 | @ room_has_bats | |
56 | @ Description: | |
57 | @ Check if room_number contains bats. | |
58 | @ Returns 1 or 0 representing true or false. | |
59 | @ Call Stack: | |
60 | @ room_number <-- TOS | |
61 | @ Return Stack: | |
62 | @ 1 or 0 <-- TOS | |
63 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
64 | NSSVTSSSTTSSN | MARK: 10001100 (room_has_bats) | |
65 | @ We seek the pointer: | |
66 | @ (room_number * room_struct_size) + 1 + ROOM_DATA_BASE | |
67 | @ where '+1' accounts for the offset of the bat boolean in the desired room. | |
68 | NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size) | |
69 | TSSN | MULTIPLY | |
70 | SSSTN | PUSH +1 | |
71 | TSSS | ADD | |
72 | SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (GAME_DATA_BASE address) | |
73 | TSSS | ADD | |
74 | TTT | LOAD | |
75 | NTN | RTS | |
76 | ||
77 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
78 | @ Name: | |
79 | @ room_has_pits | |
80 | @ Description: | |
81 | @ Check if room_number contains pits. | |
82 | @ Returns 1 or 0 representing true or false. | |
83 | @ Call Stack: | |
84 | @ room_number <-- TOS | |
85 | @ Return Stack: | |
86 | @ 1 or 0 <-- TOS | |
87 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
88 | NSSVTSSSTTSTN | MARK: 10001101 (room_has_pits) | |
89 | @ We seek the pointer: | |
90 | @ (room_number * room_struct_size) + 0 + ROOM_DATA_BASE | |
91 | @ where '+0' accounts for the offset of the pit boolean in the desired room. | |
92 | NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size) | |
93 | TSSN | MULTIPLY | |
94 | SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (GAME_DATA_BASE address) | |
95 | TSSS | ADD | |
96 | TTT | LOAD | |
97 | NTN | RTS | |
98 | ||
99 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
100 | @ Name: | |
101 | @ room_has_wumpus | |
102 | @ Description: | |
103 | @ Check if room contains wumpus. | |
104 | @ Returns 1 or 0 representing true or false. | |
105 | @ Call Stack: | |
106 | @ room_number <-- TOS | |
107 | @ Return Stack: | |
108 | @ 1 or 0 <-- TOS | |
109 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
110 | NSSVTSTSSSSSN | MARK: 10100000 (room_has_wumpus) | |
111 | SSSTSSSSSSSSSTTTN | PUSH 0x1007 (wumpus_location address) | |
112 | TTT | LOAD | |
113 | TSST | SUBTRACT | |
114 | NTSTSTSSSSSSSSSSSSSN | BRZ > 10100000 00000000 (room_has_wumpus:true) | |
115 | SSSSN | PUSH 0 (false) | |
116 | NTN | RTS | |
117 | NSSVTSTSSSSSSSSSSSSSN | MARK: 10100000 00000000 (room_has_wumpus:true) | |
118 | SSSTN | PUSH 1 (true) | |
119 | NTN | RTS | |
120 | ||
121 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
122 | @ Name: | |
123 | @ are_bats_near | |
124 | @ Description: | |
125 | @ Given a room number, checks rooms within one hop for bats. | |
126 | @ Returns 1 if bats are present or 0 if no bats. | |
127 | @ Call Stack: | |
128 | @ room_number <-- TOS | |
129 | @ Return Stack: | |
130 | @ 1 or 0 <-- TOS | |
131 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
132 | #include <stack.pvvs> | |
133 | NSSVTSSTTTSSN | MARK: 10011100 (are_bats_near) | |
134 | ||
135 | @ Prepare the stack by loading the number of links per room and decrementing. | |
136 | @ We will loop until this reaches 0 or we find bats. | |
137 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) | |
138 | TTT | LOAD | |
139 | SSSTN | PUSH 1 | |
140 | TSST | SUBTRACT | |
141 | ||
142 | @ Check one nearby room on each pass through this loop. | |
143 | @ TOS> tunnel_index, room_number | |
144 | NSSVTSSTTTSSSSSSSSSSN | MARK: 10011100 00000000 (are_bats_near:loop) | |
145 | SNS | DUP | |
146 | SSSTTN | PUSH 3 | |
147 | NSTTTSSN | JSR > 1100 (deepdup) | |
148 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
149 | NSTTSSSTTSSN | JSR > 10001100 (room_has_bats) | |
150 | NTSTSSTTTSSSSSSSSSTN | BRZ > 10011100 00000001 (no_bats_in_this_room) | |
151 | @ Found bats. Clean up and return. | |
152 | SNN | DROP | |
153 | SNN | DROP | |
154 | SSSTN | PUSH 1 | |
155 | NTN | RTS | |
156 | NSSVTSSTTTSSSSSSSSSTN | MARK: 10011100 00000001 (no_bats_in_this_room) | |
157 | @ Test for end of loop. | |
158 | SNS | DUP | |
159 | NTSTSSTTTSSSSSSSSTSN | BRZ > 10011100 00000010 (are_bats_near:loop_end) | |
160 | @ No bats found yet, but still need to check some rooms. | |
161 | @ Decrement tunnel index and loop again. | |
162 | SSSTN | PUSH 1 | |
163 | TSST | SUBTRACT | |
164 | NSNTSSTTTSSSSSSSSSSN | JMP > 10011100 00000000 (are_bats_near:loop) | |
165 | @ No bats found in nearby rooms. Clean up and return. | |
166 | NSSVTSSTTTSSSSSSSSTSN | MARK: 10011100 00000010 (are_bats_near:loop_end) | |
167 | SNN | DROP | |
168 | SNN | DROP | |
169 | SSSSN | PUSH 0 | |
170 | NTN | RTS | |
171 | ||
172 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
173 | @ Name: | |
174 | @ are_pits_near | |
175 | @ Description: | |
176 | @ Given a room number, checks rooms within one hop for pits. | |
177 | @ Returns 1 if pits are present or 0 if no pits. | |
178 | @ Call Stack: | |
179 | @ room_number <-- TOS | |
180 | @ Return Stack: | |
181 | @ 1 or 0 <-- TOS | |
182 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
183 | #include <stack.pvvs> | |
184 | NSSVTSSTTTSTN | MARK: 10011101 (are_pits_near) | |
185 | ||
186 | @ Prepare the stack by loading the number of links per room and decrementing. | |
187 | @ We will loop until this reaches 0 or we find pits. | |
188 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) | |
189 | TTT | LOAD | |
190 | SSSTN | PUSH 1 | |
191 | TSST | SUBTRACT | |
192 | ||
193 | @ Check one nearby room on each pass through this loop. | |
194 | @ TOS> tunnel_index, room_number | |
195 | NSSVTSSTTTSTSSSSSSSSN | MARK: 10011101 00000000 (are_pits_near:loop) | |
196 | SNS | DUP | |
197 | SSSTTN | PUSH 3 | |
198 | NSTTTSSN | JSR > 1100 (deepdup) | |
199 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
200 | NSTTSSSTTSTN | JSR > 10001101 (room_has_pits) | |
201 | NTSTSSTTTSTSSSSSSSTN | BRZ > 10011101 00000001 (no_pits_in_this_room) | |
202 | @ Found pits. Clean up and return. | |
203 | SNN | DROP | |
204 | SNN | DROP | |
205 | SSSTN | PUSH 1 | |
206 | NTN | RTS | |
207 | NSSVTSSTTTSTSSSSSSSTN | MARK: 10011101 00000001 (no_pits_in_this_room) | |
208 | @ Test for end of loop. | |
209 | SNS | DUP | |
210 | NTSTSSTTTSTSSSSSSTSN | BRZ > 10011101 00000010 (are_pits_near:loop_end) | |
211 | @ No pits found yet, but still need to check some rooms. | |
212 | @ Decrement tunnel index and loop again. | |
213 | SSSTN | PUSH 1 | |
214 | TSST | SUBTRACT | |
215 | NSNTSSTTTSTSSSSSSSSN | JMP > 10011101 00000000 (are_pits_near:loop) | |
216 | @ No pits found in nearby rooms. Clean up and return. | |
217 | NSSVTSSTTTSTSSSSSSTSN | MARK: 10011101 00000010 (are_pits_near:loop_end) | |
218 | SNN | DROP | |
219 | SNN | DROP | |
220 | SSSSN | PUSH 0 | |
221 | NTN | RTS | |
222 | ||
223 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
224 | @ Name: | |
225 | @ is_wumpus_very_near | |
226 | @ Description: | |
227 | @ Given a room number, checks rooms within one hop for the wumpus. | |
228 | @ Returns 1 if wumpus is present, otherwise 0. | |
229 | @ Call Stack: | |
230 | @ room_number <-- TOS | |
231 | @ Return Stack: | |
232 | @ 1 or 0 <-- TOS | |
233 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
234 | #include <stack.pvvs> | |
235 | NSSVTSSTTTTTN | MARK: 10011111 (is_wumpus_very_near) | |
236 | ||
237 | @ Prepare the stack by loading the number of links per room and decrementing. | |
238 | @ We will loop until this reaches 0 or we find the wumpus. | |
239 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) | |
240 | TTT | LOAD | |
241 | SSSTN | PUSH 1 | |
242 | TSST | SUBTRACT | |
243 | ||
244 | @ Check one nearby room on each pass through this loop. | |
245 | @ TOS> tunnel_index, room_number | |
246 | NSSVTSSTTTTTSSSSSSSSN | MARK: 10011111 00000000 (is_wumpus_very_near:loop) | |
247 | SNS | DUP | |
248 | SSSTTN | PUSH 3 | |
249 | NSTTTSSN | JSR > 1100 (deepdup) | |
250 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
251 | NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) | |
252 | NTSTSSTTTTTSSSSSSSTN | BRZ > 10011111 00000001 (no_wumpus_in_this_room) | |
253 | @ Found wumpus. Clean up and return. | |
254 | SNN | DROP | |
255 | SNN | DROP | |
256 | SSSTN | PUSH 1 | |
257 | NTN | RTS | |
258 | NSSVTSSTTTTTSSSSSSSTN | MARK: 10011111 00000001 (no_wumpus_in_this_room) | |
259 | @ Test for end of loop. | |
260 | SNS | DUP | |
261 | NTSTSSTTTTTSSSSSSTSN | BRZ > 10011111 00000010 (is_wumpus_very_near:loop_end) | |
262 | @ No wumpus found yet, but still need to check some rooms. | |
263 | @ Decrement tunnel index and loop again. | |
264 | SSSTN | PUSH 1 | |
265 | TSST | SUBTRACT | |
266 | NSNTSSTTTTTSSSSSSSSN | JMP > 10011111 00000000 (is_wumpus_very_near:loop) | |
267 | @ No wumpus found in nearby rooms. Clean up and return. | |
268 | NSSVTSSTTTTTSSSSSSTSN | MARK: 10011111 00000010 (is_wumpus_very_near:loop_end) | |
269 | SNN | DROP | |
270 | SNN | DROP | |
271 | SSSSN | PUSH 0 | |
272 | NTN | RTS | |
273 | ||
274 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
275 | @ Name: | |
276 | @ is_wumpus_near | |
277 | @ Description: | |
278 | @ Given a room number, checks rooms within two hops for the wumpus. | |
279 | @ Returns 1 if wumpus is present, otherwise 0. | |
280 | @ Call Stack: | |
281 | @ room_number <-- TOS | |
282 | @ Return Stack: | |
283 | @ 1 or 0 <-- TOS | |
284 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
285 | #include <stack.pvvs> | |
286 | NSSVTSSTTTTSN | MARK: 10011110 (is_wumpus_near) | |
287 | ||
288 | @ Prepare the stack by loading the number of links per room and decrementing. | |
289 | @ We will loop until this reaches 0 or we find the wumpus. | |
290 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) | |
291 | TTT | LOAD | |
292 | SSSTN | PUSH 1 | |
293 | TSST | SUBTRACT | |
294 | ||
295 | @ Check one nearby room and its connecting rooms on each pass through this loop. | |
296 | @ TOS> tunnel_index, room_number | |
297 | NSSVTSSTTTTSSSSSSSSSN | MARK: 10011110 00000000 (is_wumpus_near:loop) | |
298 | SNS | DUP | |
299 | SSSTTN | PUSH 3 | |
300 | NSTTTSSN | JSR > 1100 (deepdup) | |
301 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
302 | @ TOS> tunnel_endpoint, tunnel_index, room_number | |
303 | SNS | DUP | |
304 | NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) | |
305 | SSSTN | PUSH 1 | |
306 | TSST | SUBTRACT | |
307 | NTSTSSTTTTSSSSSSSTTN | BRZ > 10011110 00000011 (found_wumpus_one_hop) | |
308 | NSTTSSTTTTTN | JSR > 10011111 (is_wumpus_very_near) | |
309 | SSSTN | PUSH 1 | |
310 | TSST | SUBTRACT | |
311 | NTSTSSTTTTSSSSSSTSSN | BRZ > 10011110 00000100 (found_wumpus_two_hops) | |
312 | @ Test for end of loop. | |
313 | SNS | DUP | |
314 | NTSTSSTTTTSSSSSSSTSN | BRZ > 10011110 00000010 (is_wumpus_near:loop_end) | |
315 | @ No wumpus found yet, but still need to check some rooms. | |
316 | @ Decrement tunnel index and loop again. | |
317 | SSSTN | PUSH 1 | |
318 | TSST | SUBTRACT | |
319 | NSNTSSTTTTSSSSSSSSSN | JMP > 10011110 00000000 (is_wumpus_near:loop) | |
320 | ||
321 | @ No wumpus found in nearby rooms. Clean up and return. | |
322 | NSSVTSSTTTTSSSSSSSTSN | MARK: 10011110 00000010 (is_wumpus_near:loop_end) | |
323 | SNN | DROP | |
324 | SNN | DROP | |
325 | SSSSN | PUSH 0 | |
326 | NTN | RTS | |
327 | ||
328 | @ Found wumpus. Clean up and return. | |
329 | NSSVTSSTTTTSSSSSSSTTN | MARK: 10011110 00000011 (found_wumpus_one_hop) | |
330 | SNN | DROP | |
331 | NSSVTSSTTTTSSSSSSTSSN | MARK: 10011110 00000100 (found_wumpus_two_hops) | |
332 | SNN | DROP | |
333 | SNN | DROP | |
334 | SSSTN | PUSH 1 | |
335 | NTN | RTS | |
336 | ||
310931d2 AT |
337 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
338 | @ Name: | |
339 | @ seed_rng | |
340 | @ Description: | |
341 | @ Generate seed from keyboard input. | |
342 | @ Call Stack: | |
343 | @ <empty> | |
344 | @ Return Stack: | |
345 | @ <empty> | |
346 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
347 | #include <logic.pvvs> | |
348 | NSSVTSSSSSTTN | MARK: 10000011 (seed_rng) | |
349 | ||
350 | SSSTSSSSN | PUSH 16 (loop counter) | |
351 | SSSSN | PUSH 0 (rng seed) | |
352 | ||
353 | NSSVTSSSSSTTSSSSSSSSN | MARK: 10000011 00000000 (seed_rng:main loop) | |
354 | @ Get character from user and print ASCII '.' as feedback. | |
355 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
356 | TNTS | GETCHAR | |
357 | SSSTSTTTSN | PUSH ASCII '.' | |
358 | TNSS | PUTCHAR | |
359 | @ Left shift the seed by 4 bits. | |
360 | SSSTSSN | PUSH 4 (shift count) | |
361 | NSTTSTTSTN | JSR > 101101 (lshift) | |
362 | @ XOR seed with character from user. | |
363 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
364 | TTT | LOAD | |
365 | NSTTSTSTTN | JSR > 101011 (xor) | |
366 | @ Decrement counter | |
367 | SNT | SWAP | |
368 | SSSTN | PUSH +1 | |
369 | TSST | SUBTRACT | |
370 | @ Test for loop completion | |
371 | SNS | DUP | |
372 | NTSTSSSSSTTSSSSSSSTN | BRZ > 10000011 00000001 (seed_rng:cleanup and return) | |
373 | SNT | SWAP | |
374 | NSNTSSSSSTTSSSSSSSSN | JMP > 10000011 00000000 (seed_rng:main loop) | |
375 | ||
376 | @ Store seed, clean up and return. | |
377 | NSSVTSSSSSTTSSSSSSSTN | MARK: 10000011 00000001 (seed_rng:cleanup and return) | |
378 | SNN | DROP | |
379 | SSSSN | PUSH 0 (seed address) | |
380 | SNT | SWAP | |
381 | TTS | STORE | |
382 | SSSTSTSN | PUSH ASCII '\n' | |
383 | SSSTSTSN | PUSH ASCII '\n' | |
384 | TNSS | PUTCHAR | |
385 | TNSS | PUTCHAR | |
386 | NTN | RTS | |
387 | ||
388 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
389 | @ Name: | |
2d81bb77 | 390 | @ are_rooms_adjacent |
310931d2 | 391 | @ Description: |
2d81bb77 | 392 | @ Checks if 'room_number_1' is adjacent to 'room_number_2'. |
310931d2 | 393 | @ Call Stack: |
2d81bb77 AT |
394 | @ room_number_2 |
395 | @ room_number_1 <-- TOS | |
310931d2 AT |
396 | @ Return Stack: |
397 | @ (1 or 0) for true/false <-- TOS | |
398 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
399 | #include <stack.pvvs> | |
2d81bb77 | 400 | NSSVTSTSSTSSN | MARK: 10100100 (are_rooms_adjacent) |
310931d2 AT |
401 | |
402 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room) | |
403 | TTT | LOAD | |
404 | SSSTN | PUSH +1 | |
405 | TSST | SUBTRACT | |
406 | ||
2d81bb77 AT |
407 | @ TOS> tunnel_index, room_number_1, room_number_2 |
408 | NSSVTSTSSTSSSSSSSSSSN | MARK: 10100100 00000000 (main_loop) | |
409 | SSSTTN | PUSH +3 | |
310931d2 | 410 | NSTTTSSN | JSR > 1100 (deepdup) |
2d81bb77 | 411 | SSSTTN | PUSH +3 |
310931d2 | 412 | NSTTTSSN | JSR > 1100 (deepdup) |
2d81bb77 AT |
413 | SSSTTN | PUSH +3 |
414 | NSTTTSSN | JSR > 1100 (deepdup) | |
415 | SNT | SWAP | |
310931d2 AT |
416 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) |
417 | TSST | SUBTRACT | |
2d81bb77 | 418 | NTSTSTSSTSSSSSSSSSTN | BRZ > 10100100 00000001 (found_tunnel) |
310931d2 AT |
419 | SSSTN | PUSH +1 |
420 | TSST | SUBTRACT | |
421 | SNS | DUP | |
2d81bb77 AT |
422 | NTTTSTSSTSSSSSSSSTSN | BMI > 10100100 00000010 (no_match) |
423 | NSNTSTSSTSSSSSSSSSSN | JMP > 10100100 00000000 (main_loop) | |
310931d2 | 424 | |
2d81bb77 AT |
425 | NSSVTSTSSTSSSSSSSSSTN | MARK: 10100100 00000001 (found_tunnel) |
426 | SNN | DROP | |
310931d2 AT |
427 | SNN | DROP |
428 | SNN | DROP | |
429 | SSSTN | PUSH +1 | |
430 | NTN | RTS | |
431 | ||
2d81bb77 AT |
432 | NSSVTSTSSTSSSSSSSSTSN | MARK: 10100100 00000010 (no_match) |
433 | SNN | DROP | |
310931d2 AT |
434 | SNN | DROP |
435 | SNN | DROP | |
436 | SSSSN | PUSH 0 | |
437 | NTN | RTS | |
438 | ||
439 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
440 | @ Name: | |
441 | @ move_player | |
442 | @ Description: | |
443 | @ Prompts the player for a room number. Moves to that room, checking the new | |
444 | @ environment and executing consequences (fell in a pit, etc) as appropriate. | |
445 | @ Call Stack: | |
446 | @ <empty> | |
447 | @ Return Stack: | |
448 | @ <empty> | |
449 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
450 | #include <stdio.pvvs> | |
451 | #include <convert.pvvs> | |
452 | #include <math.pvvs> | |
453 | #include <string.pvvs> | |
454 | NSSVTSTSSSTTN | MARK: 10100011 (move_player) | |
455 | ||
456 | A"To which room do you wish to move?\n" | |
457 | SSSSN | PUSH 0 (number of string substitutions) | |
458 | NSTTSSSN | JSR > 1000 (printf) | |
459 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) | |
460 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) | |
461 | NSTTSSSTSN | JSR > 100010 (get_user_string) | |
462 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
463 | NSTTTSSSSN | JSR > 110000 (atoi) | |
464 | SNN | DROP | |
465 | ||
466 | @ The desired room number is now on the TOS. Verify that it is valid. | |
467 | SNS | DUP | |
2d81bb77 AT |
468 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location) |
469 | TTT | LOAD | |
470 | NSTTSTSSTSSN | JSR > 10100100 (are_rooms_adjacent) | |
310931d2 AT |
471 | NTSTSTSSSTTSSSSSSSTN | BRZ > 10100011 00000001 (invalid room number) |
472 | NSNTSTSSSTTSSSSSSSSN | JMP > 10100011 00000000 (valid room number) | |
473 | ||
474 | NSSVTSTSSSTTSSSSSSSTN | MARK: 10100011 00000001 (invalid room number) | |
475 | @ TOS> room_number | |
476 | SNN | DROP | |
477 | A"*Oof!* (you hit the wall)\n" | |
478 | SSSSN | PUSH 0 (number of string substitutions) | |
479 | NSTTSSSN | JSR > 1000 (printf) | |
480 | NSTTSSTTN | JSR > 10011 (fastrand) | |
481 | SSSTTSN | PUSH 6 (chance) | |
482 | TSTT | MODULO | |
483 | NTSTSTSSSTTSSSSSSTSN | BRZ > 10100011 00000010 (woke the wumpus) | |
484 | NTN | RTS | |
485 | NSSVTSTSSSTTSSSSSSTSN | MARK: 10100011 00000010 (woke the wumpus) | |
486 | A"Your colorful comments awaken the wumpus!\n" | |
487 | SSSSN | PUSH 0 (number of string substitutions) | |
488 | NSTTSSSN | JSR > 1000 (printf) | |
489 | NSTTSSTTN | JSR > 10011 (fastrand) | |
490 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number of tunnels per room) | |
491 | TSTT | MODULO | |
492 | SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus location) | |
493 | TTT | LOAD | |
494 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
495 | SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus location) | |
496 | SNT | SWAP | |
497 | TTS | STORE | |
498 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) | |
499 | TTT | LOAD | |
500 | NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) | |
501 | NTSTSTSSSTTSSSSSSTTN | BRZ > 10100011 00000011 (wumpus did not move to player) | |
502 | NSTTTTTTTTTSSSSSSSSN | JSR > 11111111 00000000 (wump_kill) | |
503 | SSSSN | PUSH 0 (number of string substitutions) | |
504 | NSTTSSSN | JSR > 1000 (printf) | |
505 | NNN | DIE | |
506 | NSSVTSTSSSTTSSSSSSTTN | MARK: 10100011 00000011 (wumpus did not move to player) | |
507 | NTN | RTS | |
508 | ||
509 | NSSVTSTSSSTTSSSSSSSSN | MARK: 10100011 00000000 (valid room number) | |
510 | @ TOS> room_number | |
511 | @ Move player to new room | |
512 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) | |
513 | SNT | SWAP | |
514 | TTS | STORE | |
515 | @ Check for wumpus in new player location | |
516 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) | |
517 | TTT | LOAD | |
518 | NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) | |
519 | NTSTSTSSSTTSSSSSTSSN | BRZ > 10100011 00000100 (no wumpus in new room) | |
520 | NSTTTTTTTTTSSSSSSSSN | JSR > 11111111 00000000 (wump_kill) | |
521 | SSSSN | PUSH 0 (number of string substitutions) | |
522 | NSTTSSSN | JSR > 1000 (printf) | |
523 | NNN | DIE | |
524 | NSSVTSTSSSTTSSSSSTSSN | MARK: 10100011 00000100 (no wumpus in new room) | |
525 | @ Check for pits in new player location | |
526 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) | |
527 | TTT | LOAD | |
528 | NSTTSSSTTSTN | JSR > 10001101 (room_has_pits) | |
529 | NTSTSTSSSTTSSSSSTSTN | BRZ > 10100011 00000101 (no pits in new room) | |
530 | NSTTSSTTN | JSR > 10011 (fastrand) | |
531 | SSSTTSN | PUSH 6 (chance) | |
532 | TSTT | MODULO | |
533 | NTSTSTSSSTTSSSSSTTSN | BRZ > 10100011 00000110 (survived the pits) | |
534 | NSTTTTTTTTTSSSSSTSTN | JSR > 11111111 00000101 (pit_kill) | |
535 | SSSSN | PUSH 0 (number of string substitutions) | |
536 | NSTTSSSN | JSR > 1000 (printf) | |
537 | NNN | DIE | |
538 | NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (survived the pits) | |
539 | NSTTTTTTTTTSSSSSTTSN | JSR > 11111111 00000110 (pit_survive) | |
540 | SSSSN | PUSH 0 (number of string substitutions) | |
541 | NSTTSSSN | JSR > 1000 (printf) | |
542 | NSSVTSTSSSTTSSSSSTSTN | MARK: 10100011 00000101 (no pits in new room) | |
543 | @ Check for bats in new player location | |
544 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) | |
545 | TTT | LOAD | |
546 | NSTTSSSTTSSN | JSR > 10001100 (room_has_bats) | |
547 | NTSTSTSSSTTSSSSSTTSN | BRZ > 10100011 00000110 (no bats in new room) | |
548 | A"*flap* *flap* *flap* (humongous bats pick you up and move you!)\n" | |
549 | SSSSN | PUSH 0 (number of string substitutions) | |
550 | NSTTSSSN | JSR > 1000 (printf) | |
551 | NSTTSSTTN | JSR > 10011 (fastrand) | |
552 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number of tunnels per room) | |
553 | TSTT | MODULO | |
554 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) | |
555 | TTT | LOAD | |
556 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
557 | NSNTSTSSSTTSSSSSSSSN | JMP > 10100011 00000000 (valid room number) | |
558 | NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (no bats in new room) | |
559 | NTN | RTS | |
560 | ||
2d81bb77 AT |
561 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
562 | @ Name: | |
563 | @ shoot_arrow | |
564 | @ Description: | |
565 | @ Prompt user for list of rooms. Shoots an arrow through each room, checking | |
566 | @ the new environment and executing consequences (fell in a pit, etc) as | |
567 | @ appropriate. | |
568 | @ Call Stack: | |
569 | @ <empty> | |
570 | @ Return Stack: | |
571 | @ <empty> | |
572 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
573 | #include <string.pvvs> | |
574 | #include <stack.pvvs> | |
575 | #include <stdio.pvvs> | |
576 | #include <math.pvvs> | |
577 | #include <wump_strings.pvvs> | |
578 | NSSVTSSTTSSTN | MARK: 10011001 (shoot_arrow) | |
579 | ||
580 | A"Through which rooms do you wish to shoot your arrow?\n(type %u room numbers separated by spaces)\n" | |
581 | SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) | |
582 | TTT | LOAD | |
583 | SSSTN | PUSH 1 (number of string substitutions) | |
584 | NSTTSSSN | JSR > 1000 (printf) | |
585 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) | |
586 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) | |
587 | NSTTSSSTSN | JSR > 100010 (get_user_string) | |
588 | ||
589 | @ Loop, converting one room number from the user string per pass. | |
590 | @ But first, prepare the stack for the loop. | |
591 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
592 | SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) | |
593 | TTT | LOAD | |
594 | @ TOS> loop_counter, ptr_to_user_string | |
595 | NSSVTSSTTSSTSSSSSSSSN | MARK: 10011001 00000000 (process_room_loop) | |
596 | @ Test for end of loop (counter == 0) | |
597 | SNS | DUP | |
598 | NTSTSSTTSSTSSSSSSSTN | BRZ > 10011001 00000001 (end of process_room_loop) | |
599 | @ Now jump forward in the user string to the next ASCII digit (or null term). | |
600 | SNT | SWAP | |
601 | NSSVTSSTTSSTSSSSSSTSN | MARK: 10011001 00000010 (next_ascii_digit_loop) | |
602 | SNS | DUP | |
603 | TTT | LOAD | |
604 | SNS | DUP | |
605 | NSTTSSSSTN | JSR > 100001 (isdigit) | |
606 | NTSTSSTTSSTSSSSSSTTN | BRZ > 10011001 00000011 (ascii_term_test) | |
607 | SNN | DROP | |
608 | NSNTSSTTSSTSSSSSTSSN | JMP > 10011001 00000100 (next_ascii_digit_loop_end) | |
609 | NSSVTSSTTSSTSSSSSSTTN | MARK: 10011001 00000011 (ascii_term_test) | |
610 | NTSTSSTTSSTSSSSSTSSN | BRZ > 10011001 00000100 (next_ascii_digit_loop_end) | |
611 | SSSTN | PUSH 1 | |
612 | TSSS | ADD | |
613 | NSNTSSTTSSTSSSSSSTSN | JMP > 10011001 00000010 (next_ascii_digit_loop) | |
614 | NSSVTSSTTSSTSSSSSTSSN | MARK: 10011001 00000100 (next_ascii_digit_loop_end) | |
615 | @ Call atoi with the newly updated pointer to process another room number. | |
616 | NSTTTSSSSN | JSR > 110000 (atoi) | |
617 | SNT | SWAP | |
618 | SSSTTN | PUSH 3 (rotation_depth) | |
619 | NSTTSTSN | JSR > 1010 (stackrotate) | |
620 | @ Decrement the loop counter and loop again. | |
621 | SNT | SWAP | |
622 | SSSTN | PUSH 1 | |
623 | TSST | SUBTRACT | |
624 | NSNTSSTTSSTSSSSSSSSN | JMP > 10011001 00000000 (process_room_loop) | |
625 | @ Loop is complete. Moving on. | |
626 | NSSVTSSTTSSTSSSSSSSTN | MARK: 10011001 00000001 (end of process_room_loop) | |
627 | SNN | DROP | |
628 | SNN | DROP | |
629 | ||
630 | @ Stack now contains only integers for room numbers (zero padded to full count). | |
631 | @ They are in reverse order, so reverse again. | |
632 | @ Temporarily use the USER_INPUT_BUFFER as a loop counter. | |
633 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
634 | SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) | |
635 | TTT | LOAD | |
636 | TTS | STORE | |
637 | @ Now perform the reversal. | |
638 | NSSVTSSTTSSTSSSSSTSTN | MARK: 10011001 00000101 (reverse_loop) | |
639 | @ First shift the TOS element back to its final location. | |
640 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
641 | TTT | LOAD | |
642 | NSTTSTSN | JSR > 1010 (stackrotate) | |
643 | @ Now decrement the loop counter. | |
644 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
645 | TTT | LOAD | |
646 | SSSTN | PUSH 1 | |
647 | TSST | SUBTRACT | |
648 | @ And check for the end of loop condition (counter < 2) | |
649 | SNS | DUP | |
650 | SSSTN | PUSH 1 | |
651 | TSST | SUBTRACT | |
652 | NTSTSSTTSSTSSSSSTTSN | BRZ > 10011001 00000110 (reverse_loop_end) | |
653 | @ The loop continues. Store the new loop counter and go around again. | |
654 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
655 | SNT | SWAP | |
656 | TTS | STORE | |
657 | NSNTSSTTSSTSSSSSTSTN | JMP > 10011001 00000101 (reverse_loop) | |
658 | @ End of loop. Clean up and continue. | |
659 | NSSVTSSTTSSTSSSSSTTSN | MARK: 10011001 00000110 (reverse_loop_end) | |
660 | SNN | DROP | |
661 | ||
662 | @@@@@ Initialization complete. @@@@@ | |
663 | ||
664 | @ Stack now contains a list room numbers as integers, in order. | |
665 | ||
666 | @ Put a loop index and the starting location of the arrow on the stack. | |
667 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location, now arrow_location) | |
668 | TTT | LOAD | |
669 | SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) | |
670 | TTT | LOAD | |
671 | ||
672 | @ TOS> loop_index, arrow_location, list_of_room_numbers ... | |
673 | @ Move the arrow through a new room for each pass of the loop. | |
674 | NSSVTSSTTSSTSSSSSTTTN | MARK: 10011001 00000111 (arrow_loop) | |
675 | @ Check loop index for end of loop condition (index==0). | |
676 | SNS | DUP | |
677 | NTSTSSTTSSTSSSSTTSTN | BRZ > 10011001 00001101 (loop_end) | |
678 | @ Is the requested room number connected to the arrows current room? | |
679 | SNT | SWAP | |
680 | SNS | DUP | |
681 | SSSTSSN | PUSH 4 | |
682 | NSTTTSSN | JSR > 1100 (deepdup) | |
683 | NSTTSTSSTSSN | JSR > 10100100 (are_rooms_adjacent) | |
684 | NTSTSSTTSSTSSSSTSSSN | BRZ > 10011001 00001000 (not_adjacent) | |
685 | @ Room was adjacent. Print update for user, clean up stack and jump ahead. | |
686 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
687 | SNT | SWAP | |
688 | TTS | STORE | |
689 | SNT | SWAP | |
690 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
691 | SNT | SWAP | |
692 | TTS | STORE | |
693 | A"The arrow sails out of room %u and enters room %u.\n" | |
694 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
695 | TTT | LOAD | |
696 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
697 | TTT | LOAD | |
698 | SSSTSN | PUSH 2 | |
699 | NSTTSSSN | JSR > 1000 (printf) | |
700 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
701 | TTT | LOAD | |
702 | SNT | SWAP | |
703 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
704 | TTT | LOAD | |
705 | SNT | SWAP | |
706 | NSNTSSTTSSTSSSSTSSTN | JMP > 10011001 00001001 (room_is_valid) | |
707 | @ Room was not adjacent. Select a random adjacent room for the arrow. | |
708 | NSSVTSSTTSSTSSSSTSSSN | MARK: 10011001 00001000 (not_adjacent) | |
709 | SSSTTN | PUSH 3 | |
710 | NSTTSTTN | JSR > 1011 (stackrotatereverse) | |
711 | @ TOS> (invalid) room_number, arrow_location, loop_index, rest_of_room_numbers ... | |
712 | @ Start a message to the user. | |
713 | @ First, store two values we will need when printing the user message. | |
714 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
715 | SNT | SWAP | |
716 | TTS | STORE | |
717 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
718 | SNT | SWAP | |
719 | TTS | STORE | |
720 | A"*thunk* The arrow can't find a way from room %u to room %u " | |
721 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
722 | TTT | LOAD | |
723 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
724 | TTT | LOAD | |
725 | SSSTSN | PUSH 2 | |
726 | NSTTSSSN | JSR > 1000 (printf) | |
727 | @ Now locate a random, connected room for the arrow to visit. | |
728 | NSTTSSSSN | JSR > 10000 (random) | |
729 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room) | |
730 | TTT | LOAD | |
731 | TSTT | MODULO | |
732 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
733 | TTT | LOAD | |
734 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
735 | @ Now finish the message to the user. | |
736 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
737 | SNT | SWAP | |
738 | TTS | STORE | |
739 | A"and flys randomly into room %u!\n" | |
740 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
741 | TTT | LOAD | |
742 | SSSTN | PUSH 1 | |
743 | NSTTSSSN | JSR > 1000 (printf) | |
744 | @ And cleanup the stack before continuing onward. | |
745 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 | |
746 | TTT | LOAD | |
747 | SNT | SWAP | |
748 | SSSTTSSSSSSSSSSSTN | PUSH 0x3001 | |
749 | TTT | LOAD | |
750 | SNT | SWAP | |
751 | ||
752 | NSSVTSSTTSSTSSSSTSSTN | MARK: 10011001 00001001 (room_is_valid) | |
753 | @ TOS> loop_index, arrow_location, list_of_room_numbers ... | |
754 | SSSTTN | PUSH 3 | |
755 | NSTTSTSN | JSR > 1010 (stackrotate) | |
756 | SNN | DROP | |
757 | @ TOS> (new) arrow_location, loop_index, (smaller) list_of_room_numbers ... | |
758 | @ Does new room contain a wumpus? | |
759 | SNS | DUP | |
760 | NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) | |
761 | NTSTSSTTSSTSSSSTSTSN | BRZ > 10011001 00001010 (no_wumpus_here) | |
762 | @ Player slew the wumpus! | |
763 | NSTTTTTTTTTSSSSSSSTN | JSR > 11111111 00000001 (kill_wump) | |
764 | SSSSN | PUSH 0 | |
765 | NSTTSSSN | JSR > 1000 (printf) | |
766 | NNN | DIE | |
767 | @ No wumpus here. Does the new room contain the player? | |
768 | NSSVTSSTTSSTSSSSTSTSN | MARK: 10011001 00001010 (no_wumpus_here) | |
769 | SNS | DUP | |
770 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location) | |
771 | TTT | LOAD | |
772 | TSST | SUBTRACT | |
773 | NTSTSSTTSSTSSSSTSTTN | BRZ > 10011001 00001011 (player_shot_self) | |
774 | NSNTSSTTSSTSSSSTTSSN | JMP > 10011001 00001100 (no_events_in_room) | |
775 | NSSVTSSTTSSTSSSSTSTTN | MARK: 10011001 00001011 (player_shot_self) | |
776 | @ Player hit by own arrow! | |
777 | NSTTTTTTTTTSSSSSSTTN | JSR > 11111111 00000011 (shoot_self) | |
778 | SSSSN | PUSH 0 | |
779 | NSTTSSSN | JSR > 1000 (printf) | |
780 | NNN | DIE | |
781 | @ No player here. Update loop index, cleanup stack and loop again. | |
782 | NSSVTSSTTSSTSSSSTTSSN | MARK: 10011001 00001100 (no_events_in_room) | |
783 | SNT | SWAP | |
784 | SSSTN | PUSH 1 | |
785 | TSST | SUBTRACT | |
786 | NSNTSSTTSSTSSSSSTTTN | JMP > 10011001 00000111 (arrow_loop) | |
787 | NSSVTSSTTSSTSSSSTTSTN | MARK: 10011001 00001101 (loop_end) | |
788 | SNN | DROP | |
789 | SNN | DROP | |
790 | A"The arrows wavers in its flight and can go no further!\n" | |
791 | SSSSN | PUSH 0 | |
792 | NSTTSSSN | JSR > 1000 (printf) | |
793 | ||
794 | @ Since the player did not kill the wumpus, there is a chance it will wake and move. | |
795 | NSTTSSSSN | JSR > 10000 (random) | |
796 | SSSTTSN | PUSH 6 | |
797 | TSTT | MODULO | |
798 | NTSTSSTTSSTSSSSTTTSN | BRZ > 10011001 00001110 (move_wumpus) | |
799 | NSNTSSTTSSTSSSTSSSSN | JMP > 10011001 00010000 (wumpus_continues_to_slumber) | |
800 | NSSVTSSTTSSTSSSSTTTSN | MARK: 10011001 00001110 (move_wumpus) | |
801 | @ Move the wumpus to a random connected room. | |
802 | NSTTSSSSN | JSR > 10000 (random) | |
803 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room) | |
804 | TTT | LOAD | |
805 | TSTT | MODULO | |
806 | SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus_location) | |
807 | TTT | LOAD | |
808 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
809 | SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus_location) | |
810 | SNT | SWAP | |
811 | TTS | STORE | |
812 | @ Did the wumpus enter the player room? | |
813 | SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus_location) | |
814 | TTT | LOAD | |
815 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location) | |
816 | TTT | LOAD | |
817 | TSST | SUBTRACT | |
818 | NTSTSSTTSSTSSSSTTTTN | BRZ > 10011001 00001111 (player_death) | |
819 | NSNTSSTTSSTSSSTSSSSN | JMP > 10011001 00010000 (wumpus_continues_to_slumber) | |
820 | NSSVTSSTTSSTSSSSTTTTN | MARK: 10011001 00001111 (player_death) | |
821 | NSTTTTTTTTTSSSSSSSSN | JSR > 11111111 00000000 (wump_kill) | |
822 | SSSSN | PUSH 0 | |
823 | NSTTSSSN | JSR > 1000 (printf) | |
824 | NNN | DIE | |
825 | ||
826 | NSSVTSSTTSSTSSSTSSSSN | MARK: 10011001 00010000 (wumpus_continues_to_slumber) | |
827 | @ Decrement the number of arrows. | |
828 | SSSTSSSSSSSSSTSTN | PUSH 0x1005 (ptr to number_of_arrows) | |
829 | TTT | LOAD | |
830 | SSSTN | PUSH 1 | |
831 | TSST | SUBTRACT | |
832 | SNS | DUP | |
833 | SSSTSSSSSSSSSTSTN | PUSH 0x1005 (ptr to number_of_arrows) | |
834 | SNT | SWAP | |
835 | TTS | STORE | |
836 | @ Check for empty quiver. | |
837 | NTSTSSTTSSTSSSTSSSTN | BRZ > 10011001 00010001 (empty_quiver) | |
838 | NTN | RTS | |
839 | NSSVTSSTTSSTSSSTSSSTN | MARK: 10011001 00010001 (empty_quiver) | |
840 | NSTTTTTTTTTSSSSSSTSN | JSR > 11111111 00000010 (no_arrows) | |
841 | SSSSN | PUSH 0 | |
842 | NSTTSSSN | JSR > 1000 (printf) | |
843 | NNN | DIE | |
844 | ||
310931d2 AT |
845 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
846 | @ Name: | |
847 | @ move_or_shoot | |
848 | @ Description: | |
849 | @ Parse user input, branching to the appropriate subroutine to move or shoot. | |
850 | @ This function does not perform any boundary checks/limits. | |
851 | @ Call Stack: | |
852 | @ <empty> | |
853 | @ Return Stack: | |
854 | @ <empty> | |
855 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
856 | #include <stdio.pvvs> | |
857 | #include <string.pvvs> | |
4db3f7c7 | 858 | #include <wump_strings.pvvs> |
310931d2 AT |
859 | NSSVTSTSSSTSN | MARK: 10100010 (move_or_shoot) |
860 | ||
861 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) | |
862 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) | |
863 | NSTTSSSTSN | JSR > 100010 (get_user_string) | |
864 | ||
865 | @ Examine the first character of the user input buffer for 'm' or 's'. | |
866 | @ If character is something else, prompt user to try again. | |
867 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
868 | TTT | LOAD | |
869 | SSSSTTSTTSTN | PUSH 109 (ASCII 'm') | |
870 | TSST | SUBTRACT | |
871 | NTSTSTSSSTSSSSSSSSSN | BRZ > 10100010 00000000 (move) | |
872 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
873 | TTT | LOAD | |
874 | SSSSTTTSSTTN | PUSH 115 (ASCII 's') | |
875 | TSST | SUBTRACT | |
876 | NTSTSTSSSTSSSSSSSSTN | BRZ > 10100010 00000001 (shoot) | |
877 | NSTTTTTTTTTSSSSTSSSN | JSR > 11111111 00001000 (problem_with_input) | |
878 | SSSSN | PUSH 0 (number of string substitutions) | |
879 | NSTTSSSN | JSR > 1000 (printf) | |
880 | NSNTSTSSSTSN | JMP > 10100010 (move_or_shoot) | |
881 | ||
882 | @ User typed 'm' | |
883 | NSSVTSTSSSTSSSSSSSSSN | MARK: 10100010 00000000 (move) | |
884 | NSTTSTSSSTTN | JSR > 10100011 (move_player) | |
885 | NTN | RTS | |
886 | ||
887 | @ User typed 's' | |
888 | NSSVTSTSSSTSSSSSSSSTN | MARK: 10100010 00000001 (shoot) | |
2d81bb77 | 889 | NSTTSSTTSSTN | JSR > 10011001 (shoot_arrow) |
310931d2 AT |
890 | NTN | RTS |
891 | ||
892 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
893 | @ Name: | |
894 | @ get_answer | |
895 | @ Description: | |
896 | @ Parse user input, returning 0 if user string started with 'n' or 1 if 'y'. | |
897 | @ This function does not perform any boundary checks/limits. | |
898 | @ Call Stack: | |
899 | @ <empty> | |
900 | @ Return Stack: | |
901 | @ (1 or 0 for True/False) <--- TOS | |
902 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
903 | #include <stdio.pvvs> | |
904 | #include <string.pvvs> | |
c23ef97b | 905 | #include <wump_strings.pvvs> |
310931d2 AT |
906 | NSSVTSSTTSSSN | MARK: 10011000 (get_answer) |
907 | ||
908 | @ TODO: Consider extending the GETCHAR instruction in VVS to indicate an empty | |
909 | @ buffer instead of blocking. This would allow a character by character | |
910 | @ check without printing a slew of retry messages if the buffer is | |
911 | @ non-empty. | |
912 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) | |
913 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) | |
914 | NSTTSSSTSN | JSR > 100010 (get_user_string) | |
915 | ||
916 | @ Examine the first character of the user input buffer for 'y' or 'n'. | |
917 | @ If character is something else, prompt user to try again. | |
918 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
919 | TTT | LOAD | |
920 | SSSSTTTTSSTN | PUSH 121 (ASCII 'y') | |
921 | TSST | SUBTRACT | |
922 | NTSTSSTTSSSSSSSSSSSN | BRZ > 10011000 00000000 (answer: yes) | |
923 | SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) | |
924 | TTT | LOAD | |
925 | SSSSTTSTTTSN | PUSH 110 (ASCII 'n') | |
926 | TSST | SUBTRACT | |
927 | NTSTSSTTSSSSSSSSSSTN | BRZ > 10011000 00000001 (answer: no) | |
928 | NSTTTTTTTTTSSSSTSSSN | JSR > 11111111 00001000 (problem_with_input) | |
929 | SSSSN | PUSH 0 (number of string substitutions) | |
930 | NSTTSSSN | JSR > 1000 (printf) | |
931 | NSNTSSTTSSSN | JMP > 10011000 (get_answer) | |
932 | ||
933 | @ User typed 'y' | |
934 | NSSVTSSTTSSSSSSSSSSSN | MARK: 10011000 00000000 (answer: yes) | |
935 | SSSTN | PUSH 1 | |
936 | NTN | RTS | |
937 | ||
938 | @ User typed 'n' | |
939 | NSSVTSSTTSSSSSSSSSSTN | MARK: 10011000 00000001 (answer: no) | |
940 | SSSSN | PUSH 0 | |
941 | NTN | RTS | |
942 | ||
943 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
944 | @ Name: | |
945 | @ print_cave_description | |
946 | @ Description: | |
947 | @ Prints information about the cave (number of rooms, etc). | |
948 | @ Call Stack: | |
949 | @ <empty> | |
950 | @ Return Stack: | |
951 | @ <empty> | |
952 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
953 | #include <stdio.pvvs> | |
c23ef97b | 954 | #include <wump_strings.pvvs> |
310931d2 AT |
955 | NSSVTSSTTSTTN | MARK: 10011011 (print_cave_description) |
956 | NSTTTTTTTTTSSSSTSTSN | JSR > 11111111 00001010 (cave_description) | |
957 | SSSTSSSSSSSSSTSTN | PUSH 0x1005 (number_of_arrows address) | |
958 | TTT | LOAD | |
959 | SSSTSSSSSSSSSSSTN | PUSH 0x1001 (number_of_pits address) | |
960 | TTT | LOAD | |
961 | SSSTSSSSSSSSSSTSN | PUSH 0x1002 (number_of_bats address) | |
962 | TTT | LOAD | |
963 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_tunnels address) | |
964 | TTT | LOAD | |
965 | SSSTSSSSSSSSSSSSN | PUSH 0x1000 (number_of_rooms address) | |
966 | TTT | LOAD | |
967 | SSSTSTN | PUSH 5 (number of substitions) | |
968 | NSTTSSSN | JSR > 1000 (printf) | |
969 | NTN | RTS | |
970 | ||
971 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
972 | @ Name: | |
973 | @ print_room_stats | |
974 | @ Description: | |
975 | @ Prints information about current room and hints about nearby rooms. | |
976 | @ Call Stack: | |
977 | @ <empty> | |
978 | @ Return Stack: | |
979 | @ <empty> | |
980 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
310931d2 AT |
981 | #include <stdio.pvvs> |
982 | #include <stack.pvvs> | |
983 | NSSVTSTSSSSTN | MARK: 10100001 (print_room_stats) | |
984 | ||
985 | @ Print location and arrow quantity remaining. | |
2d81bb77 | 986 | A"\n----------\n\nYou are in room %u of the cave and have %u arrows remaining.\n" |
310931d2 AT |
987 | SSSTSSSSSSSSSTSTN | PUSH 0x1005 (number_of_arrows address) |
988 | TTT | LOAD | |
989 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address) | |
990 | TTT | LOAD | |
991 | SSSTSN | PUSH 2 (number of substitutions) | |
992 | NSTTSSSN | JSR > 1000 (printf) | |
993 | ||
994 | @ Print if bats/pits/wumpus nearby. | |
995 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address) | |
996 | TTT | LOAD | |
997 | SNS | DUP | |
998 | NSTTSSTTTSSN | JSR > 10011100 (are_bats_near) | |
999 | NTSTSTSSSSTSSSSSSSSN | BRZ > 10100001 00000000 (no_bats) | |
1000 | A"*rustle* (Bats must be nearby.)\n" | |
1001 | SSSSN | PUSH 0 (number of substitutions) | |
1002 | NSTTSSSN | JSR > 1000 (printf) | |
1003 | NSSVTSTSSSSTSSSSSSSSN | MARK: 10100001 00000000 (no_bats) | |
1004 | SNS | DUP | |
1005 | NSTTSSTTTSTN | JSR > 10011101 (are_pits_near) | |
1006 | NTSTSTSSSSTSSSSSSSTN | BRZ > 10100001 00000001 (no_pits) | |
1007 | A"*whoosh* (You feel a draft from nearby pits.)\n" | |
1008 | SSSSN | PUSH 0 (number of substitutions) | |
1009 | NSTTSSSN | JSR > 1000 (printf) | |
1010 | NSSVTSTSSSSTSSSSSSSTN | MARK: 10100001 00000001 (no_pits) | |
1011 | NSTTSSTTTTSN | JSR > 10011110 (is_wumpus_near) | |
1012 | NTSTSTSSSSTSSSSSSTSN | BRZ > 10100001 00000010 (no_wumpus) | |
1013 | A"*sniff* (You smell the evil Wumpus nearby!)\n" | |
1014 | SSSSN | PUSH 0 (number of substitutions) | |
1015 | NSTTSSSN | JSR > 1000 (printf) | |
1016 | NSSVTSTSSSSTSSSSSSTSN | MARK: 10100001 00000010 (no_wumpus) | |
1017 | ||
1018 | @ Print a list of nearby rooms. | |
1019 | A"This room contains tunnels to the following rooms:" | |
1020 | SSSSN | PUSH 0 (number of substitutions) | |
1021 | NSTTSSSN | JSR > 1000 (printf) | |
1022 | SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address) | |
1023 | TTT | LOAD | |
1024 | SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) | |
1025 | TTT | LOAD | |
1026 | SSSTN | PUSH 1 | |
1027 | TSST | SUBTRACT | |
1028 | @ Print one room on each pass through this loop. | |
1029 | @ TOS> tunnel_index, room_number | |
1030 | NSSVTSTSSSSTSSSSSSTTN | MARK: 10100001 00000011 (print_room_list_loop) | |
1031 | A" %u" | |
1032 | SSSTSTN | PUSH 5 | |
1033 | NSTTTSSN | JSR > 1100 (deepdup) | |
1034 | SSSTTTN | PUSH 7 | |
1035 | NSTTTSSN | JSR > 1100 (deepdup) | |
1036 | NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) | |
1037 | SSSTN | PUSH 1 (number of substitutions) | |
1038 | NSTTSSSN | JSR > 1000 (printf) | |
1039 | @ Test for end of loop | |
1040 | SNS | DUP | |
1041 | NTSTSTSSSSTSSSSSTSSN | BRZ > 10100001 00000100 (print_room_list_loop_end) | |
1042 | SSSTN | PUSH 1 | |
1043 | TSST | SUBTRACT | |
1044 | NSNTSTSSSSTSSSSSSTTN | JMP > 10100001 00000011 (print_room_list_loop) | |
1045 | @ Clean up and return. | |
1046 | NSSVTSTSSSSTSSSSSTSSN | MARK: 10100001 00000100 (print_room_list_loop_end) | |
1047 | SSSTSTSN | PUSH 10 (ASCII '\n') | |
1048 | TNSS | PUTCHAR | |
1049 | SNN | DROP | |
1050 | SNN | DROP | |
1051 | NTN | RTS | |
1052 | ||
2da74194 | 1053 | #endif |