Search code examples
mipsmips32

Unsetting and resetting certain bits


For a homework assignment in school, I need to use a MMIO LED display where each led is exactly 2 bits stored within a byte. For the assignment I need to "move" these LEDs up, down, left, and right. I also need to set the color (I will be using 0x40 for this). Here's my issue:

When I click the "right" arrow to move the LED over 1 column, it remains in the current column when it should be returning to black (0x00). If I click right 4 times (moving over exactly 1 byte), I get another lit LED, leaving the original one there.

Here is my MIPS code:

getLedPattern:
move $t2, $s2
andi $t1, $t2, 0x3 #remainder of x / 4 is in $t0
sll $t0, $t2, 2 #x / 4 is in $t0
beq $t0, 0, case0
beq $t0, 1, case1
beq $t0, 2, case2
case3:
    andi $a0, 0xFFFFFFFC
    #insert $a1 into bits 0 and 1 of $a0 into $v0
    or $v0, $a0, $a1
    jr $ra

case2:
    andi $a0, 0xFFFFFCFF
    #insert $a1 into bits 2 and 3 of $a0 into $v0
    #srl $a1, $a1, 2
    or $v0, $a0, $a1
    jr $ra

case1:
    andi $a0, 0xFFFCFFFF
    #insert $a1 into bits 4 and 5 of $a0 into $v0
    #srl $a1, $a1, 4
    or $v0, $a0, $a1
    jr $ra

case0:
    andi $a0, 0xFCFFFFFF
    #insert $a1 into bits 6 and 7 of $a0 into $v0
    #srl $a1, $a1, 6
    or $v0, $a0, $a1
    jr $ra

setLED:
    addi $sp, $sp, -20
    sw $ra, 0($sp)
    sw $t0, 4($sp)
    sw $t1, 8($sp)
    sw $t2, 12($sp)
    sw $t3, 16($sp)

move $t5, $a0
sll $t6, $a1, 5     # y*32
srl $t2, $a2, 2     # x/4
add $t5, $t5, $t6
add $t5, $t5, $t2
lb $a0, 0($t5)
move $a1, $a3
jal getLedPattern
sb $v0, 0($t5)
move $s3, $t5

lw $ra, 0($sp)
lw $t0, 4($sp)
lw $t1, 8($sp)
lw $t2, 12($sp)
lw $t3, 16($sp)
addi $sp, $sp, 20
jr $ra

The logic is that it starts out at at memory location 0xFFFFOOO8 (top left LED), moves down one row (+32 bytes) and over x columns (plus x*bits). However, I can't seem to unset the current LED and move it over one. Any help would be appreciated. I believe that my or in getLedPattern: is wrong, but not 100% sure.

Hopefully, getting this correct I will be able to get this correct in a general sense (no LED display).


Solution

  • I guess that your constants for clearing bits are wrong. try the following instead:

    0xfffffffc  // or ~0x03
    0xfffffff3  // or ~0x0C
    0xffffffcf  // or ~0x30
    0xffffff3f  // or ~0xC0
    

    There are other oddity in your code:

    • s2 is used, but never set
    • s3 is set, but never used
    • case1 and case2 will never be reached because $t0 can hold nor 1 neither 2