###########################################################################
# Bubble Sort Assembly Language Example
# Author: W. Schilling
#
# This example shows how one can read in 5 numbers from the keyboard
# and sort them in ascending order.
# The comments have questions embedded which you should read in order to really understand what is happening in the code.
###########################################################################
.data
myArray:	.space 20	# <<<<<  What is this doing?


.text
###########################################################################
# function: main
# This is the main program.  It will read 5 numbers, sort them in ascending order, and print them out to the console.
# Parameters:
##########################################################################
main:
	la $a0, myArray		# Load the address of the array into memory.
	li $a1, 5		# Load a constant value of 5 into $a1, representing the 5 numbers to read in.
	jal getInput		# Call the get Input method to read in the values.
	
	la $a0, myArray		# Load the address of the array into memory.
	li $a1, 5		# Load a constant value of 5 into $a1, representing the 5 numbers to read in.
	jal sortArray		# Call the get Input method to read in the values.
	
	
	la $a0, myArray		# Load the address of the array into memory.
	li $a1, 5		# Load a constant value of 5 into $a1, representing the 5 numbers to read in.
	jal printArray		# Call the get Input method to read in the values.

	li $v0, 10		# Exit the program.
	syscall		
			


###########################################################################
# function: printArray
# This method will print an array of integers to the console.
#
# Parameters:
#   $a0 - A pointer which has the first address of the array in memory.
#   $a1 - An integer designating the length of the array.
##########################################################################
printArray:
	# Function preamble.
	# Put the return address on the stack.
   	addi $sp, $sp, -4	# Adjust the stack pointer.
	sw $ra, 0($sp)		# STore the item on the stack.
	
	move $t0, $a0

printArrayLoop1:
	ble $a1, 0, endPrintArray	# Exit the loop if the conditions are not correct.
	
	lw $a0, 0($t0)		# Load the integer into memory from the array.
	li $v0, 1		# Printout the integer.
	syscall
	
	addiu $t0, $t0, 4	# <<<========================================Why are we adding 4 here?
	addiu $a1, $a1, -1	# <<<<======================================== What are we doing here?
	j printArrayLoop1

endPrintArray:
   #function cleanup
   # Put the return address back in the register.
   lw $ra, 0($sp)		# Load the data into the register.
   addi $sp, $sp, 4	# Move the stack pointer a value of 4.
   jr $ra


###########################################################################
# function: getInput
# This method will read a set of n numbers and placxe them into the array.
#
# Parameters:
#   $a0 - A pointer which has the first address of the array in memory.
#   $a1 - An integer designating the length of the array (or how many number to read in.)
##########################################################################
getInput:
	# Function preamble.
	# Put the return address on the stack.
   	addi $sp, $sp, -4	# Adjust the stack pointer.
	sw $ra, 0($sp)		# STore the item on the stack.
	
	move $t0, $a0

getInputLoop1:
	ble $a1, 0, endGetInput	# Exit the loop if the conditions are not correct.
	
	li $v0, 5		# Read in an integer.
	syscall
	
	sw $v0, 0($t0)		# Store the value into memory.
	addiu $t0, $t0, 4	# <<<========================================Why are we adding 4 here?
	addiu $a1, $a1, -1	#<<<<======================================== What are we doing here?
	j getInputLoop1

endGetInput:
   #function cleanup
   # Put the return address back in the register.
   lw $ra, 0($sp)		# Load the data into the register.
   addi $sp, $sp, 4	# Move the stack pointer a value of 4.
   jr $ra



###########################################################################
# function: sortArray
# This method will sort an array in ascending order.
# The array is a set of continguos memory locations starting at an address
# and going on for a given size.
# When the method is finished, the data will be sorted from
# smallest to largest values.
#
# Parameters:
#   $a0 - A pointer which has the first address of the array in memory.
#   $a1 - An integer designating the length of the array.
##########################################################################
sortArray:
   # Function preamble.
   # Put the return address on the stack.
   	addi $sp, $sp, -4	# Adjust the stack pointer.
	sw $ra, 0($sp)		# STore the item on the stack.

	li $t0, 0		# $t0 is going to represent the index1 value for the loop.
loop1:
	#for (int index1 = 0; index1 < size; index1++)
	#{
	# $t3 represents the currently referenced element in the array.
	move $t1, $a0 		# $t1 is going to represent the actual address that is to be accessed, or the current element on the array.
	
	li $t2, 0		# Initialize the index to 0.
        #for (int index2 = 0; index2 < size; index2++)
        #{
loop2:
     	lw $t3, 0($t1) # Load a register with the data that is in memory.
      	lw $t4, 4($t1) # Load the next element into memory.
      	
        #    if (array[index2]>array[index2+1])
	#    {
	#      int temp = array[index2+1];
	#      array[index2+1] = array[index2];
	#      array[index2] = temp;
	#    }
     	ble $t3, $t4, doNotSwapElements	# <===================================== What am I doing here?  Why am I doing it? <======================================    

      	sw $t3, 4($t1) # Load a register with the data that is in memory.
      	sw $t4, 0($t1) # Load the next element into memory.
      	
doNotSwapElements:
	addiu $t1, $t1, 4	# What am I doing here?
	addiu $t2, $t2, 1	# What am I doing here?

#	  }
#	}
	addi $t5, $a1, -1	# <<<<<<<<<<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++What are we doing here and why?
	bltu $t2, $t5, loop2	# Determine if we still need to keep executing the inner loop.
	addiu $t0, $t0, 1	# If not, perform the post increment option for the outer loop.

	bltu $t0, $a1, loop1	# Determine if we need to continue the outer loop or not.

endSortArray:
   #function cleanup
   # Put the return address back in the register.
   lw $ra, 0($sp)		# Load the data into the register.
   addi $sp, $sp, 4	# Move the stack pointer a value of 4.
   jr $ra
   


