Lab 2 - Letter guessing game
In this lab, I decided to mimic something professor has taught in his recording, which shows how to get input, print output and jump to different branches based on conditions. Assembly is supper difficult for me as I'm really not familiar with the language. As a result, I decide to combine my lab 1 and his instructions to create a letter guessing game. This program will randomly select a letter from A to Z, store it in the memory. The user will guess the letter. If they guess it correctly, a prompt will appear and the screen will become green, else there will be an error prompt followed by an input prompt for retry, and the screen will turn red. Here is the code:
; ROM routines
define SCINIT $ff81 ; initialize/clear screen
define CHRIN $ffcf ; input character from keyboard
define CHROUT $ffd2 ; output character to screen
define SCREEN $ffed ; get screen size
define PLOT $fff0 ; get/set cursor coordinates
define GENERATED_LETTER $0040
define INPUT_LETTER $0041
define LOW_COLOR_BYTE $42
define HIGH_COLOR_BYTE $43
;$2: Red
;$5: Green
INITIALIZE:
JSR SCINIT
LDA #$00
STA LOW_COLOR_BYTE
LDA #$00
STA HIGH_COLOR_BYTE
GENERATE_LETTER:
LDA $FE ; GET THE RANDOM BYTE
AND #$1F ; MASK IT TO REDUCE THE BIT RANGE FROM
ORA #$41 ; ADD THE VALUE WITH 65 IN HEX TO BE A LETTER
STA GENERATED_LETTER;
LDY #$00
RESET_Y_FOR_INPUT_PROMPT:
LDY #$00
PRINT_INPUT_PROMPT:
LDA INPUT_PROMPT,Y
BEQ GET_INPUT
JSR CHROUT ; put the character in A on to the screen
INY
BNE PRINT_INPUT_PROMPT
GET_INPUT:
LDY #$00 ; COUNT THE CHARACTER TYPE
GET_CHAR:
JSR CHRIN
CMP #$00
BEQ GET_CHAR
CMP #$08 ;COMPARE WITH BACKSPACE
BNE CHECK_ENTER; IF NOT BACKSPACE, THEN CHECK FOR ENTER
CPY #$00 ; CHECK IF THERE IS NO CHARACTER
BEQ GET_CHAR
DEY
LDA #$20 ;LOAD A WITH WHITE SPACE
JSR CHROUT
LDA #$83 ;MOVE CURSOR LEFT 1 POSITION
JSR CHROUT
JSR CHROUT
LDA #$A0 ; CODE FOR BLACK SPACE
JSR CHROUT
LDA #$83
JSR CHROUT
CHECK_ENTER:
CMP #$0D ; CHECK IF ITS THE ENTER CHAR
BNE CHECK_LETTER; ... IF NOT ENTER, CHECK FOR CHARS
CPY #$01 ; CHECK IF THERE ARE 1 CHARS
BEQ PRINT_INPUT_LETTER ;
CHECK_LETTER:
CMP #97 ; COMPARE INPUT WITH "a"
BCC UPPERCASE ; CHECK IF ITS UPPERCASE
CMP #123 ; CHECK INPUT WIHT "z+1"
BCS GET_CHAR ; IF HIGHER THAN "z", GET ANOTHER CHARACTER
SEC
SBC #32 ; SUBSTRACT 32 TO CONVERT lowercase TO UPPERCASE
UPPERCASE:
CMP #65 ;Compare input char with A, C=1 if A >= 65, C=0 if A < 65
BCC GET_CHAR ; if lower than A, get another Char
CMP #91 ; Compare input char with Z + 1
BCS GET_CHAR ; if higher than Z, get another Char
CPY #$05 ; CHECK THE COUNT OF THE CHARACTERS
BEQ GET_CHAR ; IF WE HAVE 5 WE DON'T ACCEPT ANOTHER CHAR
STA INPUT_LETTER
JSR CHROUT ; PRINT RECEIVED CHARACTER ON THE SCREEN
LDA #$A0 ; CODE FOR BLACK SPACE
JSR CHROUT
LDA #$83
JSR CHROUT
INY
JMP GET_CHAR
PRINT_INPUT_LETTER:
LDA #$0D
JSR CHROUT
LDA INPUT_LETTER
CMP GENERATED_LETTER
BEQ RESET_Y_FOR_CORRECT_ANSWER_PROMPT
JMP RESET_Y_FOR_WRONG_ANSWER_PROMPT
RESET_Y_FOR_WRONG_ANSWER_PROMPT:
LDY #$00
PRINT_WRONG_ANSWER_PROMPT:
LDA WRONG_ANSWER_PROMPT,Y
BEQ RESET_Y_FOR_RED_SCREEN
JSR CHROUT ; put the character in A on to the screen
INY
BNE PRINT_WRONG_ANSWER_PROMPT
RESET_Y_FOR_RED_SCREEN:
LDY #$00
LDA #$02
STA HIGH_COLOR_BYTE
LDA #$02
PAINT_SCREEN_RED:
STA (LOW_COLOR_BYTE), Y
INY
BNE PAINT_SCREEN_RED
INC HIGH_COLOR_BYTE
LDX HIGH_COLOR_BYTE
CPX #$06
BNE PAINT_SCREEN_RED
JMP RESET_Y_FOR_INPUT_PROMPT
RESET_Y_FOR_CORRECT_ANSWER_PROMPT:
LDY #$00
PRINT_CORRECT_ANSWER_PROMPT:
LDA CORRECT_ANSWER_PROMPT,Y
BEQ RESET_Y_FOR_GREEN_SCREEN
JSR CHROUT ; put the character in A on to the screen
INY
BNE PRINT_CORRECT_ANSWER_PROMPT
RESET_Y_FOR_GREEN_SCREEN:
LDY #$00
LDA #$02
STA HIGH_COLOR_BYTE
LDA #$05
PAINT_SCREEN_GREEN:
STA (LOW_COLOR_BYTE), Y
INY
BNE PAINT_SCREEN_GREEN
INC HIGH_COLOR_BYTE
LDX HIGH_COLOR_BYTE
CPX #$06
BNE PAINT_SCREEN_GREEN
JMP DONE
DONE:
BRK
INPUT_PROMPT:
DCB "T", "O", 32, "G", "U", "E", "S", "S", 44, 32, "E", "N", "T", "E", "R", 32, "A", 32, "L", "E", "T", "T", "E", "R", 32, "A", "N", "D", 32, "P", "R", "E", "S", "S", 32, "E", "N", "T", "E", "R", ":", 32, 00
WRONG_ANSWER_PROMPT:
DCB "Y","O","U","R", 32, "A","N","S","W","E","R", 32, "I","S", 32, "I","N","C","O","R","R","E","C","T", $0D, 00
CORRECT_ANSWER_PROMPT:
DCB "C","O","R","R","E","C","T", 32, "A","N","S","W","E","R","!",32, "E","X","I","T","I","N","G",32, "T","H","E",32, "P","R","O","G","R","A","M",".", 00
define SCINIT $ff81 ; initialize/clear screen
define CHRIN $ffcf ; input character from keyboard
define CHROUT $ffd2 ; output character to screen
define SCREEN $ffed ; get screen size
define PLOT $fff0 ; get/set cursor coordinates
define GENERATED_LETTER $0040
define INPUT_LETTER $0041
define LOW_COLOR_BYTE $42
define HIGH_COLOR_BYTE $43
;$2: Red
;$5: Green
INITIALIZE:
JSR SCINIT
LDA #$00
STA LOW_COLOR_BYTE
LDA #$00
STA HIGH_COLOR_BYTE
GENERATE_LETTER:
LDA $FE ; GET THE RANDOM BYTE
AND #$1F ; MASK IT TO REDUCE THE BIT RANGE FROM
ORA #$41 ; ADD THE VALUE WITH 65 IN HEX TO BE A LETTER
STA GENERATED_LETTER;
LDY #$00
RESET_Y_FOR_INPUT_PROMPT:
LDY #$00
PRINT_INPUT_PROMPT:
LDA INPUT_PROMPT,Y
BEQ GET_INPUT
JSR CHROUT ; put the character in A on to the screen
INY
BNE PRINT_INPUT_PROMPT
GET_INPUT:
LDY #$00 ; COUNT THE CHARACTER TYPE
GET_CHAR:
JSR CHRIN
CMP #$00
BEQ GET_CHAR
CMP #$08 ;COMPARE WITH BACKSPACE
BNE CHECK_ENTER; IF NOT BACKSPACE, THEN CHECK FOR ENTER
CPY #$00 ; CHECK IF THERE IS NO CHARACTER
BEQ GET_CHAR
DEY
LDA #$20 ;LOAD A WITH WHITE SPACE
JSR CHROUT
LDA #$83 ;MOVE CURSOR LEFT 1 POSITION
JSR CHROUT
JSR CHROUT
LDA #$A0 ; CODE FOR BLACK SPACE
JSR CHROUT
LDA #$83
JSR CHROUT
CHECK_ENTER:
CMP #$0D ; CHECK IF ITS THE ENTER CHAR
BNE CHECK_LETTER; ... IF NOT ENTER, CHECK FOR CHARS
CPY #$01 ; CHECK IF THERE ARE 1 CHARS
BEQ PRINT_INPUT_LETTER ;
CHECK_LETTER:
CMP #97 ; COMPARE INPUT WITH "a"
BCC UPPERCASE ; CHECK IF ITS UPPERCASE
CMP #123 ; CHECK INPUT WIHT "z+1"
BCS GET_CHAR ; IF HIGHER THAN "z", GET ANOTHER CHARACTER
SEC
SBC #32 ; SUBSTRACT 32 TO CONVERT lowercase TO UPPERCASE
UPPERCASE:
CMP #65 ;Compare input char with A, C=1 if A >= 65, C=0 if A < 65
BCC GET_CHAR ; if lower than A, get another Char
CMP #91 ; Compare input char with Z + 1
BCS GET_CHAR ; if higher than Z, get another Char
CPY #$05 ; CHECK THE COUNT OF THE CHARACTERS
BEQ GET_CHAR ; IF WE HAVE 5 WE DON'T ACCEPT ANOTHER CHAR
STA INPUT_LETTER
JSR CHROUT ; PRINT RECEIVED CHARACTER ON THE SCREEN
LDA #$A0 ; CODE FOR BLACK SPACE
JSR CHROUT
LDA #$83
JSR CHROUT
INY
JMP GET_CHAR
PRINT_INPUT_LETTER:
LDA #$0D
JSR CHROUT
LDA INPUT_LETTER
CMP GENERATED_LETTER
BEQ RESET_Y_FOR_CORRECT_ANSWER_PROMPT
JMP RESET_Y_FOR_WRONG_ANSWER_PROMPT
RESET_Y_FOR_WRONG_ANSWER_PROMPT:
LDY #$00
PRINT_WRONG_ANSWER_PROMPT:
LDA WRONG_ANSWER_PROMPT,Y
BEQ RESET_Y_FOR_RED_SCREEN
JSR CHROUT ; put the character in A on to the screen
INY
BNE PRINT_WRONG_ANSWER_PROMPT
RESET_Y_FOR_RED_SCREEN:
LDY #$00
LDA #$02
STA HIGH_COLOR_BYTE
LDA #$02
PAINT_SCREEN_RED:
STA (LOW_COLOR_BYTE), Y
INY
BNE PAINT_SCREEN_RED
INC HIGH_COLOR_BYTE
LDX HIGH_COLOR_BYTE
CPX #$06
BNE PAINT_SCREEN_RED
JMP RESET_Y_FOR_INPUT_PROMPT
RESET_Y_FOR_CORRECT_ANSWER_PROMPT:
LDY #$00
PRINT_CORRECT_ANSWER_PROMPT:
LDA CORRECT_ANSWER_PROMPT,Y
BEQ RESET_Y_FOR_GREEN_SCREEN
JSR CHROUT ; put the character in A on to the screen
INY
BNE PRINT_CORRECT_ANSWER_PROMPT
RESET_Y_FOR_GREEN_SCREEN:
LDY #$00
LDA #$02
STA HIGH_COLOR_BYTE
LDA #$05
PAINT_SCREEN_GREEN:
STA (LOW_COLOR_BYTE), Y
INY
BNE PAINT_SCREEN_GREEN
INC HIGH_COLOR_BYTE
LDX HIGH_COLOR_BYTE
CPX #$06
BNE PAINT_SCREEN_GREEN
JMP DONE
DONE:
BRK
INPUT_PROMPT:
DCB "T", "O", 32, "G", "U", "E", "S", "S", 44, 32, "E", "N", "T", "E", "R", 32, "A", 32, "L", "E", "T", "T", "E", "R", 32, "A", "N", "D", 32, "P", "R", "E", "S", "S", 32, "E", "N", "T", "E", "R", ":", 32, 00
WRONG_ANSWER_PROMPT:
DCB "Y","O","U","R", 32, "A","N","S","W","E","R", 32, "I","S", 32, "I","N","C","O","R","R","E","C","T", $0D, 00
CORRECT_ANSWER_PROMPT:
DCB "C","O","R","R","E","C","T", 32, "A","N","S","W","E","R","!",32, "E","X","I","T","I","N","G",32, "T","H","E",32, "P","R","O","G","R","A","M",".", 00
If you guess it incorrectly, you'll see this:
If you guess it correctly, this one will show:
Learning: This lab is where I feel like I start to get a hang of Assembly, how to store variables, how to utilize X and Y register and how to move to different sections in the same code space.
Area for improvement: There is a lot that can be improve. For example, instead of printing the entire screen with 1 color, I can print a portion of it, leaving more space for another guess. I can also limit the number of guess. Last but not least, I can provide some clue to let user know whether they are closer to the answer or not.
Comments
Post a Comment