Display concentration style game board with words in MIPS assembly

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