h49233
s 00095/00000/00000
d D 1.1 83/03/17 14:37:58 tes 1 0
c date and time created 83/03/17 14:37:58 by tes
e
u
4
U
t
T
I 1
GSX_Code	CSeg	Byte	Public

; NParse	Parse a number into Dx

;       Call NParse(FcbPtr,BufferPtr)		{Near PL/M invocation}

;	Dword Ptr FcbPtr and Dword Ptr BufferPtr are used for FGetCh.

; Al contains whitespace or possible first digit of number
; FGetCh used to fetch next characters
; Return in Dx an integer, if found
; Return carry set if no number found

	Public	NParse

	Extrn	FSkipBl			:Near
	Extrn	FGetCh			:Near

OldDs		Equ	Ss:(Word Ptr 8)[Bp]
OldAx		Equ	Ss:(Word Ptr 6)[Bp]
OldAl		Equ	Ss:(Byte Ptr 6)[Bp]
OldCx		Equ	Ss:(Word Ptr 4)[Bp]
OldDx		Equ	Ss:(Word Ptr 2)[Bp]
OldBp		Equ	Ss:(Word Ptr 0)[Bp]
ReturnAddress	Equ	Ss:(Dword Ptr (OldDs+2))[Bp]
BufferPtr	Equ	Ss:(Dword Ptr (ReturnAddress+2))[Bp]
FcbPtr		Equ	Ss:(Dword Ptr (BufferPtr+4))[Bp]

NParse:	Push	Ds			; Save caller's registers
	Push	Ax
	Push	Cx
	Push	Dx
	Push	Bp			;  & stack frame
	Mov	Bp,Sp			; Point into stack

	Lds	Cx,FcbPtr		; FGetCh needs FcbPtr
	Push	Ds
	Push	Cx
	Lds	Cx,BufferPtr		;  & BufferPtr
	Push	Ds
	Push	Cx
	Call	FSkipBl			; Skip until non-whitespace

	Call	NDigitLook		; See if first non-whitespace is digit
	Jc	NParseQuit		; Quit if number not found

	Sub	Dx,Dx			; Start with a zero

; Ascii digit in Al; accumulated number in Dx
NParseLoop:
	Cbw				; 0 to Ah
	Sub	Al,'0'			; Make digit into value
	Mov	Cx,Ax			; New digit in Cx
	Mov	Al,10			; 10 times previous accum
	Mul	Dx			;  plus this digit
	Add	Ax,Cx			;  makes new
	Xchg	Ax,Dx			;  accumulated number

	Call	NDigitGet		; Get next possible number byte
	Jnc	NParseLoop		; Loop until digits accumulated

	Mov	OldDx,Dx		; Return number found in Dx
	Clc				; Some number was found; reset carry

NParseQuit:
	Mov	OldAl,Al		; Return current char in Al
	Pop	Bp			; Restore caller's registers
	Pop	Dx
	Pop	Cx
	Pop	Ax
	Pop	Ds

	Ret	8			; Return to caller

	Eject

NDigitGet:
	Lds	Cx,FcbPtr		; FGetCh needs FcbPtr
	Push	Ds
	Push	Cx
	Lds	Cx,BufferPtr		;  & BufferPtr
	Push	Ds
	Push	Cx
	Call	FGetCh			; Get possible next number byte

NDigitLook:
	Cmp	Al,'0'			; Is it a digit?
	Jb	NDigitQuit		; Return with carry set if not digit
	Cmp	Al,'9'+1		; In digit range?
	Cmc				; Reset carry if in range

NDigitQuit:
	Ret				; Return with carry set if not in range

	End
E 1
