#ifndef WUMP_GAME #define WUMP_GAME @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ (c) 2019 Aaron Taylor @ See LICENSE.txt file for copyright and license details. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ get_tunnel_destination @ Description: @ Returns the room number corresponding to the destination of a tunnel @ specified by room and slot. @ Call Stack: @ slot @ room_number <-- TOS @ Return Stack: @ dst_room_number <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSSSTSSSN | MARK: 10001000 (get_tunnel_destination) @ The pointer we seek is: @ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE @ Where the '+2' accounts for the pit and bat booleans. NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size) TSSN | MULTIPLY SSSTSN | PUSH +2 TSSS | ADD TSSS | ADD SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (ROOM_DATA_BASE address) TSSS | ADD TTT | LOAD NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ get_room_struct_size @ Description: @ Returns the size in words of the data structure for a single room. @ For example, with 3 links plus bat and pit booleans, the size is 5 words. @ Call Stack: @ @ Return Stack: @ size <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSSSTSTTN | MARK: 10001011 (get_room_struct_size) SSSTSSSSSSSSSSTTN | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address) TTT | LOAD SSSTSN | PUSH +2 TSSS | ADD NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ room_has_bats @ Description: @ Check if room_number contains bats. @ Returns 1 or 0 representing true or false. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSSSTTSSN | MARK: 10001100 (room_has_bats) @ We seek the pointer: @ (room_number * room_struct_size) + 1 + ROOM_DATA_BASE @ where '+1' accounts for the offset of the bat boolean in the desired room. NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size) TSSN | MULTIPLY SSSTN | PUSH +1 TSSS | ADD SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (GAME_DATA_BASE address) TSSS | ADD TTT | LOAD NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ room_has_pits @ Description: @ Check if room_number contains pits. @ Returns 1 or 0 representing true or false. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSSSTTSTN | MARK: 10001101 (room_has_pits) @ We seek the pointer: @ (room_number * room_struct_size) + 0 + ROOM_DATA_BASE @ where '+0' accounts for the offset of the pit boolean in the desired room. NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size) TSSN | MULTIPLY SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (GAME_DATA_BASE address) TSSS | ADD TTT | LOAD NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ room_has_wumpus @ Description: @ Check if room contains wumpus. @ Returns 1 or 0 representing true or false. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSTSSSSSN | MARK: 10100000 (room_has_wumpus) SSSTSSSSSSSSSTTTN | PUSH 0x1007 (wumpus_location address) TTT | LOAD TSST | SUBTRACT NTSTSTSSSSSSSSSSSSSN | BRZ > 10100000 00000000 (room_has_wumpus:true) SSSSN | PUSH 0 (false) NTN | RTS NSSVTSTSSSSSSSSSSSSSN | MARK: 10100000 00000000 (room_has_wumpus:true) SSSTN | PUSH 1 (true) NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ are_bats_near @ Description: @ Given a room number, checks rooms within one hop for bats. @ Returns 1 if bats are present or 0 if no bats. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include NSSVTSSTTTSSN | MARK: 10011100 (are_bats_near) @ Prepare the stack by loading the number of links per room and decrementing. @ We will loop until this reaches 0 or we find bats. SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT @ Check one nearby room on each pass through this loop. @ TOS> tunnel_index, room_number NSSVTSSTTTSSSSSSSSSSN | MARK: 10011100 00000000 (are_bats_near:loop) SNS | DUP SSSTTN | PUSH 3 NSTTTSSN | JSR > 1100 (deepdup) NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) NSTTSSSTTSSN | JSR > 10001100 (room_has_bats) NTSTSSTTTSSSSSSSSSTN | BRZ > 10011100 00000001 (no_bats_in_this_room) @ Found bats. Clean up and return. SNN | DROP SNN | DROP SSSTN | PUSH 1 NTN | RTS NSSVTSSTTTSSSSSSSSSTN | MARK: 10011100 00000001 (no_bats_in_this_room) @ Test for end of loop. SNS | DUP NTSTSSTTTSSSSSSSSTSN | BRZ > 10011100 00000010 (are_bats_near:loop_end) @ No bats found yet, but still need to check some rooms. @ Decrement tunnel index and loop again. SSSTN | PUSH 1 TSST | SUBTRACT NSNTSSTTTSSSSSSSSSSN | JMP > 10011100 00000000 (are_bats_near:loop) @ No bats found in nearby rooms. Clean up and return. NSSVTSSTTTSSSSSSSSTSN | MARK: 10011100 00000010 (are_bats_near:loop_end) SNN | DROP SNN | DROP SSSSN | PUSH 0 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ are_pits_near @ Description: @ Given a room number, checks rooms within one hop for pits. @ Returns 1 if pits are present or 0 if no pits. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include NSSVTSSTTTSTN | MARK: 10011101 (are_pits_near) @ Prepare the stack by loading the number of links per room and decrementing. @ We will loop until this reaches 0 or we find pits. SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT @ Check one nearby room on each pass through this loop. @ TOS> tunnel_index, room_number NSSVTSSTTTSTSSSSSSSSN | MARK: 10011101 00000000 (are_pits_near:loop) SNS | DUP SSSTTN | PUSH 3 NSTTTSSN | JSR > 1100 (deepdup) NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) NSTTSSSTTSTN | JSR > 10001101 (room_has_pits) NTSTSSTTTSTSSSSSSSTN | BRZ > 10011101 00000001 (no_pits_in_this_room) @ Found pits. Clean up and return. SNN | DROP SNN | DROP SSSTN | PUSH 1 NTN | RTS NSSVTSSTTTSTSSSSSSSTN | MARK: 10011101 00000001 (no_pits_in_this_room) @ Test for end of loop. SNS | DUP NTSTSSTTTSTSSSSSSTSN | BRZ > 10011101 00000010 (are_pits_near:loop_end) @ No pits found yet, but still need to check some rooms. @ Decrement tunnel index and loop again. SSSTN | PUSH 1 TSST | SUBTRACT NSNTSSTTTSTSSSSSSSSN | JMP > 10011101 00000000 (are_pits_near:loop) @ No pits found in nearby rooms. Clean up and return. NSSVTSSTTTSTSSSSSSTSN | MARK: 10011101 00000010 (are_pits_near:loop_end) SNN | DROP SNN | DROP SSSSN | PUSH 0 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ is_wumpus_very_near @ Description: @ Given a room number, checks rooms within one hop for the wumpus. @ Returns 1 if wumpus is present, otherwise 0. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include NSSVTSSTTTTTN | MARK: 10011111 (is_wumpus_very_near) @ Prepare the stack by loading the number of links per room and decrementing. @ We will loop until this reaches 0 or we find the wumpus. SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT @ Check one nearby room on each pass through this loop. @ TOS> tunnel_index, room_number NSSVTSSTTTTTSSSSSSSSN | MARK: 10011111 00000000 (is_wumpus_very_near:loop) SNS | DUP SSSTTN | PUSH 3 NSTTTSSN | JSR > 1100 (deepdup) NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) NTSTSSTTTTTSSSSSSSTN | BRZ > 10011111 00000001 (no_wumpus_in_this_room) @ Found wumpus. Clean up and return. SNN | DROP SNN | DROP SSSTN | PUSH 1 NTN | RTS NSSVTSSTTTTTSSSSSSSTN | MARK: 10011111 00000001 (no_wumpus_in_this_room) @ Test for end of loop. SNS | DUP NTSTSSTTTTTSSSSSSTSN | BRZ > 10011111 00000010 (is_wumpus_very_near:loop_end) @ No wumpus found yet, but still need to check some rooms. @ Decrement tunnel index and loop again. SSSTN | PUSH 1 TSST | SUBTRACT NSNTSSTTTTTSSSSSSSSN | JMP > 10011111 00000000 (is_wumpus_very_near:loop) @ No wumpus found in nearby rooms. Clean up and return. NSSVTSSTTTTTSSSSSSTSN | MARK: 10011111 00000010 (is_wumpus_very_near:loop_end) SNN | DROP SNN | DROP SSSSN | PUSH 0 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ is_wumpus_near @ Description: @ Given a room number, checks rooms within two hops for the wumpus. @ Returns 1 if wumpus is present, otherwise 0. @ Call Stack: @ room_number <-- TOS @ Return Stack: @ 1 or 0 <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include NSSVTSSTTTTSN | MARK: 10011110 (is_wumpus_near) @ Prepare the stack by loading the number of links per room and decrementing. @ We will loop until this reaches 0 or we find the wumpus. SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT @ Check one nearby room and its connecting rooms on each pass through this loop. @ TOS> tunnel_index, room_number NSSVTSSTTTTSSSSSSSSSN | MARK: 10011110 00000000 (is_wumpus_near:loop) SNS | DUP SSSTTN | PUSH 3 NSTTTSSN | JSR > 1100 (deepdup) NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) @ TOS> tunnel_endpoint, tunnel_index, room_number SNS | DUP NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) SSSTN | PUSH 1 TSST | SUBTRACT NTSTSSTTTTSSSSSSSTTN | BRZ > 10011110 00000011 (found_wumpus_one_hop) NSTTSSTTTTTN | JSR > 10011111 (is_wumpus_very_near) SSSTN | PUSH 1 TSST | SUBTRACT NTSTSSTTTTSSSSSSTSSN | BRZ > 10011110 00000100 (found_wumpus_two_hops) @ Test for end of loop. SNS | DUP NTSTSSTTTTSSSSSSSTSN | BRZ > 10011110 00000010 (is_wumpus_near:loop_end) @ No wumpus found yet, but still need to check some rooms. @ Decrement tunnel index and loop again. SSSTN | PUSH 1 TSST | SUBTRACT NSNTSSTTTTSSSSSSSSSN | JMP > 10011110 00000000 (is_wumpus_near:loop) @ No wumpus found in nearby rooms. Clean up and return. NSSVTSSTTTTSSSSSSSTSN | MARK: 10011110 00000010 (is_wumpus_near:loop_end) SNN | DROP SNN | DROP SSSSN | PUSH 0 NTN | RTS @ Found wumpus. Clean up and return. NSSVTSSTTTTSSSSSSSTTN | MARK: 10011110 00000011 (found_wumpus_one_hop) SNN | DROP NSSVTSSTTTTSSSSSSTSSN | MARK: 10011110 00000100 (found_wumpus_two_hops) SNN | DROP SNN | DROP SSSTN | PUSH 1 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ seed_rng @ Description: @ Generate seed from keyboard input. @ Call Stack: @ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include NSSVTSSSSSTTN | MARK: 10000011 (seed_rng) SSSTSSSSN | PUSH 16 (loop counter) SSSSN | PUSH 0 (rng seed) NSSVTSSSSSTTSSSSSSSSN | MARK: 10000011 00000000 (seed_rng:main loop) @ Get character from user and print ASCII '.' as feedback. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) TNTS | GETCHAR SSSTSTTTSN | PUSH ASCII '.' TNSS | PUTCHAR @ Left shift the seed by 4 bits. SSSTSSN | PUSH 4 (shift count) NSTTSTTSTN | JSR > 101101 (lshift) @ XOR seed with character from user. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) TTT | LOAD NSTTSTSTTN | JSR > 101011 (xor) @ Decrement counter SNT | SWAP SSSTN | PUSH +1 TSST | SUBTRACT @ Test for loop completion SNS | DUP NTSTSSSSSTTSSSSSSSTN | BRZ > 10000011 00000001 (seed_rng:cleanup and return) SNT | SWAP NSNTSSSSSTTSSSSSSSSN | JMP > 10000011 00000000 (seed_rng:main loop) @ Store seed, clean up and return. NSSVTSSSSSTTSSSSSSSTN | MARK: 10000011 00000001 (seed_rng:cleanup and return) SNN | DROP SSSSN | PUSH 0 (seed address) SNT | SWAP TTS | STORE SSSTSTSN | PUSH ASCII '\n' SSSTSTSN | PUSH ASCII '\n' TNSS | PUTCHAR TNSS | PUTCHAR NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ are_rooms_adjacent @ Description: @ Checks if 'room_number_1' is adjacent to 'room_number_2'. @ Call Stack: @ room_number_2 @ room_number_1 <-- TOS @ Return Stack: @ (1 or 0) for true/false <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include NSSVTSTSSTSSN | MARK: 10100100 (are_rooms_adjacent) SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room) TTT | LOAD SSSTN | PUSH +1 TSST | SUBTRACT @ TOS> tunnel_index, room_number_1, room_number_2 NSSVTSTSSTSSSSSSSSSSN | MARK: 10100100 00000000 (main_loop) SSSTTN | PUSH +3 NSTTTSSN | JSR > 1100 (deepdup) SSSTTN | PUSH +3 NSTTTSSN | JSR > 1100 (deepdup) SSSTTN | PUSH +3 NSTTTSSN | JSR > 1100 (deepdup) SNT | SWAP NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) TSST | SUBTRACT NTSTSTSSTSSSSSSSSSTN | BRZ > 10100100 00000001 (found_tunnel) SSSTN | PUSH +1 TSST | SUBTRACT SNS | DUP NTTTSTSSTSSSSSSSSTSN | BMI > 10100100 00000010 (no_match) NSNTSTSSTSSSSSSSSSSN | JMP > 10100100 00000000 (main_loop) NSSVTSTSSTSSSSSSSSSTN | MARK: 10100100 00000001 (found_tunnel) SNN | DROP SNN | DROP SNN | DROP SSSTN | PUSH +1 NTN | RTS NSSVTSTSSTSSSSSSSSTSN | MARK: 10100100 00000010 (no_match) SNN | DROP SNN | DROP SNN | DROP SSSSN | PUSH 0 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ move_player @ Description: @ Prompts the player for a room number. Moves to that room, checking the new @ environment and executing consequences (fell in a pit, etc) as appropriate. @ Call Stack: @ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include #include #include NSSVTSTSSSTTN | MARK: 10100011 (move_player) A"To which room do you wish to move?\n" SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) NSTTSSSTSN | JSR > 100010 (get_user_string) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) NSTTTSSSSN | JSR > 110000 (atoi) SNN | DROP @ The desired room number is now on the TOS. Verify that it is valid. SNS | DUP SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location) TTT | LOAD NSTTSTSSTSSN | JSR > 10100100 (are_rooms_adjacent) NTSTSTSSSTTSSSSSSSTN | BRZ > 10100011 00000001 (invalid room number) NSNTSTSSSTTSSSSSSSSN | JMP > 10100011 00000000 (valid room number) NSSVTSTSSSTTSSSSSSSTN | MARK: 10100011 00000001 (invalid room number) @ TOS> room_number SNN | DROP A"*Oof!* (you hit the wall)\n" SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NSTTSSTTN | JSR > 10011 (fastrand) SSSTTSN | PUSH 6 (chance) TSTT | MODULO NTSTSTSSSTTSSSSSSTSN | BRZ > 10100011 00000010 (woke the wumpus) NTN | RTS NSSVTSTSSSTTSSSSSSTSN | MARK: 10100011 00000010 (woke the wumpus) A"Your colorful comments awaken the wumpus!\n" SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NSTTSSTTN | JSR > 10011 (fastrand) SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number of tunnels per room) TSTT | MODULO SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus location) TTT | LOAD NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus location) SNT | SWAP TTS | STORE SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) TTT | LOAD NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) NTSTSTSSSTTSSSSSSTTN | BRZ > 10100011 00000011 (wumpus did not move to player) NSTTTTTTTTTSSSSSSSSN | JSR > 11111111 00000000 (wump_kill) SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NNN | DIE NSSVTSTSSSTTSSSSSSTTN | MARK: 10100011 00000011 (wumpus did not move to player) NTN | RTS NSSVTSTSSSTTSSSSSSSSN | MARK: 10100011 00000000 (valid room number) @ TOS> room_number @ Move player to new room SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) SNT | SWAP TTS | STORE @ Check for wumpus in new player location SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) TTT | LOAD NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) NTSTSTSSSTTSSSSSTSSN | BRZ > 10100011 00000100 (no wumpus in new room) NSTTTTTTTTTSSSSSSSSN | JSR > 11111111 00000000 (wump_kill) SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NNN | DIE NSSVTSTSSSTTSSSSSTSSN | MARK: 10100011 00000100 (no wumpus in new room) @ Check for pits in new player location SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) TTT | LOAD NSTTSSSTTSTN | JSR > 10001101 (room_has_pits) NTSTSTSSSTTSSSSSTSTN | BRZ > 10100011 00000101 (no pits in new room) NSTTSSTTN | JSR > 10011 (fastrand) SSSTTSN | PUSH 6 (chance) TSTT | MODULO NTSTSTSSSTTSSSSSTTSN | BRZ > 10100011 00000110 (survived the pits) NSTTTTTTTTTSSSSSTSTN | JSR > 11111111 00000101 (pit_kill) SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NNN | DIE NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (survived the pits) NSTTTTTTTTTSSSSSTTSN | JSR > 11111111 00000110 (pit_survive) SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NSSVTSTSSSTTSSSSSTSTN | MARK: 10100011 00000101 (no pits in new room) @ Check for bats in new player location SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) TTT | LOAD NSTTSSSTTSSN | JSR > 10001100 (room_has_bats) NTSTSTSSSTTSSSSSTTSN | BRZ > 10100011 00000110 (no bats in new room) A"*flap* *flap* *flap* (humongous bats pick you up and move you!)\n" SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NSTTSSTTN | JSR > 10011 (fastrand) SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number of tunnels per room) TSTT | MODULO SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location) TTT | LOAD NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) NSNTSTSSSTTSSSSSSSSN | JMP > 10100011 00000000 (valid room number) NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (no bats in new room) NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ shoot_arrow @ Description: @ Prompt user for list of rooms. Shoots an arrow through each room, checking @ the new environment and executing consequences (fell in a pit, etc) as @ appropriate. @ Call Stack: @ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include #include #include #include NSSVTSSTTSSTN | MARK: 10011001 (shoot_arrow) A"Through which rooms do you wish to shoot your arrow?\n(type %u room numbers separated by spaces)\n" SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) TTT | LOAD SSSTN | PUSH 1 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) NSTTSSSTSN | JSR > 100010 (get_user_string) @ Loop, converting one room number from the user string per pass. @ But first, prepare the stack for the loop. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) TTT | LOAD @ TOS> loop_counter, ptr_to_user_string NSSVTSSTTSSTSSSSSSSSN | MARK: 10011001 00000000 (process_room_loop) @ Test for end of loop (counter == 0) SNS | DUP NTSTSSTTSSTSSSSSSSTN | BRZ > 10011001 00000001 (end of process_room_loop) @ Now jump forward in the user string to the next ASCII digit (or null term). SNT | SWAP NSSVTSSTTSSTSSSSSSTSN | MARK: 10011001 00000010 (next_ascii_digit_loop) SNS | DUP TTT | LOAD SNS | DUP NSTTSSSSTN | JSR > 100001 (isdigit) NTSTSSTTSSTSSSSSSTTN | BRZ > 10011001 00000011 (ascii_term_test) SNN | DROP NSNTSSTTSSTSSSSSTSSN | JMP > 10011001 00000100 (next_ascii_digit_loop_end) NSSVTSSTTSSTSSSSSSTTN | MARK: 10011001 00000011 (ascii_term_test) NTSTSSTTSSTSSSSSTSSN | BRZ > 10011001 00000100 (next_ascii_digit_loop_end) SSSTN | PUSH 1 TSSS | ADD NSNTSSTTSSTSSSSSSTSN | JMP > 10011001 00000010 (next_ascii_digit_loop) NSSVTSSTTSSTSSSSSTSSN | MARK: 10011001 00000100 (next_ascii_digit_loop_end) @ Call atoi with the newly updated pointer to process another room number. NSTTTSSSSN | JSR > 110000 (atoi) SNT | SWAP SSSTTN | PUSH 3 (rotation_depth) NSTTSTSN | JSR > 1010 (stackrotate) @ Decrement the loop counter and loop again. SNT | SWAP SSSTN | PUSH 1 TSST | SUBTRACT NSNTSSTTSSTSSSSSSSSN | JMP > 10011001 00000000 (process_room_loop) @ Loop is complete. Moving on. NSSVTSSTTSSTSSSSSSSTN | MARK: 10011001 00000001 (end of process_room_loop) SNN | DROP SNN | DROP @ Stack now contains only integers for room numbers (zero padded to full count). @ They are in reverse order, so reverse again. @ Temporarily use the USER_INPUT_BUFFER as a loop counter. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) TTT | LOAD TTS | STORE @ Now perform the reversal. NSSVTSSTTSSTSSSSSTSTN | MARK: 10011001 00000101 (reverse_loop) @ First shift the TOS element back to its final location. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD NSTTSTSN | JSR > 1010 (stackrotate) @ Now decrement the loop counter. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT @ And check for the end of loop condition (counter < 2) SNS | DUP SSSTN | PUSH 1 TSST | SUBTRACT NTSTSSTTSSTSSSSSTTSN | BRZ > 10011001 00000110 (reverse_loop_end) @ The loop continues. Store the new loop counter and go around again. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 SNT | SWAP TTS | STORE NSNTSSTTSSTSSSSSTSTN | JMP > 10011001 00000101 (reverse_loop) @ End of loop. Clean up and continue. NSSVTSSTTSSTSSSSSTTSN | MARK: 10011001 00000110 (reverse_loop_end) SNN | DROP @@@@@ Initialization complete. @@@@@ @ Stack now contains a list room numbers as integers, in order. @ Put a loop index and the starting location of the arrow on the stack. SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location, now arrow_location) TTT | LOAD SSSTSSSSSSSSSTSSN | PUSH 0x1004 (ptr to max_arrow_flight_distance) TTT | LOAD @ TOS> loop_index, arrow_location, list_of_room_numbers ... @ Move the arrow through a new room for each pass of the loop. NSSVTSSTTSSTSSSSSTTTN | MARK: 10011001 00000111 (arrow_loop) @ Check loop index for end of loop condition (index==0). SNS | DUP NTSTSSTTSSTSSSSTTSTN | BRZ > 10011001 00001101 (loop_end) @ Is the requested room number connected to the arrows current room? SNT | SWAP SNS | DUP SSSTSSN | PUSH 4 NSTTTSSN | JSR > 1100 (deepdup) NSTTSTSSTSSN | JSR > 10100100 (are_rooms_adjacent) NTSTSSTTSSTSSSSTSSSN | BRZ > 10011001 00001000 (not_adjacent) @ Room was adjacent. Print update for user, clean up stack and jump ahead. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 SNT | SWAP TTS | STORE SNT | SWAP SSSTTSSSSSSSSSSSTN | PUSH 0x3001 SNT | SWAP TTS | STORE A"The arrow sails out of room %u and enters room %u.\n" SSSTTSSSSSSSSSSSTN | PUSH 0x3001 TTT | LOAD SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD SSSTSN | PUSH 2 NSTTSSSN | JSR > 1000 (printf) SSSTTSSSSSSSSSSSTN | PUSH 0x3001 TTT | LOAD SNT | SWAP SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD SNT | SWAP NSNTSSTTSSTSSSSTSSTN | JMP > 10011001 00001001 (room_is_valid) @ Room was not adjacent. Select a random adjacent room for the arrow. NSSVTSSTTSSTSSSSTSSSN | MARK: 10011001 00001000 (not_adjacent) SSSTTN | PUSH 3 NSTTSTTN | JSR > 1011 (stackrotatereverse) @ TOS> (invalid) room_number, arrow_location, loop_index, rest_of_room_numbers ... @ Start a message to the user. @ First, store two values we will need when printing the user message. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 SNT | SWAP TTS | STORE SSSTTSSSSSSSSSSSTN | PUSH 0x3001 SNT | SWAP TTS | STORE A"*thunk* The arrow can't find a way from room %u to room %u " SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD SSSTTSSSSSSSSSSSTN | PUSH 0x3001 TTT | LOAD SSSTSN | PUSH 2 NSTTSSSN | JSR > 1000 (printf) @ Now locate a random, connected room for the arrow to visit. NSTTSSSSN | JSR > 10000 (random) SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room) TTT | LOAD TSTT | MODULO SSSTTSSSSSSSSSSSTN | PUSH 0x3001 TTT | LOAD NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) @ Now finish the message to the user. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 SNT | SWAP TTS | STORE A"and flys randomly into room %u!\n" SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD SSSTN | PUSH 1 NSTTSSSN | JSR > 1000 (printf) @ And cleanup the stack before continuing onward. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 TTT | LOAD SNT | SWAP SSSTTSSSSSSSSSSSTN | PUSH 0x3001 TTT | LOAD SNT | SWAP NSSVTSSTTSSTSSSSTSSTN | MARK: 10011001 00001001 (room_is_valid) @ TOS> loop_index, arrow_location, list_of_room_numbers ... SSSTTN | PUSH 3 NSTTSTSN | JSR > 1010 (stackrotate) SNN | DROP @ TOS> (new) arrow_location, loop_index, (smaller) list_of_room_numbers ... @ Does new room contain a wumpus? SNS | DUP NSTTSTSSSSSN | JSR > 10100000 (room_has_wumpus) NTSTSSTTSSTSSSSTSTSN | BRZ > 10011001 00001010 (no_wumpus_here) @ Player slew the wumpus! NSTTTTTTTTTSSSSSSSTN | JSR > 11111111 00000001 (kill_wump) SSSSN | PUSH 0 NSTTSSSN | JSR > 1000 (printf) NNN | DIE @ No wumpus here. Does the new room contain the player? NSSVTSSTTSSTSSSSTSTSN | MARK: 10011001 00001010 (no_wumpus_here) SNS | DUP SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location) TTT | LOAD TSST | SUBTRACT NTSTSSTTSSTSSSSTSTTN | BRZ > 10011001 00001011 (player_shot_self) NSNTSSTTSSTSSSSTTSSN | JMP > 10011001 00001100 (no_events_in_room) NSSVTSSTTSSTSSSSTSTTN | MARK: 10011001 00001011 (player_shot_self) @ Player hit by own arrow! NSTTTTTTTTTSSSSSSTTN | JSR > 11111111 00000011 (shoot_self) SSSSN | PUSH 0 NSTTSSSN | JSR > 1000 (printf) NNN | DIE @ No player here. Update loop index, cleanup stack and loop again. NSSVTSSTTSSTSSSSTTSSN | MARK: 10011001 00001100 (no_events_in_room) SNT | SWAP SSSTN | PUSH 1 TSST | SUBTRACT NSNTSSTTSSTSSSSSTTTN | JMP > 10011001 00000111 (arrow_loop) NSSVTSSTTSSTSSSSTTSTN | MARK: 10011001 00001101 (loop_end) SNN | DROP SNN | DROP A"The arrows wavers in its flight and can go no further!\n" SSSSN | PUSH 0 NSTTSSSN | JSR > 1000 (printf) @ Since the player did not kill the wumpus, there is a chance it will wake and move. NSTTSSSSN | JSR > 10000 (random) SSSTTSN | PUSH 6 TSTT | MODULO NTSTSSTTSSTSSSSTTTSN | BRZ > 10011001 00001110 (move_wumpus) NSNTSSTTSSTSSSTSSSSN | JMP > 10011001 00010000 (wumpus_continues_to_slumber) NSSVTSSTTSSTSSSSTTTSN | MARK: 10011001 00001110 (move_wumpus) @ Move the wumpus to a random connected room. NSTTSSSSN | JSR > 10000 (random) SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room) TTT | LOAD TSTT | MODULO SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus_location) TTT | LOAD NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus_location) SNT | SWAP TTS | STORE @ Did the wumpus enter the player room? SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus_location) TTT | LOAD SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location) TTT | LOAD TSST | SUBTRACT NTSTSSTTSSTSSSSTTTTN | BRZ > 10011001 00001111 (player_death) NSNTSSTTSSTSSSTSSSSN | JMP > 10011001 00010000 (wumpus_continues_to_slumber) NSSVTSSTTSSTSSSSTTTTN | MARK: 10011001 00001111 (player_death) NSTTTTTTTTTSSSSSSSSN | JSR > 11111111 00000000 (wump_kill) SSSSN | PUSH 0 NSTTSSSN | JSR > 1000 (printf) NNN | DIE NSSVTSSTTSSTSSSTSSSSN | MARK: 10011001 00010000 (wumpus_continues_to_slumber) @ Decrement the number of arrows. SSSTSSSSSSSSSTSTN | PUSH 0x1005 (ptr to number_of_arrows) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT SNS | DUP SSSTSSSSSSSSSTSTN | PUSH 0x1005 (ptr to number_of_arrows) SNT | SWAP TTS | STORE @ Check for empty quiver. NTSTSSTTSSTSSSTSSSTN | BRZ > 10011001 00010001 (empty_quiver) NTN | RTS NSSVTSSTTSSTSSSTSSSTN | MARK: 10011001 00010001 (empty_quiver) NSTTTTTTTTTSSSSSSTSN | JSR > 11111111 00000010 (no_arrows) SSSSN | PUSH 0 NSTTSSSN | JSR > 1000 (printf) NNN | DIE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ move_or_shoot @ Description: @ Parse user input, branching to the appropriate subroutine to move or shoot. @ This function does not perform any boundary checks/limits. @ Call Stack: @ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include #include NSSVTSTSSSTSN | MARK: 10100010 (move_or_shoot) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) NSTTSSSTSN | JSR > 100010 (get_user_string) @ Examine the first character of the user input buffer for 'm' or 's'. @ If character is something else, prompt user to try again. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) TTT | LOAD SSSSTTSTTSTN | PUSH 109 (ASCII 'm') TSST | SUBTRACT NTSTSTSSSTSSSSSSSSSN | BRZ > 10100010 00000000 (move) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) TTT | LOAD SSSSTTTSSTTN | PUSH 115 (ASCII 's') TSST | SUBTRACT NTSTSTSSSTSSSSSSSSTN | BRZ > 10100010 00000001 (shoot) NSTTTTTTTTTSSSSTSSSN | JSR > 11111111 00001000 (problem_with_input) SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NSNTSTSSSTSN | JMP > 10100010 (move_or_shoot) @ User typed 'm' NSSVTSTSSSTSSSSSSSSSN | MARK: 10100010 00000000 (move) NSTTSTSSSTTN | JSR > 10100011 (move_player) NTN | RTS @ User typed 's' NSSVTSTSSSTSSSSSSSSTN | MARK: 10100010 00000001 (shoot) NSTTSSTTSSTN | JSR > 10011001 (shoot_arrow) NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ get_answer @ Description: @ Parse user input, returning 0 if user string started with 'n' or 1 if 'y'. @ This function does not perform any boundary checks/limits. @ Call Stack: @ @ Return Stack: @ (1 or 0 for True/False) <--- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include #include NSSVTSSTTSSSN | MARK: 10011000 (get_answer) @ TODO: Consider extending the GETCHAR instruction in VVS to indicate an empty @ buffer instead of blocking. This would allow a character by character @ check without printing a slew of retry messages if the buffer is @ non-empty. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer address) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (buffer size) NSTTSSSTSN | JSR > 100010 (get_user_string) @ Examine the first character of the user input buffer for 'y' or 'n'. @ If character is something else, prompt user to try again. SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) TTT | LOAD SSSSTTTTSSTN | PUSH 121 (ASCII 'y') TSST | SUBTRACT NTSTSSTTSSSSSSSSSSSN | BRZ > 10011000 00000000 (answer: yes) SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address) TTT | LOAD SSSSTTSTTTSN | PUSH 110 (ASCII 'n') TSST | SUBTRACT NTSTSSTTSSSSSSSSSSTN | BRZ > 10011000 00000001 (answer: no) NSTTTTTTTTTSSSSTSSSN | JSR > 11111111 00001000 (problem_with_input) SSSSN | PUSH 0 (number of string substitutions) NSTTSSSN | JSR > 1000 (printf) NSNTSSTTSSSN | JMP > 10011000 (get_answer) @ User typed 'y' NSSVTSSTTSSSSSSSSSSSN | MARK: 10011000 00000000 (answer: yes) SSSTN | PUSH 1 NTN | RTS @ User typed 'n' NSSVTSSTTSSSSSSSSSSTN | MARK: 10011000 00000001 (answer: no) SSSSN | PUSH 0 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ print_cave_description @ Description: @ Prints information about the cave (number of rooms, etc). @ Call Stack: @ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include NSSVTSSTTSTTN | MARK: 10011011 (print_cave_description) NSTTTTTTTTTSSSSTSTSN | JSR > 11111111 00001010 (cave_description) SSSTSSSSSSSSSTSTN | PUSH 0x1005 (number_of_arrows address) TTT | LOAD SSSTSSSSSSSSSSSTN | PUSH 0x1001 (number_of_pits address) TTT | LOAD SSSTSSSSSSSSSSTSN | PUSH 0x1002 (number_of_bats address) TTT | LOAD SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_tunnels address) TTT | LOAD SSSTSSSSSSSSSSSSN | PUSH 0x1000 (number_of_rooms address) TTT | LOAD SSSTSTN | PUSH 5 (number of substitions) NSTTSSSN | JSR > 1000 (printf) NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: @ print_room_stats @ Description: @ Prints information about current room and hints about nearby rooms. @ Call Stack: @ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include NSSVTSTSSSSTN | MARK: 10100001 (print_room_stats) @ Print location and arrow quantity remaining. A"\n----------\n\nYou are in room %u of the cave and have %u arrows remaining.\n" SSSTSSSSSSSSSTSTN | PUSH 0x1005 (number_of_arrows address) TTT | LOAD SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address) TTT | LOAD SSSTSN | PUSH 2 (number of substitutions) NSTTSSSN | JSR > 1000 (printf) @ Print if bats/pits/wumpus nearby. SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address) TTT | LOAD SNS | DUP NSTTSSTTTSSN | JSR > 10011100 (are_bats_near) NTSTSTSSSSTSSSSSSSSN | BRZ > 10100001 00000000 (no_bats) A"*rustle* (Bats must be nearby.)\n" SSSSN | PUSH 0 (number of substitutions) NSTTSSSN | JSR > 1000 (printf) NSSVTSTSSSSTSSSSSSSSN | MARK: 10100001 00000000 (no_bats) SNS | DUP NSTTSSTTTSTN | JSR > 10011101 (are_pits_near) NTSTSTSSSSTSSSSSSSTN | BRZ > 10100001 00000001 (no_pits) A"*whoosh* (You feel a draft from nearby pits.)\n" SSSSN | PUSH 0 (number of substitutions) NSTTSSSN | JSR > 1000 (printf) NSSVTSTSSSSTSSSSSSSTN | MARK: 10100001 00000001 (no_pits) NSTTSSTTTTSN | JSR > 10011110 (is_wumpus_near) NTSTSTSSSSTSSSSSSTSN | BRZ > 10100001 00000010 (no_wumpus) A"*sniff* (You smell the evil Wumpus nearby!)\n" SSSSN | PUSH 0 (number of substitutions) NSTTSSSN | JSR > 1000 (printf) NSSVTSTSSSSTSSSSSSTSN | MARK: 10100001 00000010 (no_wumpus) @ Print a list of nearby rooms. A"This room contains tunnels to the following rooms:" SSSSN | PUSH 0 (number of substitutions) NSTTSSSN | JSR > 1000 (printf) SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address) TTT | LOAD SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT @ Print one room on each pass through this loop. @ TOS> tunnel_index, room_number NSSVTSTSSSSTSSSSSSTTN | MARK: 10100001 00000011 (print_room_list_loop) A" %u" SSSTSTN | PUSH 5 NSTTTSSN | JSR > 1100 (deepdup) SSSTTTN | PUSH 7 NSTTTSSN | JSR > 1100 (deepdup) NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination) SSSTN | PUSH 1 (number of substitutions) NSTTSSSN | JSR > 1000 (printf) @ Test for end of loop SNS | DUP NTSTSTSSSSTSSSSSTSSN | BRZ > 10100001 00000100 (print_room_list_loop_end) SSSTN | PUSH 1 TSST | SUBTRACT NSNTSTSSSSTSSSSSSTTN | JMP > 10100001 00000011 (print_room_list_loop) @ Clean up and return. NSSVTSTSSSSTSSSSSTSSN | MARK: 10100001 00000100 (print_room_list_loop_end) SSSTSTSN | PUSH 10 (ASCII '\n') TNSS | PUTCHAR SNN | DROP SNN | DROP NTN | RTS #endif