#
# spim-puts.s: puts() function written in MIPS assembly language compatible
# with the SPIM simulator (brg 14-Dec-2002)
# run with: spim -mapped_io -file spim-puts.s
#

.data
str:
	.asciiz "Hello, world"

.text

main:
	addiu $sp, $sp, -4	# get some stack space
	sw $ra, 0($sp)		# save return address on stack
	la $a0, str			# get a pointer to hello world string
	jal puts			# print the string
	lw $ra, 0($sp)		# get our return address back
	addiu $sp, $sp, 4	# restore stack pointer
	jr $ra				# we're done.

puts:
    addiu $sp, $sp, -8	# get some stack space
    sw $ra, 0($sp)		# save regs on stack
    sw $s0, 4($sp)
	move $s0, $a0		# save a pointer to the string passed in
puts_loop:
	lb $a0, 0($s0)		# load the next char
	beqz $a0, puts_done	# if it is zero, end the loop
	jal putchar			# write the char
	addiu $s0, $s0, 1	# advance pointer to next char
	j puts_loop			# and loop.
puts_done:
	li $a0, 0x0D		# write a carriage return
	jal putchar
	li $a0, 0x0A		# write a line feed
	jal putchar
	li $v0, 0			# return zero
	lw $ra, 0($sp)		# restore regs
	lw $s0, 4($sp)
    addiu $sp, $sp, 8	# restore stack pointer
    jr $ra				# and return.

putchar:
	li $t0, 0xffff0008	# get transmitter control reg
	lw $t0, 0($t0)		# load it
	and $t0, $t0, 1		# check ready bit
	beqz $t0, putchar	# if not ready, loop
	li $t0, 0xffff000c	# get transmitter buffer reg
	sw $a0, 0($t0)		# store the char into it
putchar_loop:
	li $t0, 0xffff0008	# once again, wait for transmitter to be ready
	lw $t0, 0($t0)		# (we know it's printed the char, once it becomes ready)
	and $t0, $t0, 1
	beqz $t0, putchar_loop
	jr $ra				# ok, we're done

