Replaced get_line() from wumpus with get_user_string() from stdlib.
[vvhitespace] / examples / wump / wump_ui.pvvs
index 455e30d..2b9c268 100644 (file)
@@ -58,6 +58,219 @@ TNSS                  | PUTCHAR
 TNSS                  | PUTCHAR
 NTN                   | RTS
 
 TNSS                  | PUTCHAR
 NTN                   | RTS
 
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   is_room_adjacent
+@ Description:
+@   Checks if 'room_number' is adjacent to the player's current room.
+@ Call Stack:
+@   room_number  <-- TOS
+@ Return Stack:
+@   (1 or 0) for true/false  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSTSSTSSN         | MARK: 10100100 (is_room_adjacent)
+
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number_of_tunnels_per_room)
+TTT                   | LOAD
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+
+@ TOS> tunnel_index, destination_room_num
+NSSVTSTSSTSSSSSSSSSSN | MARK: 10100100 00000000 (is_room_adjacent:main_loop)
+SSSTSN                | PUSH +2
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTSN                | PUSH +2
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player_location)
+TTT                   | LOAD
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+TSST                  | SUBTRACT
+NTSTSTSSTSSSSSSSSSTN  | BRZ > 10100100 00000001 (is_room_adjacent:found_tunnel)
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+SNS                   | DUP
+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)
+SNN                   | DROP
+SNN                   | DROP
+SSSTN                 | PUSH +1
+NTN                   | RTS
+
+NSSVTSTSSTSSSSSSSSTSN | MARK: 10100100 00000010 (is_room_adjacent:no_match)
+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:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+#include <convert.pvvs>
+#include <math.pvvs>
+#include <string.pvvs>
+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
+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)
+@ TOS> room_number
+SNN                   | DROP
+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)
+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)
+NSTTSSSSN             | JSR > 10000 (random)
+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)
+NSTTSSSSN             | JSR > 10000 (random)
+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)
+NSTTSSSSN             | JSR > 10000 (random)
+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:
+@   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:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+#include <string.pvvs>
+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)
+@ TODO: JSR shoot
+NTN                   | RTS
+
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ Name:
 @   get_answer
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ Name:
 @   get_answer
@@ -70,13 +283,16 @@ NTN                   | RTS
 @   (1 or 0 for True/False)   <--- TOS
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 #include <stdio.pvvs>
 @   (1 or 0 for True/False)   <--- TOS
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 #include <stdio.pvvs>
+#include <string.pvvs>
 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.
 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.
-NSTTSSTTSSTN          | JSR > 10011001 (get_line)
+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.
 
 @ Examine the first character of the user input buffer for 'y' or 'n'.
 @ If character is something else, prompt user to try again.
@@ -90,7 +306,7 @@ TTT                   | LOAD
 SSSSTTSTTTSN          | PUSH 110 (ASCII 'n')
 TSST                  | SUBTRACT
 NTSTSSTTSSSSSSSSSSTN  | BRZ > 10011000 00000001 (answer: no)
 SSSSTTSTTTSN          | PUSH 110 (ASCII 'n')
 TSST                  | SUBTRACT
 NTSTSSTTSSSSSSSSSSTN  | BRZ > 10011000 00000001 (answer: no)
-NSTTTTTTTTTSSSSTSSSN  | JSR > 11111111 00001000 (problem_with_yes_no_answer)
+NSTTTTTTTTTSSSSTSSSN  | JSR > 11111111 00001000 (problem_with_input)
 SSSSN                 | PUSH 0 (number of string substitutions)
 NSTTSSSN              | JSR > 1000 (printf)
 NSNTSSTTSSSN          | JMP > 10011000 (get_answer)
 SSSSN                 | PUSH 0 (number of string substitutions)
 NSTTSSSN              | JSR > 1000 (printf)
 NSNTSSTTSSSN          | JMP > 10011000 (get_answer)
@@ -105,43 +321,6 @@ NSSVTSSTTSSSSSSSSSSTN | MARK: 10011000 00000001 (answer: no)
 SSSSN                 | PUSH 0
 NTN                   | RTS
 
 SSSSN                 | PUSH 0
 NTN                   | RTS
 
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   get_line
-@ Description:
-@   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.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-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)
-SNS                   | DUP
-SNS                   | DUP
-TNTS                  | GETCHAR
-TTT                   | LOAD
-SNS                   | DUP
-TNSS                  | PUTCHAR
-SSSTSTSN              | PUSH 10 (ASCII '\n')
-TSST                  | SUBTRACT
-NTSTSSTTSSTSSSSSSSTN  | BRZ > 10011001 00000001 (input loop:terminate)
-@ Character was not ENTER. Increment buffer pointer and loop again.
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-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')
-TTS                   | STORE
-NTN                   | RTS
-
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ Name:
 @   print_cave_description
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ Name:
 @   print_cave_description