##  Towers of Hanoi
##	as developed by Lin Jensen
##	in CSC 116 class
##	17 March 1999

##	Each Tower is represented by a word pointer
##	to an as yet unspecified structure
##
##	The operations to be performed on a tower are:
#		Remove a ring
##		Place a ring
##		Print the state of the tower

##  Version 2, actually implement the tower as a data structure, a mini-stack
##	sp, points to top of stack
##      the rings are represented by numeric characters in a string,
##	so that the characters 	"123\n" depict a stack with 3 rings
##		while		"  2\n" shows a stack with 1 ring of size 2
##	see the data segment for the full "view" of the stacks

#------------------------------------------------------------------------------  
	.text
	.globl __start

moveTower:	# move a tower from source to dest using spare, of n rings
		# moveTower (source, dest, spare, n ) - args. in
		#		$a0   $a1   $a2  $a3   as per MIPS conventions

# base case, n=0, do nothing!
	bnez	$a3, store
	jr	$ra
store:	# towers and return address on stack:
	sub	$sp, 16		#space for 4 words stack frame
	sw	$a0, 0($sp)	# source
	sw	$a1, 4($sp)	# dest
	sw	$a2, 8($sp)	# spare
	sw	$ra,12($sp)	#   save return address!

	sub	$a3, 1		# n-1

## moveTower (source, spare, dest, n-1)   move all but bottom ring to spare
#	lw	$a0, 0($sp)		#(it's already set)
	lw	$a1, 8($sp)
	lw	$a2, 4($sp)
	jal	moveTower

## moveRing  (source, dest)		  transfer the bottom ring		
	lw	$a0, 0($sp)	# source
	lw	$a1,4($sp)	# dest
	jal	moveRing

## moveTower (spare, dest, source, n-1)	  move them from spare back to dest
	lw	$a0, 8($sp)	# spare
	lw	$a1, 4($sp)	# dest
	lw	$a2, 0($sp)	# source
	jal	moveTower

# exit code
	add	$a3, 1		# restore to n
	lw	$ra,12($sp)	# restore return address
####				# don't need to restore $a0-$a2
	add	$sp, 16		# release stack frame
	jr	$ra		# return

#### ----------------------------------------------------------------------------
#
#	Main program, call moveTower and exit
#
#### ----------------------------------------------------------------------------

__start: 
	la	$a0, Tower1	#to start off, point to the "stack pointers"
	la	$a1, Tower2
	la	$a2, Tower3
	lw	$a3, NumberRings  # on Tower1 initially

	jal	moveTower

	li	$v0, 10
	syscall			# ciao........

#### ----------------------------------------------------------------------------
#	moveRing  pop top ring from source, (blank in it's place), push on dest
#		a0 - source tower
#		a1 - destination tower  
#	also print the new configuration  
#### ----------------------------------------------------------------------------

moveRing:
	sub	$sp, 4		
	sw	$ra, ($sp)
#   pop source stack    	  $a0 points to its "stack pointer"
	jal 	pop     	# $v0 is the size of ring popped
#   push the ring on dest stack
	move	$a0,$a1		# destination sp
	move	$a1,$v0		# ring to push
	jal	push

	la	$a0, view	# print all the towers!!!
	li	$v0,4
	syscall
	lw	$ra, ($sp)	# restore return address
	add	$sp, 4
	jr	$ra

pop:	# source stack
#
#	$a0 is the address in memory of the tower, represented by a "stack pointer"
#		giving the address of the top character on the tower's stack of rings
#	There are 2 levels of indirect addressing here
#
	lw	$t0,($a0)	# load source sp 
	lb	$v0,($t0)	# get top ring char as return value
	li	$t2,' '		# blank it from view
	sb	$t2,($t0)
	add	$t0, 1		# adjust sp and store it
	sw	$t0,($a0)	# store sp of this tower
	jr	$ra

push:	# the ring on dest stack
	lw	$t0,($a0)	# load sp for the tower we are using
	sub	$t0, 1		# make space on character stack
	sb	$a1, ($t0)	# store the ring there
	sw	$t0, ($a0)	# store madified stack pointer
	jr	$ra

#### ---------- DATA SEGMENT ----------------------------------------------
	.data

Tower1:	.word	stack1		#stack pointers to the stacks of chars
Tower2: .word	stack2
Tower3: .word	stack3
NumberRings:	.word	3

view:		# this ascii area gives a view of the Towers, on their side
	.ascii	"1:"
stack1:	.ascii	  "123\n"	# top of stack with the 3 rings
	.ascii	"2:   "		# Tower 2 is empty
stack2: .ascii	     "\n"	# point to top of empty stack
	.ascii	"3:   "
stack3: .asciiz      "\n-----\n"

# end of file hanoi2.asm
