Creating a Single-Digit Adder using the MMIO Capabilities of MARS Simulator

Memory-mapped InputOutput in MIPS assembly homework help

.text .globl main main: lui $t0,0xffff # load address of receiver control lw $t1,0($t0) # load receiver control state ori $t1,$t1,2 # enable keyboard interrupts sw $t1,0($t0) # save receiver control state loop: b loop li $v0, 10 # exit the program syscall .ktext 0x80000180 # location of exception/interrupt handler la $k0,regspace sw $t0,($k0) # save t0 value sw $t1,4($k0) # save t1 value sw $t2,8($k0) # save t2 value sw $a0,12($k0) # save a0 value sw $ra,16($k0) # save ra value mfc0 $k0,$13 # load the cause register in k0 srl $t0,$k0, 2 # Extract exception code from $k0, bits 2-5 andi $t0,$t0, 0x1f bnez $t0,skip # if not zero is not an interrupt lui $t0,0xffff # load start address of I/O registers lw $a0,4($t0) # load received character la $t0,state lw $t1,($t0) # load current state beq $t1,0,state0 beq $t1,1,state1 beq $t1,2,state2 beq $t1,3,state3 state0: blt $a0,'0',error # see if the char was a digit bgt $a0,'9',error # if not, print error li $t1,1 # go to state 1 sw $t1,($t0) # save state la $t0,z addi $t1,$a0,-48 # convert ascii to integer sw $t1,($t0) # update total sum b print # print current char state1: bne $a0,'+',error # see if the char was a plus sign, if not, print error li $t1,2 # go to state 2 sw $t1,($t0) # save state b print # print current char state2: blt $a0,'0',error # see if the char was a digit bgt $a0,'9',error # if not, print error li $t1,3 # go to state 3 sw $t1,($t0) # save state la $t0,z lw $t1,($t0) # load current sum addi $t2,$a0,-48 # convert ascii to integer add $t1,$t1,$t2 # add digit sw $t1,($t0) # update total sum b print # print current char state3: bne $a0,'=',error # see if the char was a plus sign, if not, print error li $t1,0 # go to state 0 to start over sw $t1,($t0) # save state jal print_char # print equal sign la $t0,z lw $t1,($t0) # load current sum blt $t1,10,onedig # if it's only one digit, print it addi $t2,$t1,-10 # calculate remaining digit li $a0,'1' # print first a one jal print_char move $t1,$t2 onedig: addi $a0,$t1,48 # convert to ascii jal print_char # print sum li $a0,10 # to print a new line b print error: li $t1,0 # go to state 0 sw $t1,($t0) # save state li $a0,10 # to print a new line jal print_char li $a0,'E' # indicate error jal print_char li $a0,'R' # indicate error jal print_char li $a0,'R' # indicate error jal print_char li $a0,10 # to print a new line print: jal print_char skip: la $k0,regspace lw $t0,($k0) # restore t0 value lw $t1,4($k0) # restore t1 value lw $t2,8($k0) # restore t2 value lw $a0,12($k0) # restore a0 value lw $ra,16($k0) # restore ra value eret # return from exception # print the character in a0 print_char: lui $t0,0xffff # load start address of I/O registers wait: lw $t1,8($t0) # poll terminal status andi $t1,$t1,1 # see if it's ready to transmit beq $t1,$0,wait # if not, keep polling sw $a0,12($t0) # send character to display jr $ra .kdata regspace: .space 20 # space to save 5 registers state: .word 0 z: .byte 0