
*	ReadInt.asm (of PCQ Pascal runtime library)
*	Copyright (c) 1989 Patrick Quaid

*	This routine reads an integer from a text file.  Note that
*	normal files and standard input are handled very differently.  This
*	is because we always have the next character from a normal file in
*	its buffer, but we would not require the same from standard in
*	because it would make the user type something on the terminal.

	SECTION	ONE

	XREF	_p%readonechar
	XREF	_p%getthatchar
	XREF	stdinbuffed
	XREF	_p%readarbbuf

	XDEF	_p%readint
_p%readint

* At the outset, a0 has the address of the variable and the address
* of the file record is on the stack

	move.l	a0,-(sp)	; save the variable address
	move.l	8(sp),a0	; get the file record
	move.l	a0,d0
	bne	readintfile	; if it is a file, go around

	moveq	#0,d1		; clear the number in case of eof
1$	jsr	_p%readonechar	; get the next character
	jsr	_p%getthatchar	; get infile^
	cmp.b	#' ',d0		; is it a space?
	beq	1$		; if so, read on
	cmp.b	#9,d0		; is it a tab?
	beq	1$		; read on

	moveq.l	#0,d1		; starts at zero
	moveq.w	#1,d2		; and positive
	cmp.b	#'-',d0		; is it the minus sign?
	bne.s	3$		; if not, go around.
	moveq.w	#-1,d2		; negative numbers
	bra.s	6$		; eat the minus sign

3$	cmp.b	#'0',d0		; is it numeric?
	bge.s	7$		; if > 0 then continue
	move.b	#-1,stdinbuffed	; if not, re-buffer char
	bra.s	4$		; and leave
7$	cmp.b	#'9',d0		; numeric?
	ble.s	8$		; if so, go on
	move.b	#-1,stdinbuffed	; if not, re-buffer char
	bra.s	4$		; and leave
8$	asl.l	#1,d1		; d1 = d1 * 2
	move.l	d1,-(sp)	; store d1 * 2
	asl.l	#2,d1		; d1 = d1 * 4 (* 8 total)
	add.l	(sp)+,d1	; finally, d1= d1*8 + d1*2= d1*10
	sub.b	#'0',d0		; get the actual number
	and.l	#255,d0		; always positive, so now it's long
	add.l	d0,d1		; d1= d1*10 + d0
6$	jsr	_p%readonechar	; read next char
	jsr	_p%getthatchar	; move new char into d0
	bra	3$		; and start again
4$	move.l	(sp)+,a0	; get address of variable
	tst.w	d2		; is this negative?
	bpl.s	5$		; if not, skip
	neg.l	d1		; if so, negate the result
5$	move.l	d1,d0		; store final number
	rts

readintfile:			; read an int from a file
	moveq	#0,d1		; clear the number in case of eof
	bra.s	2$		; skip the first read
1$	tst.b	12(a0)		; at eof yet?
	bne	4$		; if so, leave
	jsr	_p%readarbbuf	; get the next character
2$	move.b	4(a0),d0	; get infile^
	cmp.b	#' ',d0		; is it a space?
	beq	1$		; if so, read on
	cmp.b	#9,d0		; is it a tab?
	beq	1$		; read on

	moveq.l	#0,d1		; starts at zero
	moveq.w	#1,d2		; and positive
	cmp.b	#'-',d0		; is it the minus sign?
	bne.s	3$		; if not, go around.
	moveq.w	#-1,d2		; negative numbers
	bra.s	6$		; eat the minus sign

3$	cmp.b	#'0',d0		; is it numeric?
	blt.s	4$		; if not, go away
	cmp.b	#'9',d0		; numeric?
	bgt.s	4$		; if not, leave
	asl.l	#1,d1		; d1 = d1 * 2
	move.l	d1,-(sp)	; store d1 * 2
	asl.l	#2,d1		; d1 = d1 * 4 (* 8 total)
	add.l	(sp)+,d1	; finally, d1= d1*8 + d1*2= d1*10
	sub.b	#'0',d0		; get the actual number
	and.l	#255,d0		; always positive, so now it's long
	add.l	d0,d1		; d1= d1*10 + d0
6$	tst.b	12(a0)		; at eof yet?
	bne.s	4$		; if so, leave
	movem.l	d1/d2,-(sp)	; save number and sign for now
	jsr	_p%readarbbuf	; read next char
	movem.l	(sp)+,d1/d2	; retrieve them
	move.b	4(a0),d0	; move new char into d0
	bra	3$		; and start again
4$	move.l	(sp)+,a0	; get address of variable
	tst.w	d2		; is this negative?
	bpl.s	5$		; if not, skip
	neg.l	d1		; if so, negate the result
5$	move.l	d1,d0		; store final number
	rts

	END
