Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Copyright Maxwell Cudlitz
- # If you steal this for a final project I will find you
- .data ## Message + temp & main cell boards
- # bitmap viewer requires word sizes
- main_array: .space 0x10000 # initial allocation for the main array (32 * 32 words)
- temp_array: .space 0x10000 # initial allocation for temporary array (32 * 32 words)
- welcome_message: .asciiz "[Make sure the bitmap display is open, with the following settings]\nUnit Width in Pixels:\t 1 x 1\nDisplay Size:\t\t 128 x 128\nBase Address:\t\t 0x10010000"
- .text
- la $s1, main_array # get main_array address
- la $s2, temp_array # get temp_array address
- li $s3, 0x0 # used for neighbor counts
- li $s4, 0x0 # used mem address offsets in check
- GAMELOOP:
- # print instructions for viewing board
- li $v0, 4
- la $a0, welcome_message
- syscall
- # generate random board
- jal RANDOMIZEBOARD
- gameTick:
- # load next frame of game state into temporary array
- la $a0, CHECKCELL
- jal LOOPBOARD
- # load next frame of game state into temporary array
- la $a0, COPYCELL
- jal LOOPBOARD
- # loop
- j gameTick
- # loops over board, JALR to address $a0
- # used for loading the temporary board, as well as copying
- LOOPBOARD:
- addi $sp, $sp, -0x4 # ra to stack
- sw $ra, 0x0($sp)
- move $t3, $a0 # store param
- li $t0, 0x0 # iterator- iterate by 32 (bits in a word)
- loopBoard:
- bgeu $t0, 0x10000, returnBoard # break loop when iterator reaches end of memory segment
- add $t1, $t0, $s1 # store address + offset
- addi $sp, $sp, -0xC # push locals to stack
- sw $t0, 0($sp)
- sw $t1, 4($sp)
- sw $t3, 8($sp)
- move $a0, $t0 # pass iterator as param
- jalr $t3 # jump to passed address
- lw $t0, 0($sp) # pop locals from stack
- lw $t1, 4($sp)
- lw $t3, 8($sp)
- addi $sp, $sp, 0xC
- addi $t0, $t0, 0x4 # iterate outer iterator by 4 (for word-offset cells)
- j loopBoard # continue loop
- returnBoard:
- lw $ra, 0($sp) # pop ra from stack
- add $sp, $sp, 0x4
- jr $ra # return
- # fill board with random bits, one every word
- RANDOMIZEBOARD:
- addi $sp, $sp, -0x4 # ra to stack
- sw $ra, 0($sp)
- li $t0, 0x0 # iterator; iterates by 32 (bits in a word)
- loopBoardRnd:
- bgtu $t0, 0x4000, returnBoardRnd # return if board filled
- add $t1, $t0, $s1 # add to mem offset to obtain array location
- li $v0, 41 # random int code
- li $a1, 0xFFFFFFFF # max bound = word max (will set 32 elements of array at a time)
- syscall # generate rand
- move $t3, $a0 # store rand result
- addi $sp, $sp, -0x8 # push locals to stack
- sw $t0, 0($sp)
- sw $t1, 4($sp)
- move $a0, $t3 # load random result into arg
- mul $a1, $t0, 0x4 # load iterator byte offset into arg (group of 32 words)
- jal INSERTRANDWORD # insert 32 random cell values
- lw $t0, 0($sp) # pop locals from stack
- lw $t1, 4($sp)
- addi $sp, $sp, 0x8
- addi $t0, $t0, 0x20 # iterate by 32
- j loopBoardRnd # continue loop
- returnBoardRnd:
- lw $ra, 0($sp) # pop ra from stack
- add $sp, $sp, 0x4
- jr $ra # return
- # inserts the word at $a0 into the board at offset $a1, setting 64 cells at once
- # makes rand insertion more than 64 times faster
- INSERTRANDWORD:
- addi $sp, $sp, -0x4 # push ra to stack
- sw $ra, 0($sp)
- li $t0, 0x0 # outer iterator; iterate over bits of word
- li $t2, 0x80000000 # store [10000000000000000000000000000000b] to serve as bitmask
- loopInsRnd:
- bge $t0, 0x20, returnInsRnd # after iterating 32 bits (1 word) return
- and $t4, $t2, $a0 # will be nonzero if bit at this element
- sne $t4, $t4, 0x0 # sets if bit was nonzero
- sll $t4, $t4, 0x7 # shift to max value
- mul $t1, $t0, 0x4 # mul iterator to get word offset
- add $t1, $t1, $s1 # add to mem offset to obtain array location
- add $t1, $t1, $a1 # offset by passed mem offset
- sw $t4, 0($t1) # store byte in array
- addi $t0, $t0, 0x1 # iterate
- srl $t2, $t2, 0x1 # shift mask
- jal loopInsRnd # continue loop
- returnInsRnd:
- lw $ra, 0($sp) # pop + jump to ra
- addi $sp, $sp, 0x4
- jr $ra
- # checks the cell at index $a0
- CHECKCELL:
- # Checks are done in a clockwise direction
- # 0 1 2
- # 7 x 3
- # 6 5 4
- add $s4, $s1, $a0 # store address + index offset
- li $s3, 0x0 # reset neighbor count
- move $t0, $a0 # copy cell index
- addi $t0, $t0, 0x1 # add 1 to index to prevent div by zero, and align index.
- li $t1, 0x80 # load 128 * 4 - (column count (bytes)) for div
- srl $t0, $t0, 0x2 # normalize
- div $t1, $t0, $t1 # div to obtain position on row
- mfhi $t1 # get position on row from remainder
- seq $t3, $t1, 0x1 # flag if leftmost column
- seq $t4, $t1, 0x200 # flag if rightmost column
- checkCell_0:
- blt $t0, 0x200, cellCheck_3 # skip upper checks (0 - 2) if index is on first row
- bne $t3, 0x0, checkCell_1 # skip if left-aligned
- lw $t5, -0x204($s4) # load top-left byte (-128 - 1) * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- checkCell_1:
- lw $t5, -0x200($s4) # load top-mid byte (-128) * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- cellCheck_2:
- bne $t3, 0x0, cellCheck_5 # early-exit 2-4 if right-aligned
- lw $t5, -0x1FC($s4) # load top-right byte (-128 + 1) * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- cellCheck_3:
- lb $t5, 0x4($s4) # load mid-right byte 1 * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- checkCell_4:
- # (128 * 128) - 64 - 1 = 0x3FBF
- # skip lower checks (0 - 2) if index is on first row [default case]
- ####### possible problem area as is not BGTE #######
- bgt $t1, 0x3FBF, checkCell_7
- lw $t5, 0x204($s4) # load bot-right byte (128 + 1) * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- cellCheck_5:
- lw $t5, 0x200($s4) # load mid-bot byte (128) * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- cellCheck_6:
- bne $t4, 0x0, finishCheck # early-exit 6-7 if left-aligned
- lw $t5, 0x1FC($s4) # load bot-left byte (128 - 1) * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- checkCell_7:
- lw $t5, -0x4($s4) # load mid-left byte -1 * 4
- add $s3, $s3, $t5 # add value to neighbor counter
- finishCheck:
- lw $t0, 0x0($s4) # load val if no change
- srl $s3, $s3, 0x7 # normalize counter
- bgt $s3, 0x3, kill # overpopulation
- blt $s3, 0x2, kill # underpopulation
- beq $s3, 0x3, breeding # breeding
- j finCheck
- kill:
- li $t0, 0x0 # new cell will be = 0
- j finCheck
- breeding:
- li $t0, 0x80 # new cell will be = 1
- finCheck:
- add $s4, $s2, $a0 # store address + index offset of temp array
- sw $t0, 0x0($s4) # store in temp array
- jr $ra # return to loop
- COPYCELL:
- add $t0, $s1, $a0 # store address + index offset (main board)
- add $t1, $s2, $a0 # store address + index offset (temp board)
- lw $t1, 0($t1) # load value from temp board
- sw $t1, 0($t0) # store value in main board from temp
- jr $ra
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement