-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCoreInput.asm
209 lines (166 loc) · 4.44 KB
/
CoreInput.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
.data
ptr_a0: .word 0
str_getUserInputTitle: .asciiz "YOUR MOVE"
str_getUserInputSubtitle: .asciiz "Please choose a valid position to place your piece.\nYou can enter your choice in any order, but it must be capitalized.\n(Example: A3 or 2B)\n\n[INPUT]: "
str_playAgainTitle: .asciiz "PLAY AGAIN?"
str_playAgainSubtitle: .asciiz "Would you like to play again?\n1. Return to main menu\n2. Exit application\n\n[INPUT]: "
str_userInput: .asciiz ""
str_newLine: .asciiz "\n"
str_buffer: .asciiz " "
int_buffer: .word 0
.text
.globl checkIntRange
checkIntRange:
#$a0 : Word
#$a1 : Lower Value
#$a2 : Upper Value
#$v0 : Result
li $v0, 0
#checks if $a0 >= $a1
blt $a0, $a1, range_check_complete
#checks if $a0 <= $a2
bgt $a0, $a2, range_check_complete
#sets $v0 to one if both tests pass
li $v0, 1
range_check_complete:
jr $ra
.globl isInteger
isInteger:
#$a0 : ascii code to test
#method: Move $a0 into pointer to preserve it
sw $a0, ptr_a0
#method: Save return address to the stack
move $a0, $ra
jal saveReturnAdd
#method: Check if the ascii value in $a0 is within the the acsii values of 1 and 8 (49 and 56)
lw $a0, ptr_a0
li $a1, 49
li $a2, 56
jal checkIntRange
#method: Reload the return address, and return to caller
jal loadReturnAdd
jr $ra
.globl isChar
isChar:
#$a0 : ascii code to test
#method: Move $a0 into pointer to preserve it
sw $a0, ptr_a0
#method: Save return address to the stack
move $a0, $ra
jal saveReturnAdd
#method: Check if the ascii value in $a0 is within the the acsii values of A and H (65 and 72)
lw $a0, ptr_a0
li $a1, 65
li $a2, 72
jal checkIntRange
#method: Reload the return address, and return to caller
jal loadReturnAdd
jr $ra
.globl getUserInput
getUserInput:
#method: save registers to the stack
move $a0, $ra
jal saveAllRegisters
# $s0 : First character
# $s1 : Second character
# $s2 : If the move is valid
# $s3 : Validated user input
#output: Print the input prompt
la $a0, str_getUserInputTitle
la $a1, str_getUserInputSubtitle
jal renderPrompt
begin_validation:
#input: Get the user input
la $a0, str_userInput
li $a1, 3
li $v0, 8
syscall
#input: Read the newline character
la $a0, str_buffer
li $a1, 0
li $v0, 8
syscall
#method: Get the characters from the input string
la $t1, str_userInput
lb $s0, 0($t1)
lb $s1, 1($t1)
li $s2, 0
#condition: Check if the first character is an integer
move $a0, $s0
jal isInteger
beq $v0, 1, first_is_int
#condition: Check if the first character is a letter
move $a0, $s0
jal isChar
beqz $v0, validation_complete
#condition: Check if the second character is an integer
move $a0, $s1
jal isInteger
beqz $v0, validation_complete
#method: Make the first character the integer, and the second character a letter
move $t0, $s0
move $s0, $s1
move $s1, $t0
#method: Input is validated
j input_validated
first_is_int:
#condition: Check if the second character is a letter
move $a0, $s1
jal isChar
beqz $v0, validation_complete
input_validated:
#method: Set the inputs to be aligned with the rows & columns of a table
addi $s0, $s0, -49
addi $s1, $s1, -65
#method: Check if is legal move
move $a0, $s0
move $a1, $s1
li $a2, 88
jal isValidMove
beqz $v0, validation_complete
#method: Input is validated and move is legal
li $s2, 1
validation_complete:
#condition: If the input isn't valid, redo input
beq $s2, 1, return_input
#method: Render error if input isn't valid
la $a0, str_getUserInputSubtitle
jal renderError
j begin_validation
return_input:
#method: Combine the user input into a single register
sll $s3, $s0, 4
add $s3, $s3, $s1
move $v0, $s3
#method: Reload registers from the stack and return to the caller
jal loadAllRegisters
jr $ra
.globl playAgain
playAgain:
move $a0, $ra
jal saveReturnAdd
#output: Print the user prompt
la $a0, str_playAgainTitle
la $a1, str_playAgainSubtitle
jal renderPrompt
get_replay_choice:
#input: Get the users choise
li $v0, 5
syscall
sw $v0, int_buffer
#method: validate the input
move $a0, $v0
li $a1, 1
li $a2, 2
jal checkIntRange
#condition: If the input is invalid, ask again
bnez $v0, valid_replay_choice
la $a0, str_playAgainSubtitle
jal renderError
j get_replay_choice
valid_replay_choice:
#method: Return the user input
lw $v0, int_buffer
#method: Reload the return address
jal loadReturnAdd
jr $ra