# Program to swap two elements in an array.  In this example program, the array
# is of size 5, and the number of the entry to be swapped is entered at the 
# keyboard.  When the program is started the array is printed out, and the 
# program prompts you for the entry number.  If the entry number is too large 
# or too small, the program prompts you to try again.

# This program uses the system calls to do both input and output.  It is very
# linear, containing no subroutines.  

# Mf

# C Program:

# swap (int v[],int k) {
# 
#     int temp;
#
#     temp = v[k];
#     v[k] = v[k+1];
#     v[k+1] = temp;
# }

	.data
Array:	.word 6
	.word 8
	.word 14
	.word 3
	.word 22234

outst1:	.asciiz "\n\nArray before: "
outst2:	.asciiz "\nArray after: "
error:	.asciiz "\ninput out of range - please try again: "
quest:	.asciiz "\nplease enter number between 0 and 4 (inclusive): "
space:	.asciiz " "
instr:	.asciiz "elements to swap"
thanks:	.asciiz "\nThank you for playing - please come again!"
entry:	.word 0
	.word 0
nmbr:	.word 3

	.text
	.globl main		# program starts here

main:	li $v0,4		# syscall for print string
	la $a0,outst1		# address of string to print
	syscall			# print out the "before array" string

	li $8,0			# clear register 8
loop1:	lw $a0,Array($8)	# get first element of array
	li $v0,1		# print integer syscall
	syscall

	li $v0,4		# syscall for print string
	la $a0,space		# address of string to print
	syscall			# print out a space between numbers
	
	addi $8,$8,4		# increment counter
	bne $t0,20,loop1	# do until counter = 5 (5x4, actually)

	li $v0,4		# syscall for print string
	la $a0,quest		# address of string to print
	syscall			# ask for input

getnum:	la $a0,entry		# address of buffer to put result
	li $a1,2		# number of characters to get
	li $v0,8		# syscall for reading string
	syscall			# get number from keyboard, put in buffer

	lw	$10,entry	# get just-inputted offset (k)
	blt	$10,0x30,prntrr	# if input is less than '0', exit
	bge	$10,0x34,prntrr	# if input is greater than or equal to '4', exit

	andi	$10,0xf		# clear off ascii part of number
	la	$11,Array	# get array address from memory (v)

	sll	$10,$10,2	# $10 = k * 4 (calculate array offset)
	add	$12,$11,$10	# $12 = address of v[k] ($12 = v + k*4)

	lw	$13,0($12)	# $13 = v[k] 
	lw	$14,4($12)	# $14 = v[k+1] 

	sw	$14,0($12)	# v[k] = v[k+1]
	sw	$13,4($12)	# v[k+1] = temp (v[k])

# Now, print out new array

	li $v0,4		# syscall for print string
	la $a0,outst2		# address of string to print
	syscall			# print out "after" string

	li $8,0			# clear register 8
loop2:	lw $a0,Array($8)	# get first element of array
	li $v0,1		# print integer syscall
	syscall			# print numbers

	li $v0,4		# syscall for print string
	la $a0,space		# address of string to print
	syscall			# print space
	
	addi $8,$8,4		# increment counter
	bne $t0,20,loop2	# do until done

	la $a0,thanks		# address of thanks string
	li $v0,4		# syscall for print string
	syscall			# print thanks

	jr $31			# return to SPIM monitor

prntrr:	la $a0,error		# address of "try again" string
	li $v0,4		# syscall for print string
	syscall			# print "try again"

	j getnum		# go back to routine to get chars from keyboard

	.end main
