;
; SYSLIB Module Name:  SEVAL
; Author:  Richard Conn
; SYSLIB Version Number:  2.0
; Module Version Number:  1.0
; Module Entry Points:
;	EVAL
; Module External References:
;	CAPS		EVAL10		EVAL16		EVAL2
;	EVAL8
;

;
;  EVAL --
;	On input, HL points to a string of ASCII binary, octal, decimal,
; or hexadecimal characters to convert to binary; this string may take
; any of the following forms --
;
;	bbbbbbbbbbbbbbbbB -- b=0 or b=1; binary string
;	ttttt or tttttD -- 0<= t <= 9; decimal string
;	hhhhH or hhhhX -- 0<= h <= F; hexadecimal string
;	oooooooO or oooooooQ -- 0<= o <=7; octal string
;
;	On return, DE = value, HL points to next byte after
; string, A=E; BC is not affected.
;	On return, CARRY Set means error, and HL pts to byte after error
;

	EXT	CAPS	; CAPITALIZATION ROUTINE
	EXT	EVAL16	; CONVERT HEX STRING
	EXT	EVAL10	; CONVERT DEC STRING
	EXT	EVAL8	; CONVERT OCT STRING
	EXT	EVAL2	; CONVERT BIN STRING

EVAL::
	PUSH	B	; SAVE BC
	PUSH	H	; SAVE PTR TO 1ST CHAR
	XRA	A	; A=0
	STA	CFLAG	; SET CHARACTER FOUND FLAG TO NULL

;  Find end of string
FEND:
	MOV	A,M	; GET BYTE
	CALL	CAPS	; CAPITALIZE
	SUI	'0'	; ASSUME HEX
	JC	FEDONE	; DONE
	CPI	10	; 0-9?
	JC	FECONT	; CONTINUE
	SUI	7
	CPI	16	; A-F?
	JNC	FEDONE

;  Digit found -- set flag and point to next
FECONT:
	MVI	A,1	; GET A 1
	STA	CFLAG	; SET FLAG
	INX	H	; PT TO NEXT
	JMP	FEND

;  Found end of string
FEDONE:
	MOV	A,M	; GET OFFENDING CHAR
	CALL	CAPS	; CAPITALIZE
	MOV	C,A
	DCX	H	; GET PREVIOUS CHAR (POSSIBLY BINARY OR DEC)
	MOV	A,M	; GET IT
	CALL	CAPS	; CAPITALIZE
	MOV	B,A
	POP	H	; RESTORE POINTER TO 1ST CHAR IN STRING
	LXI	D,0	; SET ZERO VALUE (ERROR EXIT)
	LDA	CFLAG	; ANY CHARS?
	JZ	DONE	; DONE IF NONE

;  Determine type of string (H,X=hex; O,Q=oct; B=bin; D,other=dec)
	MOV	A,C	; GET TERMINATING CHAR
	CPI	'H'	; HEX
	JZ	EHEX
	CPI	'X'
	JZ	EHEX
	CPI	'O'	; OCTAL
	JZ	EOCT
	CPI	'Q'
	JZ	EOCT
	MOV	A,B	; GET PREVIOUS CHAR FOR BINARY CHECK
	CPI	'B'	; BINARY?
	JZ	EBIN

;  Evaluate string as decimal
	CALL	EVAL10	; EVALUATE AS DECIMAL
	MOV	A,M	; MAY PT TO D
	CALL	CAPS
	CPI	'D'	; INCR HL IF SO
	JNZ	DONE
	INX	H	; PT TO NEXT
	JMP	DONE

;  Evaluate string as hexadecimal
EHEX:
	CALL	EVAL16	; EVAUATE AS HEXADECIMAL
	MOV	A,M	; MUST PT TO H OR X
	CALL	CAPS
	INX	H	; PT TO NEXT
	CPI	'H'
	JZ	DONE
	CPI	'X'
	JZ	DONE

;  String Error -- set flag
ERROR:
	MOV	A,E	; LOW-ORDER IN A
	STC		; SET CARRY FLAG FOR ERROR
	POP	B	; RESTORE BC
	RET

;  Evaluate string as octal
EOCT:
	CALL	EVAL8	; EVALUATE AS OCTAL
	MOV	A,M	; MUST PT TO O OR Q
	CALL	CAPS
	INX	H	; PT TO NEXT
	CPI	'O'
	JZ	DONE
	CPI	'Q'
	JZ	DONE
	JMP	ERROR	; ERROR OTHERWISE

;  Flag buffer
CFLAG:	DS	1	; 0 IF NO CHARS IN STRING, 1 OTHERWISE

;  Evaluate string as binary
EBIN:
	CALL	EVAL2	; EVALUATE AS BINARY
	MOV	A,M	; MUST PT TO B
	CALL	CAPS
	INX	H	; PT TO NEXT
	CPI	'B'
	JNZ	ERROR

;  Done with evaluation -- no error
DONE:
	MOV	A,E	; LOW-ORDER IN A
	ORA	A	; CLEAR CARRY FLAG
	POP	B	; RESTORE BC
	RET

	END
