#include <cosc065.h>

/*************************
 * COSC 065 Fall 2005    *
 * Lecture 17 Demo       *
 * D.W. Brylow           *
 * brylow at mscs.mu.edu *
 *************************/
	
.rodata
FMT:	.string "%d\n"

#define EOF -1
	
.text
.globl main

main:
        /* Function prolog. */
        /* Sets up environment for user program to execute. */
        stwu    r1,-32(r1)  /* Make room on Stack for O/S values.  */
        mflr    r0          /* Store O/S return address on Stack.  */
        stw     r0,36(r1)
        stw     r31,28(r1)  /* Store O/S frame pointer on Stack.   */
        mr      r31,r1      /* new stack top is now frame pointer. */

        /* Start of your program. */

mainloop:	
	bl	getInt	    /* Call getInt and print out the      */
                            /*  results until EOF is seen.        */
	cmpwi	r3, EOF
	beq	done
	
	mr	r4, r3      /* Second arg to printf() is my int.  */
	lis	r3, FMT@ha  /* First arg to printf() is format string. */
	addi	r3, r3, FMT@l
	bl      printf

	b	mainloop
	
done:	
        /* End of your program. */

        /* Function epilogue. */
        /* Restores the environment from the O/S. */
        lwz r11,0(r1)     /* Restore O/S Stack pointer.          */
        lwz r0,4(r11)     /* Restore O/S return address.         */
        mtlr r0           
        lwz r31,-4(r11)   /* Restore O/S frame pointer.          */
        mr r1,r11
	li r3, 0          /* Return value of 0 (normal exit).    */
        blr               /* Return to Operating System.         */


/*******************
 * getInt
 * Calls getchar repeatedly to read in characters from
 *  the O/S which are interpreted as a multi-digit,
 *  positive integer.  Filters out unwanted non-digits.
 *******************/
#define INT r13	          /* Current value of integer read so far. */
#define OLDLR r14	  /* Return address of caller.             */

getInt:
	mflr	OLDLR     /* Keep return address safe. */
	
	li	INT, 0	  /* Initialize integer value. */

intloop:	
	bl	getchar   /* Get a character from O/S. */

	cmpwi	r3, EOF   /* Getchar returns EOF when  */
	beq	eof       /*  end of file is reached.  */
	
	cmpwi	r3, 0x0A  /* If newline character      */
	beq	intdone   /*  then we're done with INT */

	cmpwi	r3, 0x30  /* Throw out ASCII chars     */
	blt	intloop   /*  less than '0'.           */

	cmpwi	r3, 0x39  /* Throw out ASCII chars     */
	bgt	intloop   /*  greater than '9'.        */

			  /* Subtract ASCII value from */
			  /*  '0' to get integer value */
	subi	r3, r3, 0x30

			  /* Slide current value up a  */
			  /*  column, and add in the   */
	                  /*  newest digit on the right*/
	mulli	INT, INT, 10
	add	INT, INT, r3
	b	intloop

eof:	mr	INT, r3   /* If EOF, return an EOF.    */
	
intdone:
	mtlr	OLDLR	  /* Restore return address.   */
	mr	r3, INT   /* Send result back in r3.   */
	blr		  /* Return to caller.         */

