################################################################################
##
## LSU EE 4720 Spring 2004 Homework 2 Solution
##
##
 # Assignment: http://www.ece.lsu.edu/ee4720/2004/hw2.html

################################################################################
## Problem 1 Solution

# Solution Note
#
# The message, "It's a cookbook!" is from an old Twilight Zone
# episode.  Aliens have given us a book with the English title "To
# Serve Man" but its text is in the alien language.  Many people
# accept trips to the alien planet until their language is deciphered
# and the true topic of the book is discovered.
#
# My apologies if I spoiled the ending for anyone.


        ## Register Usage
        #
        # $a0: Procedure call argument:  Address of text.
        # $a1: Procedure call argument:  Address at which to write decoded msg.
        # There are no return values.

        # Text at "->" shows how points were implemented in the solution.

        # [x] The secret message is a short English sentence.
        #     Make sure your message is not just a part of the original text.
        # [x] Avoid multiplication instructions and especially division and mod.
        #     ->  Used shift-and-adds.
        # [x] Try to use an efficient way to write the secret message.
        #     ->  Used one sw instead of four sb's.
        # [x] Fill as many branch delay slots as possible.
        #     ->  Just one unfilled.
        # [x] Do not put an insn in a loop if it could be placed before the loop.
        # [x] Streamline the code.  This is important.
        # [x] Make sure the message is null terminated.

extract:
        addi $t7, $0, 10  # \n
        addi $t6, $0, 32  # Blank
        addi $t5, $0, 13  # Handy constant, number of digits - 1.
        add $t3, $0, $0   # Radix 5 digit count.
        addi $v0, $0, 0   # Integer value of radix-5 number.

        # Loop until \n (end of line) found.
        #
        # Program will spend most if its time in this loop so keep it
        # tight, in particular don't look for blanks here.  Loop would
        # be even tighter if we could be sure string ends with a \n.
LOOP:
        lb $t0, 0($a0)
        beq $t0, $0, EXIT
        addi $a0, $a0, 1
        bne $t0, $t7, LOOP
        nop

        # At this point $a0 is address of character after \n:
        #
	# "reformatted its    \n"  (\n is one character)
        #                       ^
        #                      $a0

        # Loop backwards, looking for a non-blank.
        #
        addi $t8, $a0, 1
BLOOP:
        lb $t0, -3($t8)
        beq $t0, $t6, BLOOP
        addi $t8, $t8, -1

        # At this point $t8 is address of second blank at end:
        #
	# "reformatted its    \n"  (\n is one character)
        #                  ^    ^
        #                 $t8  $a0

        sub $t1, $a0, $t8    # Compute number of blanks at end of line.

        # Compute v0 = v0 * 5 + t1
        #
        sll $t2, $v0, 2
        add $v0, $v0, $t2
        add $v0, $v0, $t1

        # Get another digit (LOOP) unless we already have 14 digits.
        #
        bne $t3, $t5, LOOP
        addi $t3, $t3, 1

        # At this point $v0 has four characters of the decoded message.

        # Store the four characters, reset counters, and get first digit.
        #
        sw $v0, 0($a1)
        addi $a1, $a1, 4
        addi $v0, $0, 0
        j LOOP
        addi $t3, $0, 0

EXIT:
        jr $ra
        sb $0, 0($a1)    # Null-terminate message string.