; SIMPLE PORT-TO-PORT VERIFY WITH FIFO
; VERS 1.1 MARTIN EBERHARD NOVEMBER 2010
;DELIBERATELY BRIEF FOR FRONT PANEL TOGGLING

; THIS PROGRAM ENDS BY STOPPING THE TAPE READER. IF YOUR
; TTY DOES NOT SUPPORT THIS FEATURE, WATCH FOR A "HALT"
; ON THE FRONT PANEL. VERIFY RESULTS ARE STORED IN
; THE 4 BYTES AT THE END OF THIS PROGRAM. SUCCESSFUL
; VERIFY WILL LEAVE 000 IN LOCATION "ERDPTH". FAILURE
; WILL LEAVE THE QUEUE DEPTH THERE, THE TAPE DATA IN
; LOCATION "ERDATA", AND A POINTER TO THE MISMATCHED RS232
; DATA IN THE 2 BYTES AT "ERADDR".

; 2SIO REGISTER EQUATES

A0CTRL	EQU	10H	;ACIA 0 CONTROL OUTPUT PORT
A0STAT	EQU	10H	;ACIA 0 STATUS INPUT PORT
A0TDR	EQU	11H	;ACIA 0 TX DATA REGISTER
A0RDR	EQU	11H	;ACIA 0 RX DATA REGISTER
A1CTRL	EQU	12H	;ACIA 1 CONTROL OUTPUT PORT
A1STAT	EQU	12H	;ACIA 1 STATUS INPUT PORT
A1TDR	EQU	13H	;ACIA 1 TX DATA REGISTER
A1RDR	EQU	13H	;ACIA 1 RX DATA REGISTER

; ACIA CONTROL REGISTER BITS

ACCDS1	EQU	00000001B	;COUNTER DIVIDE SEL 1
ACCDS2	EQU	00000010B	;COUNTER DIVIDE SEL 2
ACWS1	EQU	00000100B	;WORD SELECT 1
ACWS2	EQU	00001000B	;WORD SELECT 2
ACWS3	EQU	00010000B	;WORD SELECT 3
ACTC1	EQU	00100000B	;TX CONTROL 1
ACTC2	EQU	01000000B	;TX CONTROL 2
ACRXIE	EQU	10000000B	;RX INT ENABLE

ACRSET	EQU	00000011B	;MASTER RESET

;COMPOUND ACIA COMMANDS

AC0INIT	EQU	ACCDS1+ACWS3	;/16 CLOCK, 8 BITS+2 STOP
AC0REN	EQU	AC0INIT+ACTC2	;MAKES RTS ACTIVE
AC1INIT	EQU	ACCDS1+ACWS1+ACWS3 ;/16 CLK, 8 BITS+1 STOP
AC1CTS	EQU	AC1INIT+ACTC2	;MAKES RTS INACTIVE

; ACIA STATUS REGISTER BITS

ASRDRF	EQU	00000001B	;RX DATA REG FULL
ASTDRE	EQU	00000010B	;TX DATA REG EMPTY
ASDCD	EQU	00000100B	;DATA CARRIER DETECT
ASCTS	EQU	00001000B	;CLEAR TO SEND
ASFE	EQU	00010000B	;FRAMING ERROR
ASOVRN	EQU	00100000B	;RX OVERRUN ERROR
ASPE	EQU	01000000B	;PARITY ERROR
ASIRQ	EQU	10000000B	;INTERRUPT REQUEST

; PROGRAM EQUATES

FIFO	EQU	ACRSET*256	;BUFF ADDR AND RESET CMD
LOWMRK	EQU	124		;LOW WATER MARK

ORG 300H

; INITIALIZE FIFO

	LXI	D,FIFO		;DE IS INPUT POINTER
	MOV	H,E		;HL IS INPUT POINTER AND LEADER FLAG
	MOV	L,E
	MOV	C,E		;BYTE COUNT=0

; INITIALIZE BOTH ACIAS

	MOV	A,D		;BUF ADDR HIGH BYTE IS ALSO RESET
	OUT	A0CTRL
	OUT	A1CTRL

	MVI	A,AC0INIT
	OUT	A0CTRL

; MAIN LOOP

MAIN1:	MVI	A,AC1INIT	;ENABLE RS232
	OUT	A1CTRL

CHKIN:	IN	A1STAT
	RAR			;TEST RDR FULL
	JNC	CHKOUT

	IN	A1RDR
	STAX	D
	INR	E		;256 BYTE FIFO

	INR	C		;BUMP BYTE CNT
	JP	NOCTS		;128 BYTES: DE-ASSERT CTS

	MVI	A,AC1CTS	;DE-ASSERT CTS
	OUT	A1CTRL
NOCTS:
CHKOUT:	IN	A0STAT		;TEST FOR TTY DATA
	RAR			;TEST RDR FULL
	JNC	CHKIN		;NO TAPE DATA: LOOK FOR MORE RS232

	IN	A0RDR		;GET BYTE FROM PAPER TAPE

	ORA	A		;SKIP OVER INITIAL NULLS
	JNZ	NONULL

	CMP	H		;TEST FOR LEADER
	JZ	CHKIN		;STILL IN LEADER: IGNORE NULLS

NONULL:	MOV	H,D		;SET H<>0: END OF LEADER, OUTPUT PTR

	CMP	M		;COMPARE TO FIFO BYTE
	JNZ	ERROR

	INR	L		;256 BYTE FIFO

	MOV	A,C
	CPI	LOWMRK		;LOW WATER MARK	
	DCR	C		;SETS Z, BUT WON'T TOUCH CARRY

	JNC	CHKIN		;C SET BY LOW WATER MARK CMP
	JNZ	MAIN1		;MORE DATA: KEEP GOING

;DONE IF FIFO EMPTIED (A=1, C=0 FOR NORMAL EXIT)

ERROR:	SHLD	ERADDR		;SAVE DATA POINTER
	LXI	H,ERDATA	;SAVE PAPER TAPE ERROR DATA
	MOV	M,A

	MVI	A,AC0CTS	;STOP THE READER
	OUT	A0CTRL

	DCX	H
	MOV	M,C		;SAVE QUEUE DEPTH AT ERDPTH

	HLT

ERDPTH:	DB	0		;FIFO DEPTH AT END
ERDATA:	DB	0		;PAPER TAPE DATA AT END
ERADDR:	DW	0		;FIFO POINTER AT END
	
	END