Display concentration style game board with words in MIPS assembly
Solution
Prj2.asm
# { box class
box: .struct
ul: .byte 0 # upper left
top: .byte 0
ur: .byte 0 # upper right
left: .byte 0
middle: .byte 0
right: .byte 0
ll: .byte 0 # lower left
bot: .byte 0 # bottom
lr: .byte 0 # lower right
.data
# { card class
card: .struct
word: .word 0
x: .word 0
y: .word 0
match: .byte 0
faceup: .byte 0
.byte 0
.byte 0
.data
.align 4
infile: .asciiz “wordfile.txt”
words: .space 2444 #611*4
cards: .word 0
# { instances of box}
boxBlank:
.ascii ” ”
boxd: .byte 201,205,187
.byte 186,32,186
.byte 200,205,188
boxs: .byte 218,196,191
.byte 179,32,179
.byte 192,196,217
boxw: .ascii “¬Þ¬Þ¬Þ”
.ascii “§ ˆ ”
.ascii “‡‡‡”
boxg1: .ascii “¬¡¬¡¬¡¬¡ ¬¡¬¡¬¡¬¡”
boxb: .ascii “¬Ã¬Ã¬Ã¬à ¬Ã¬Ã¬Ã¬Ô
.extern lfsr,4
#——————————————————————————-
# void box::draw(int x:a0, int y:a1, int w:a2, int h:a3,box *this:s0)
.code
box.draw:
mov $t9,$a0 # save x for re-use
syscall $xy #
lb $a0,box.ul($s0)
syscall $print_char
lb $a0,box.top($s0)
mov $t0,$a2
b 2f
1: syscall $print_char
addi $t0,$t0,-1
2: bgtz $t0,1b
lb $a0,box.ur($s0)
syscall $print_char
mov $a0,$t9
addi $a1,$a1,1
syscall $xy
b 4f
3: lb $a0,box.left($s0)
syscall $print_char
lb $a0,box.middle($s0) #
mov $t0,$a2
b 2f
1: syscall $print_char
addi $t0,$t0,-1
2: bgtz $t0,1b
lb $a0,box.right($s0)
syscall $print_char
mov $a0,$t9
addi $a1,$a1,1
syscall $xy
addi $a3,$a3,-1
4: bgtz $a3,3b
lb $a0,box.ll($s0)
syscall $print_char
lb $a0,box.bot($s0)
mov $t0,$a2
b 2f
1: syscall $print_char
addi $t0,$t0,-1
2: bgtz $t0,1b
lb $a0,box.lr($s0)
syscall $print_char
jr $ra
#——————————————————————————-
# int random()
# random generator that uses the Galois LFSR PRNG function
random:
li $v0,0x0d000001
lw $t0,lfsr($gp)
srl $t1,$t0,1
andi $t0,$t0,1
beqz $t0,1f
li $t0,-1
1: and $v0,$v0,$t0
xor $v0,$v0,$t1
sw $v0,lfsr($gp)
jr $ra
#——————————————————————————-
#void Fileread(a0: char * filename,a1: char * buffer)
Fileread:
or $t0,$a1,$0 # save pointer to place to load file
add $a1,$0,$0
add $a2,$0,$0
syscall $open
add $a0,$v0,$0 # save file descriptor
or $a1,$t0,$0 # recover pointer to buffer
ori $a2,$0,1 # read a single char at a time
ori $t1,$0,611 # counter of words
1: syscall $read # read a char
lb $t0,($a1) # load read char in t3
beqz $t0,2f
beq $t0,13,1b # if it’s CR, continue
beq $t0,10,2f # if we reached end of line, continue
addi $a1,$a1,1
b 1b
2: sb $0,($a1) # insert end of string
addi $a1,$a1,1
addi $t1,$t1,-1
bnez $t1,1b
syscall $close
jr $ra
#——————————————————————————-
# void card.card(card * c)
card.draw:
addi $sp,$sp,-12
sw $ra,0($sp) # save return address
sw $s0,4($sp)
sw $s1,8($sp)
or $s1,$0,$a0
lw $a0,card.x($s1)
lw $a1,card.y($s1)
ori $a2,$0,3
ori $a3,$0,1
lb $t0,card.match($s1)
bnez $t0,3f # if matched, don’t draw
lb $t1,card.faceup($s1)
bnez $t1,1f # draw up
la $s0,boxd
b 2f
1: la $s0,boxs
2: jal box.draw
lb $t0,card.faceup($s1)
beqz $t0,3f # for face down, don’t draw word
lw $a0,card.x($s1)
addi $a0,$a0,1
lw $a1,card.y($s1)
addi $a1,$a1,1
syscall $xy # else, put the word
lw $t0,card.word($s1)
sll $t0,$t0,2
la $t1,words
add $a0,$t1,$t0
syscall $print_string
3: lw $ra,0($sp)
lw $s0,4($sp)
lw $s1,8($sp)
add $sp,$sp,12
jr $ra
#——————————————————————————-
# void card.card(card * c)
card.card:
addi $sp,$sp,-4
sw $ra,0($sp) # save return address
sw $0,card.word($a0)
sw $0,card.x($a0)
sw $0,card.y($a0)
sb $0,card.match($a0)
ori $t0,$0,1
sb $t0,card.faceup($a0)
lw $ra,0($sp)
add $sp,$sp,4
jr $ra
#——————————————————————————-
# card * card.new()
card.new:
addi $sp,$sp,-12
sw $ra,0($sp) # save return address
sw $s0,4($sp)
sw $a0,8($sp)
ori $a0,$0,16 # reserve space for a card
syscall $malloc
or $s0,$0,$v0
or $a0,$0,$v0
jal card.card
or $v0,$0,$s0
lw $ra,0($sp)
lw $s0,4($sp)
lw $a0,8($sp)
add $sp,$sp,12
jr $ra
#——————————————————————————-
#void Shuffle(card * array[ ]:a0, int N:a1)
Shuffle:
addi $sp,$sp,-8
sw $ra,0($sp) # save return address
sw $a1,4($sp)
1: jal random
div $v0,$a1
mfhi $t0
sll $t0,$t0,2
add $t0,$t0,$a0
lw $t2,($t0)
addi $a1,$a1,-1
sll $t1,$a1,2
add $t1,$t1,$a0
lw $t3,($t1)
lw $t4,card.word($t2) # shuffle only the words…
lw $t5,card.word($t3)
sw $t5,card.word($t2)
sw $t4,card.word($t3)
bgtz $a1,1b
lw $ra,0($sp)
lw $a1,4($sp)
add $sp,$sp,8
jr $ra
#——————————————————————————-
# void clrscr()
clrscr:
addi $sp,$sp,-16
sw $ra,0($sp) # save return address
sw $a0,4($sp)
sw $a1,8($sp)
sw $v0,12($sp)
ori $t0,$0,25
ori $a0,$0,10
1: syscall $print_char
addi $t0,$t0,-1
bnez $t0,1b
or $a0,$0,$0
or $a1,$0,$0
syscall $xy
lw $ra,0($sp)
lw $a0,4($sp)
lw $a1,8($sp)
lw $v0,12($sp)
add $sp,$sp,16
jr $ra
#——————————————————————————-
.data
prompt: .asciiz “Please enter the level of difficulty (1-6): ”
exit: .asciiz ” Press Enter to continue, x to exit: ”
n: .word 0
array: .word 0 # pointer to start address of array of cards
.code
.globl main
#——————————————————————————-
# void main()
main:
ori $t0,$0,1
sw $t0,lfsr($gp)
la $a0,infile # load all words in memory
la $a1,words
jal Fileread
1: jal clrscr
la $a0,prompt
syscall $print_string
syscall $read_int
beqz $v0,1b #
sltiu $t0,$v0,7 # check for out-of-range
beqz $t0,1b # try again
jal clrscr # clear the screen
ori $t0,$0,2
sllv $s0,$t0,$v0 # calculate 2<<n
la $s1,n
sw $v0,($s1) # save difficulty n
or $a0,$0,$s0 # reserve space for card array
sll $a0,$a0,2 # multiply by 4 to get number in bytes
syscall $malloc
la $t0,array # point to start of array with s5
sw $v0,($t0) # save pointer to allocated array
or $s5,$0,$v0
lw $v0,($s1) # restore difficulty level in v0
li $s1,2 # initial boxes wide
li $s2,1 # initial boxes tall
andi $t0,$v0,1 # odd?
srl $v0,$v0,1 # divided by 2
sllv $s1,$s1,$v0
add $v0,$v0,$t0
sllv $s2,$s2,$v0
or $s7,$0,$0
mov $s4,$0 # working counters y
mov $s3,$0 # x
li $a2,3 # width of middle of box
2: li $a3,1 # height of middle of box
sll $a0,$s3,2
add $a0,$a0,$s3 # x = 5 * s3
sll $a1,$s4,1
add $a1,$a1,$s4 # y = 3 * s4
jal card.new
or $s0,$v0,$0
sw $a0,card.x($s0) # save x and y
sw $a1,card.y($s0)
bnez $s7,3f
jal random # generate a word number
ori $t0,$0,611
divu $v0,$t0
mfhi $s6
3: sw $s6,card.word($s0)
sw $s0,($s5)
addi $s5,$s5,4
xori $s7,$s7,1
addi $s3,$s3,1
bne $s3,$s1,2b
mov $s3,$0
addi $s4,$s4,1
bne $s4,$s2,2b
la $t0,array # shuffle the cards
lw $a0,($t0)
la $t0,n
lw $t1,($t0)
ori $t0,$0,2
sllv $a1,$t0,$t1 # calculate 2<<n
jal Shuffle
or $s0,$a1,$0 # print cards
la $t0,array
lw $s1,($t0) # get array pointer in s1
4: lw $t0,($s1) # get a card pointer
or $a0,$0,$t0
jal card.draw
addi $s1,$s1,4
addi $s0,$s0,-1
bnez $s0,4b
or $s0,$a1,$0 # free all allocated space
la $t0,array
lw $s1,($t0) # get array pointer in s1
5: lw $a0,($s1) # get a card pointer
syscall $free
addi $s1,$s1,4
addi $s0,$s0,-1
bnez $s0,5b
la $t0,array
lw $a0,($t0) # get pointer to allocated array
syscall $free # free it
or $a0,$0,$0
ori $a1,$0,24
syscall $xy
la $a0,exit
syscall $print_string
syscall $read_char
bne $v0,’x,1b
syscall $exit