;
; HCS02X04.SRC
;
; Intel-Hex-Reader
;
	ORG	04800H
;
hexbuf:		DS	256
datbuf:		DS	256
hexpoint:	DS	2	; pointer to character in error
hexaddr:	DS	2	; address of hex-record
hextype:	DS	1	; type of hex-record
hexstat:	DS	1	; status of hex-load, 0 if OK
hexchar:	DS	1	; last character read
;
	ORG	04020H
;
atonib:
	cjne	a,#'0',$+3
	jc	atn0		; below      0 - invalid
	cjne	a,#'9'+1,$+3
	jc	atnd        	; between 0..9 - decimal
	cjne	a,#'A',$+3
	jc	atna		; between 9..A - invalid
	cjne	a,#'F'+1,$+3
	jc	atnh		; between A..F - hex
	jmp	atnz		; above      F - invalid
atnh:
	clr	c
	subb	a,#'A'-10
	clr	c
	ret
atnd:
	clr	c
	subb	a,#'0'
	clr	c
	ret	
atn0:
	mov	a,#010H
	setb	c
	ret
atna:
	mov	a,#012H
	setb	c
	ret
atnz:
	mov	a,#014H
	setb	c
	ret
;
rchar:
	mov	dpl,r0
	mov	dph,r2
	movx	a,@dptr
	inc	dptr
	mov	r0,dpl
	mov	r2,dph
	mov	dptr,#hexchar
	movx	@dptr,a
	ret	

;
rbyte:
	lcall	rchar
	lcall	atonib
	jc	rbyex
	swap	a

	mov	r7,a
	lcall	rchar
	lcall	atonib
	jc	rbyex
	orl	a,r7
	clr	c
rbyex:
	ret
;	clr	acc.5		; convert to uppercase

; --- read byte and incorporate in checksum
;
rbchk:
	lcall	rbyte
	jc	rbcx
	mov	r7,a
	mov	a,r6
	clr	c
	subb	a,r7
	mov	r6,a
	mov	a,r7
	clr	c
rbcx:
	ret
;
; --- read intel-hex from HEXBUF
;
rhex:
	mov	r0,#LOW(hexbuf)
	mov	r2,#HIGH(hexbuf)
	mov	dptr,#hexpoint
	mov	a,r0
	movx	@dptr,a
	inc	dptr
	mov	a,r2
	movx	@dptr,a
rhexp:
	mov	dptr,#hexpoint
	movx	a,@dptr
	mov	r0,a
	inc	dptr
	movx	a,@dptr
	mov	r2,a
rhexr:
	mov	dptr,#hexstat
	clr	a
	movx	@dptr,a		; reset status to OK
	mov	r6,#0		; initialize checksum
	lcall	rchar
	cjne	a,#':',rhxnocol
	lcall	rbchk		; read length
	jc	rhxerrx

	mov	r4,a		; keep as counter in R4
	lcall	rbchk		; read high address
	jc	rhxerrx
	mov	r3,a		; save in R3
	mov	dptr,#hexaddr+1
	movx	@dptr,a		; memorize high address
	lcall	rbchk		; read low address
	jc	rhxerrx
	mov	r1,a
	mov	dptr,#hexaddr
	movx	@dptr,a		; memorize low address
	lcall	rbchk		; read record type
	jc	rhxerrx
	mov	dptr,#hextype
	movx	@dptr,a		; memorize type
	cjne	a,#0,rhxndat
; ------------------------------ TYPE 0: data record
	cjne	r4,#0,rhxdloop
	jmp	rhxcxum
rhxdloop:			
	lcall	rbchk		; read data byte
	jc	rhxerrx
	mov	dpl,r1
	mov	dph,r3
	movx	@dptr,a		; store data byte
	inc	dptr
	mov	r1,dpl
	mov	r3,dph
	djnz	r4,rhxdloop	; repeat for all data bytes
	jmp	rhxcxum
rhxndat:
	cjne	a,#1,rhxneof
; ------------------------------ TYPE 1: EOF record
	cjne	r4,#0,rhxeloop
	jmp	rhxcxum
rhxeloop:
	lcall	rbchk		; consume any data bytes
	jc	rhxerrx
	djnz	r4,rhxeloop
	jmp	rhxcxum
; ------------------------------ end of record, read checksum 
rhxcxum:
	lcall	rbchk
	jc	rhxerrx
	mov	a,r6
	cjne	a,#0,rhxecxum
	mov	a,#0
	jmp	rhxerrx
rhxneof:
	jmp	rhxnotyp
;
rhxerrx:
	mov	dptr,#hexstat
	movx	@dptr,a
	mov	dptr,#hexpoint
	mov	a,r0
	movx	@dptr,a
	inc	dptr
	mov	a,r2
	movx	@dptr,a
	ret
;
rhxnocol:			; line did not start with ':'
	cjne	a,#'.',rhxnoind ; is it '.' (EOF) ?
	mov	a,#0		; '.', indicate success
	setb	c
	ljmp	rhxerrx
;
rhxnoind:
	mov	a,#2
	setb	c
	ljmp	rhxerrx
rhxnodig:
	mov	a,#4
	setb	c
	ljmp	rhxerrx
rhxnotyp:
	mov	a,#6
	setb	c
	ljmp	rhxerrx
rhxecxum:
	mov	a,#8
	setb	c
	ljmp	rhxerrx
;
;
; -------------------------------------------------------------------
;
rhexl:
	anl	psw,#011100111B
	mov	r5,#'~'		; prompt is '~'
	mov	a,#080H
	lcall	30H		; output prompt string
	mov	a,#05H
	lcall	30H		; input text via BASIC-52
	mov	r0,#07H
	mov	r2,#00H		; point to BASIC-52 input text
	lcall	rhexr		; parse the intel-hex input
	jnc	rhexl		; repeat as long there is no error
	ret
;
; -------------------------------------------------------------------
;
	ORG 04000H
;
ent_rhex:
	ljmp	rhex
ent_rhexp:
	ljmp	rhexp
ent_rhexl:
	ljmp	rhexl
;
; -------------------------------------------------------------------
;
	END