@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ This files contains user interface functions for Hunt the Wumpus.
@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
@ See LICENSE.txt file for copyright and license details.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Generate seed from keyboard input.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
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)
SSSTSTTTSN | PUSH ASCII '.'
@ 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)
NSTTSTSTTN | JSR > 101011 (xor)
@ Test for loop completion
NTSTSSSSSTTSSSSSSSTN | BRZ > 10000011 00000001 (seed_rng:cleanup and return)
NSNTSSSSSTTSSSSSSSSN | JMP > 10000011 00000000 (seed_rng:main loop)
@ Store seed, clean up and return.
NSSVTSSSSSTTSSSSSSSTN | MARK: 10000011 00000001 (seed_rng:cleanup and return)
SSSSN | PUSH 0 (seed address)
SSSTSTSN | PUSH ASCII '\n'
SSSTSTSN | PUSH ASCII '\n'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Checks if 'room_number' is adjacent to the player's current room.
@ (1 or 0) for true/false <-- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTSSTSSN | MARK: 10100100 (is_room_adjacent)
SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number_of_tunnels_per_room)
@ TOS> tunnel_index, destination_room_num
NSSVTSTSSTSSSSSSSSSSN | MARK: 10100100 00000000 (is_room_adjacent:main_loop)
NSTTTSSN | JSR > 1100 (deepdup)
NSTTTSSN | JSR > 1100 (deepdup)
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player_location)
NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination)
NTSTSTSSTSSSSSSSSSTN | BRZ > 10100100 00000001 (is_room_adjacent:found_tunnel)
NTTTSTSSTSSSSSSSSTSN | BMI > 10100100 00000010 (is_room_adjacent:no_match)
NSNTSTSSTSSSSSSSSSSN | JMP > 10100100 00000000 (is_room_adjacent:main_loop)
NSSVTSTSSTSSSSSSSSSTN | MARK: 10100100 00000001 (is_room_adjacent:found_tunnel)
NSSVTSTSSTSSSSSSSSTSN | MARK: 10100100 00000010 (is_room_adjacent:no_match)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
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)
NSTTSSTTSSTN | JSR > 10011001 (get_line)
SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address)
NSTTTSSSSN | JSR > 110000 (atoi)
@ The desired room number is now on the TOS. Verify that it is valid.
NSTTSTSSTSSN | JSR > 10100100 (is_room_adjacent)
NTSTSTSSSTTSSSSSSSTN | BRZ > 10100011 00000001 (invalid room number)
NSNTSTSSSTTSSSSSSSSN | JMP > 10100011 00000000 (valid room number)
NSSVTSTSSSTTSSSSSSSTN | MARK: 10100011 00000001 (invalid room number)
A"*Oof!* (you hit the wall)\n"
SSSSN | PUSH 0 (number of string substitutions)
NSTTSSSN | JSR > 1000 (printf)
NSTTSSSSN | JSR > 10000 (random)
SSSTTSN | PUSH 6 (chance)
NTSTSTSSSTTSSSSSSTSN | BRZ > 10100011 00000010 (woke the wumpus)
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)
NSTTSSSSN | JSR > 10000 (random)
SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number of tunnels per room)
SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus location)
NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination)
SSSTSSSSSSSSSTTTN | PUSH 0x1007 (ptr to wumpus location)
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location)
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)
NSSVTSTSSSTTSSSSSSTTN | MARK: 10100011 00000011 (wumpus did not move to player)
NSSVTSTSSSTTSSSSSSSSN | MARK: 10100011 00000000 (valid room number)
@ Move player to new room
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location)
@ Check for wumpus in new player location
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location)
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)
NSSVTSTSSSTTSSSSSTSSN | MARK: 10100011 00000100 (no wumpus in new room)
@ Check for pits in new player location
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location)
NSTTSSSTTSTN | JSR > 10001101 (room_has_pits)
NTSTSTSSSTTSSSSSTSTN | BRZ > 10100011 00000101 (no pits in new room)
NSTTSSSSN | JSR > 10000 (random)
SSSTTSN | PUSH 6 (chance)
NTSTSTSSSTTSSSSSTTSN | BRZ > 10100011 00000110 (survived the pits)
NSTTTTTTTTTSSSSSTSTN | JSR > 11111111 00000101 (pit_kill)
SSSSN | PUSH 0 (number of string substitutions)
NSTTSSSN | JSR > 1000 (printf)
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)
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)
NSTTSSSSN | JSR > 10000 (random)
SSSTSSSSSSSSSSTTN | PUSH 0x1003 (ptr to number of tunnels per room)
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (ptr to player location)
NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination)
NSNTSTSSSTTSSSSSSSSN | JMP > 10100011 00000000 (valid room number)
NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (no bats in new room)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Parse user input, branching to the appropriate subroutine to move or shoot.
@ This function does not perform any boundary checks/limits.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTSSSTSN | MARK: 10100010 (move_or_shoot)
NSTTSSTTSSTN | JSR > 10011001 (get_line)
@ 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)
SSSSTTSTTSTN | PUSH 109 (ASCII 'm')
NTSTSTSSSTSSSSSSSSSN | BRZ > 10100010 00000000 (move)
SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address)
SSSSTTTSSTTN | PUSH 115 (ASCII 's')
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)
NSSVTSTSSSTSSSSSSSSSN | MARK: 10100010 00000000 (move)
NSTTSTSSSTTN | JSR > 10100011 (move_player)
NSSVTSTSSSTSSSSSSSSTN | MARK: 10100010 00000001 (shoot)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Parse user input, returning 0 if user string started with 'n' or 1 if 'y'.
@ This function does not perform any boundary checks/limits.
@ (1 or 0 for True/False) <--- TOS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
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
NSTTSSTTSSTN | JSR > 10011001 (get_line)
@ 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)
SSSSTTTTSSTN | PUSH 121 (ASCII 'y')
NTSTSSTTSSSSSSSSSSSN | BRZ > 10011000 00000000 (answer: yes)
SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address)
SSSSTTSTTTSN | PUSH 110 (ASCII 'n')
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)
NSSVTSSTTSSSSSSSSSSSN | MARK: 10011000 00000000 (answer: yes)
NSSVTSSTTSSSSSSSSSSTN | MARK: 10011000 00000001 (answer: no)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Read one line of user input and store in buffer.
@ Appends null terminator to end of string.
@ This function does not perform any boundary checks/limits.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSSTTSSTN | MARK: 10011001 (get_line)
@ Get one character from user on each pass through this loop.
@ Terminate loop when line break character is received.
SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (USER_INPUT_BUFFER address)
NSSVTSSTTSSTSSSSSSSSN | MARK: 10011001 00000000 (input loop)
SSSTSTSN | PUSH 10 (ASCII '\n')
NTSTSSTTSSTSSSSSSSTN | BRZ > 10011001 00000001 (input loop:terminate)
@ Character was not ENTER. Increment buffer pointer and loop again.
NSNTSSTTSSTSSSSSSSSN | JMP > 10011001 00000000 (input loop)
@ Character was ENTER. Overwrite the line feed with a null term and return.
NSSVTSSTTSSTSSSSSSSTN | MARK: 10011001 00000001 (input loop:terminate)
SSSSN | PUSH 0 (ASCII '\0')
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Prints information about the cave (number of rooms, etc).
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSSTTSTTN | MARK: 10011011 (print_cave_description)
NSTTTTTTTTTSSSSTSTSN | JSR > 11111111 00001010 (cave_description)
SSSTSSSSSSSSSTSTN | PUSH 0x1005 (number_of_arrows address)
SSSTSSSSSSSSSSSTN | PUSH 0x1001 (number_of_pits address)
SSSTSSSSSSSSSSTSN | PUSH 0x1002 (number_of_bats address)
SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_tunnels address)
SSSTSSSSSSSSSSSSN | PUSH 0x1000 (number_of_rooms address)
SSSTSTN | PUSH 5 (number of substitions)
NSTTSSSN | JSR > 1000 (printf)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Prints information about current room and hints about nearby rooms.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#include <wump_game.pvvs>
NSSVTSTSSSSTN | MARK: 10100001 (print_room_stats)
@ Print location and arrow quantity remaining.
A"You are in room %u of the cave and have %u arrows remaining.\n"
SSSTSSSSSSSSSTSTN | PUSH 0x1005 (number_of_arrows address)
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address)
SSSTSN | PUSH 2 (number of substitutions)
NSTTSSSN | JSR > 1000 (printf)
@ Print if bats/pits/wumpus nearby.
SSSTSSSSSSSSSTTSN | PUSH 0x1006 (player_location address)
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)
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)
SSSTSSSSSSSSSSTTN | PUSH 0x1003 (number_of_links_per_room address)
@ Print one room on each pass through this loop.
@ TOS> tunnel_index, room_number
NSSVTSTSSSSTSSSSSSTTN | MARK: 10100001 00000011 (print_room_list_loop)
NSTTTSSN | JSR > 1100 (deepdup)
NSTTTSSN | JSR > 1100 (deepdup)
NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination)
SSSTN | PUSH 1 (number of substitutions)
NSTTSSSN | JSR > 1000 (printf)
NTSTSTSSSSTSSSSSTSSN | BRZ > 10100001 00000100 (print_room_list_loop_end)
NSNTSTSSSSTSSSSSSTTN | JMP > 10100001 00000011 (print_room_list_loop)
NSSVTSTSSSSTSSSSSTSSN | MARK: 10100001 00000100 (print_room_list_loop_end)
SSSTSTSN | PUSH 10 (ASCII '\n')