#####################################################################
#   Title:   Demonstrate passing information on the stack
#            Show how to "UpperCase" a string
#   Author:  Bary W Pollack
#   File:    UpCase.asm
#   Date:    Apr. 3, 2008 - 1700
#####################################################################

    .data
ttl:   .ascii  "\nDemonstrate passing info on the stack\n"
       .asciiz "and show how to \"uppercase\" a string\n\n"
get:   .asciiz "Please enter a string [Enter]: "
put:   .asciiz "In upper case, the string is:  "
buffr: .space   256     # space for 256 characters

#####################################################################

    .globl  main        # make main "global"
    .text

main:
    li      $v0, 4      # syscall code for print string
    la      $a0, ttl    # pointer to the string to be printed
    syscall

    li      $v0, 4      # syscall code for print string
    la      $a0, get    # pointer to the string to be printed
    syscall

    li      $v0, 8      # syscall code for read string
    li      $a1, 256    # Initial length of the buffer
    la      $a0, buffr  # pointer to the buffer that will hold the string
    syscall

    addiu   $sp, $sp, -4 # provide space for the address of the buffer
    la      $t0, buffr  # point to the string buffer
    sw      $t0, 0($sp) # save it in the stacak
    jal     UpperCase	# call UpperCase to "UpperCase" the string
    addiu   $sp, $sp, 4 # readjust the stack

    li	$v0, 4      # sycall code for put string
    la	$a0, put	# pointer to the string to be printed
    syscall

    li      $v0, 4      # print string code
    la      $a0, buffr  # address of the string to be printed
    syscall

    li      $v0, 10     # syscall code for EXIT
    syscall

#####################################################################
#   Stack - Variable Cross Reference
#     0: address of the string buffer
#   $t0: pointer to the current character in the buffer
#####################################################################

UpperCase:
    lw	$t0, 0($sp) # retrieve address of the string buffer
    li      $a1, 'a'    # lower case a
    li      $a2, 'z'    # lower case z
loop:
    lb	$t1, 0($t0) # grab next character
    beqz    $t1, rtn    # if NUL, then quit...
    blt	$t1, $a1, nxt  # skip conversion if < 'a'
    bgt     $t1, $a2, nxt  # skip conversion if > 'z'
    andi    $t1, $t1, 0xDF # mask with 1101 1111
    sb	$t1, 0($t0) # save the updated character
nxt:
    addiu	$t0, $t0, 1 # point at next character
    j       loop        # go back to start of loop
rtn:
    jr	$ra		# return to caller

    .end
