; read two numbers using a subroutine and store them to memory

	.ORIG x3000		; starting address is x3000

	JSR READNUM		; read two numbers and store them
	ST R0,NUM1
	JSR READNUM
	ST R0,NUM2
	HALT

; subroutine developed as an extension of the
; earlier binary code

; read a decimal number from the keyboard,
; convert it from ASCII to 2's complement, and
; return it in R0.  If any non-numeric character 
; is pressed, or the number overflows, print an 
; error message and start over.

; R0 holds the value of the last key pressed
; R1 holds the current value of the number being input
; R2 holds the additive inverse of ASCII '0' (0xFFD0)
; R3 is used as a temporary register

READNUM				; the subroutine to read a number

	ST R7,SAVE_R7		; TRAP overwrites R7, so must save
	ST R3,SAVE_R3		; callee saves register values
	ST R2,SAVE_R2
	ST R1,SAVE_R1

	LD R2,NEG_0		; put the value -x30 in R2
	AND R1,R1,#0		; clear the current value

READ_LOOP
	GETC			; read a character
	OUT			; echo it back to monitor
	ADD R3,R0,#-10		; compare with ENTER
	BRz DONE		; if ENTER pressed, done

	ADD R0,R0,R2		; subtract x30 from R0
	BRn BAD_KEY		; smaller than '0' means error
	ADD R3,R0,#-10		; check if > '9'
	BRzp BAD_KEY		; greater than '9' means error
	ADD R3,R1,R1		; sequence of adds multiplies R1 by 10
	BRn OVERFLOW		; overflow, but not really necessary here
	ADD R3,R3,R3
	BRn OVERFLOW		; overflow, but not really necessary here
	ADD R1,R1,R3
	BRn OVERFLOW		; overflow
	ADD R1,R1,R1
	BRn OVERFLOW		; overflow
	ADD R1,R1,R0		; finally, add in new digit
	BRn OVERFLOW		; overflow
	BRnzp READ_LOOP		; get another digit

DONE
	ADD R0,R1,#0		; move R1 into R0	
	LD R1,SAVE_R1		; restore register values for caller
	LD R2,SAVE_R2
	LD R3,SAVE_R3
	LD R7,SAVE_R7

	RET			; return

; print error message: "non-digit pressed"
BAD_KEY
	LEA R0,BK_MSG		; point R0 to the start of the string
PRINT_ERR
	PUTS			; the trap that you're not allowed to use in MP2
	AND R1,R1,#0		; reset current value
	BRnzp READ_LOOP		; try reading again

; print error message: "overflow"
OVERFLOW
	LEA R0,OF_MSG		; point R0 to the start of the string
	BRnzp PRINT_ERR

SAVE_R1	.BLKW 1		; storage for saved register values
SAVE_R2	.BLKW 1
SAVE_R3	.BLKW 1
SAVE_R7	.BLKW 1
NEG_0	.FILL xFFD0	; the additive inverse of ASCII '0'
NUM1	.BLKW 1		; storage for the results
NUM2	.BLKW 1

; error messages.  The sequence \n means newline and is replaced
; with a single ASCII linefeed character (#10).  Similar sequences
; include \r for #13 (carriage return), \t for #9 (TAB), \\ for 
; backslash, etc.
BK_MSG	.STRINGZ "\nnon-digit pressed\n"
OF_MSG	.STRINGZ "\noverflow\n"

	.END