# Cycle a Cellular Automaton through the changes of life # This program takes two or three arguments on the command line. # cycles The number of times the CA should be processed using the # rule table (transition function). # seed# The index to the word that is the initial value of the CA. # 0..(# of defined seed values - 1) # bitcount The number of bits in the CA bitstring. This is an optional # argument and you do not have to implement it for the basic # assignment. # # When the program is running it asks the user for two values # rule: The value from 0 to 255 that defines the transition from # one cycle of the CA to the next. # edge: Defines what to substitute for missing values at the edge of the # CA when the center bit is 0 or 31 (or bitcount-1). edge can # be 0 or 1. # # The program terminates when a rule value of 0 is entered. # --------------------------------------------------------------------------- .data # The .data area is where you declare variables that your # program needs. Examples are the seed values that the user # can select from, any message text that you want to write out # for the user, and empty variables to use as the and # bit strings for cycleCA. .text # The .text area is where your program code goes. main: j $ra # --------------------------------------------------------------------------- .text # the program instructions for cycleCA cycleCA: j $ra # --------------------------------------------------------------------------- # bitSlice3 function # get three bits out of a bit string # a0 offset from 0 to the center bit, 0..(bit string length - 1) # a1 edge control, 0=> fill edge with 0, 1 => fill edge with 1, # -1 => wrap bit from the other end of the bit string # a2 address(bit string), word aligned # a3 bit string length, must be > 0. Should be 32, unless you are # implementing arbitrary length bit strings. # t0 offset to the current bit within the bit string (0..(length -1)) # t1 offset to the current word # t2 offset to the current bit within the current word (0..31) # t3 address of word containing bit, value of same word, value of bit # t5 loop control # t6 bit offset of least significant bit .text bitSlice3: li $v0,0 # error return value bltz $a0,exitBS3 # if (center bit < 0) error bge $a0,$a3,exitBS3 # if (center bit >= length) error li $t5,2 # loop control (3 loops) addi $t6,$a0,-1 # offset to the least significant bit of the 3-bit slice loopBS3: add $t0,$t5,$t6 # offset to the current bit within the bit string bltz $t0,loEdge # if (low edge) fix it up bge $t0,$a3,hiEdge # if (high edge) fix it up findBit: srl $t1,$t0,5 # t1 = word number = bitnumber / 32 sll $t1,$t1,2 # word address offset = word number * 4 andi $t2,$t0,0x1F # t2 = bit offset = (bit number) & 0x1F add $t3,$t1,$a2 # address(current word) lw $t3,0($t3) # value(current word) srlv $t3,$t3,$t2 # shift bit to the lsb andi $t3,1 # mask it saveBit: sll $v0,$v0,1 # make room to store the bit or $v0,$v0,$t3 # store it in v0 addi $t5,-1 # loop count = loop count - 1 bgez $t5,loopBS3 # loop if more to do j exitBS3 # all done loEdge: move $t3,$a1 # t3 = edge control bit bgez $t3,saveBit # use it if we can move $t0,$a3 # wrap and use the most significant bit addi $t0,-1 # last bit number = bit count - 1 j findBit # go get it hiEdge: move $t3,$a1 # t3 = edge control bit bgez $t3,saveBit # use it if we can li $t0,0 # wrap and use least significant bit j findBit # go get it exitBS3: j $ra # return to caller # --------------------------------------------------------------------------- # Converts an integer value from a textual representation to its machine representation # Requires: # a0 the address of the start of the textual representation # Must be a null terminated string. # Returns: # v0 the machine representation of the integer value # -1 => decode error # Uses: # t0 temp product # t1 temp product # t2 next char # t3 value of next char # t4 target of slt # t5 0=>decimal, 1=>hex # t6 number base, 10 or 16 decode_int: move $t5,$zero # (t5==0) => base 10 li $t6, 10 # base 10 multiplier li $t0,48 # t0 = '0' lbu $t1,0($a0) # t1 = 1st char bne $t0,$t1,decodeStart # not hex li $t0,88 # t0 = 'X' lbu $t1,1($a0) # t1 = 2nd char andi $t1,$t1,0xDF # force upper case bne $t0,$t1,decodeStart # not hex addi $t5,1 # (t5==1) => base 16 li $t6,16 # base 16 multiplier addi $a0,2 # skip over the '0x' decodeStart: move $v0,$zero # cumulative decoded value = 0 lbu $t2,0($a0) # t2 = c = next char beqz $t2,decodeDone # quit if char is null decodeLoop: addi $t3,$t2,-48 # t3 = val = c - '0' bltz $t3,decodeError # if (val < 0) error slt $t4,$t3,10 # t4 = (val<10) bnez $t4,decodeUseIt # if (val < 10) add it to cumulative value beqz $t5,decodeError # if (base 10), error andi $t3,$t2,0xDF # force upper case addi $t3,$t3,-65 # t3 = val = c - 'A' bltz $t3,decodeError # if (val < 0) error slti $t4,$t3,6 # t4 = (val<6) beqz $t4,decodeError # if (val >= 6) error addi $t3,10 # add in the value of 0xA decodeUseIt: mul $v0,$v0,$t6 # v0 = v0*base add $v0,$v0,$t3 # v0 = v0+val addi $a0,1 # a0++ lbu $t2,0($a0) # t2 = next char bnez $t2,decodeLoop # loop if char is non-null decodeDone: jr $ra # return decodeError: addi $v0,$zero,-1 # decoding error jr $ra # return # --------------------------------------------------------------------------- # printBitString function # a0 number of bits to print # a1 address(bit string), word aligned # t0 lots of uses # t1 current word offset into the bit string # t2 current word contents # t3 current bit offset # t4 address of 2-word array containing addresses of "0", "1" strings .data zeroStr: .asciiz " " oneStr: .asciiz "1" strings: .word zeroStr,oneStr .text printBitString: blez $a0,exitBitString # quit if nothing to print addi $t0,$a0,-1 # t0 = bitcount - 1 srl $t1,$t0,5 # t1 = word offset = (bitcount-1)/32 sll $t1,$t1,2 # make it a word address andi $t3,$t0,0x1F # t3 = bit offset = (bitcount-1) & 0x1F la $t4,strings # t4 = output strings address array pBSOuter: add $t0,$a1,$t1 # address(current word) lw $t2,0($t0) # t2 = value(current word) pBSInner: srlv $t0,$t2,$t3 # shift the bit andi $t0,1 # mask the bit sll $t0,$t0,2 # make it a word offset add $t0,$t0,$t4 # addr(addr(string)) lw $a0,0($t0) # addr(string) li $v0,4 # print_string syscall # addi $t3,$t3,-1 # bit offset = bit offset - 1 bgez $t3, pBSInner # loop if more bits li $t3,31 # bit offset = 31 addi $t1,$t1,-4 # word offset = word offset - 4 bgez $t1, pBSOuter # loop if more words exitBitString: jr $ra #