;// QCASS1.SR



;OFFSETS IN THE FRAME:
OUTPUTPOINTER	= 4.
INPOINTER	= 4.
INPUTCOUNT	= 5.
OUTPUTCOUNT	= 5.
MARK		= 6.
SDP		= 7.
SDIW		= 8.
WATCHCOUNT	= 9.
RDACTON	= 10.
PARTIALOUTPUT	= 11.
PARTIALINPUT	= 12.
SACT		= 13.
CHAN1		= 14.
PARITY		= 15.

	.ENT CASWRITE,CASREAD,CASSB
	.SREL

CASWRITE:	WRITE
CASREAD:	READ
CASSB:		SPACEBACK
PTIMER:	DOG

	.NREL



;SPACE BACK A RECORD.
;CALL WITH CASSB().
;RETURNS 0 IF TIMER OVERFLOWED.
;RETURNS 1 OTHERWISE.

SPACEBACK:	STA 3 1 2
	JSR@ 370
	20
	JSR@ 367
	JSR SAVES

	LDA 0 SPACEBCOMMAND
	STA 0 @PCOMMAND

;WAIT FOR READ ACTIVE TO GO ON, THEN GO OFF

SBLOOP:	LDA 0 @STATUSIN
	MOVL# 0 0 SNC
	JMP SBOFF		;READ ACTIVE IS OFF

	STA 0 RDACTON,2
	JMP SBLOOP

SBOFF:	LDA 1 RDACTON,2
	MOV 1 1 SNR
	JMP SBLOOP		;READ ACTIVE OFF HAS NEVER BEEN ON

	SUBO 0 0		;= 0
	JMP STOP		;RECORD DONE



;WRITE A RECORD.
;CALL WITH CASWRITE(POINTER,COUNT,MARK).
;VECTOR FORMAT MUST BE <DATA><4xDEL><CR><PARITY>.
;MARK CODE SEQUENCE IS APPENDED TO RECORD IF MARK IS TRUE.
;RETURNS -1 IF TIMER EXPIRED,GENERATED PARITY BAD
;RETURNS 0 OTHERWISE.

WRITE:	STA 3 1 2
	JSR@ 370		;GETFRAME
	20
	JSR@ 367		;STOREARGS
	JSR SAVES

	LDA 0 RUNDRIVE
	STA 0 @PCOMMAND
	LDA 0 WRITECOMM
	STA 0 NCOMMAND
	LDA 0 OUTPUTCOUNT,2	;ADD 1 TO OUTPUTCOUNT
	SUBZL 1 1
	ADD 1 0
	STA 0 OUTPUTCOUNT,2
	JMP MLOOP



;THE WATCHDOG TIMER

DOG:	DSZ WATCHCOUNT,2
	BRI
	SUB 0 0			;THE TIMER RAN OUT. 
	STA 0 @PACT
	EIR
	ADC 0 0			;=-1
	JMP STOP



;THE MAIN LOOP

MLOOP:	LDA 0 @STATUSIN
	MOVR# 0 0 SNC		;DATA BIT READY?
	JMP CHECKREADACTIVE	;NO

	LDA 1 @DATAIN		;GET THE BIT
	LDA 3 PARTIALINPUT,2	;GET BYTE UNDER CONSTRUCTION
	MOVZR 3 3
	ADD 1 3 SNC		;CARRY TESTED IS FROM MOVZR
	JMP INPUTRESTORE	;BYTE NOT FINISHED

	COM 3 3		;BYTE FINISHED
	MOVS 3 3
	LDA 1 BYTEMASK
	AND 3 1
	LDA 0 PARITY,2		;FORM PARITY WITH DGN XOR CODE
	MOV 1 3
	ANDZL 0 3
	ADD 1 0
	SUB 3 0
	STA 0 PARITY,2
	LDA 3 BYTEBIT

INPUTRESTORE:	STA 3 PARTIALINPUT,2

CHKRFNB:	LDA 0 @STATUSIN
	LDA 1 CRFNB		;CHECK FOR OUTPUT READY
	AND 0 1 SNR
	JMP MLOOP

	LDA 1 PARTIALOUTPUT,2	;DRIVE IS READY FOR A BIT
	MOVZR # 1 1 SZR	;BYTE DONE?
	JMP SENDBIT		;NO

	DSZ OUTPUTCOUNT,2
	JMP GETNEXTBYTE

	LDA 1 RUNDRIVE		;SEND LAST WORD,CLEAR WRITEACTIVE
	STA 1 @PCOMMAND
	STA 1 NCOMMAND
	JMP MLOOP		;WAIT FOR THE READ TO FINISH

GETNEXTBYTE:	LDA 1 @OUTPUTPOINTER,2
	COM 1 1		;COMPLEMENT
	LDA 3 BYTEMASK
	AND 3 1
	LDA 3 BYTEBIT1
	ADD 3 1
	ISZ OUTPUTPOINTER,2

SENDBIT:	STA 1 @DATAOUT
	MOVZR 1 1

SENDX:	STA 1 PARTIALOUTPUT,2
	LDA 1 NCOMMAND
	STA 1 @PCOMMAND	;TURN ON WRITE ACTIVE
	JMP MLOOP

CHECKREADACTIVE:	MOVL# 0 0 SNC
	JMP RDACTOFF

	STA 0 RDACTON,2
	JMP CHKRFNB		;READ ACTIVE IS ON

RDACTOFF:	LDA 1 RDACTON,2 ;READ ACTIVE OFF. HAS IT BEEN ON?
	MOV 1 1  SNR
	JMP CHKRFNB		;NOT YET,THE RECORD STILL COMING

STOP1:	LDA 0 PARITY,2		;CORRECT PARITY
	MOVS 0 0
	MOVZL 0 0		;IGNORE MSB OF PARITY FOR NOW
	MOVZR 0 0
	MOVZS 0 0 SZR
	ADC 0 0			;=-1



; FINISH UP. AC0 ALREADY CONTAINS RESULT CODE

STOP:	LDA 1 STOPDRIVE
	STA 1 @PCOMMAND

;RESTORE INTERRUPT AND DISPLAY STATE AND RETURN

	LDA 1 SDIW,2
	STA 1 @P421

	LDA 1 CHAN1,2
	STA 1 @PCHAN1

	LDA 1 SDP,2
	STA 1 @P420

	LDA 1 SACT,2
	STA 1 @PACT

	JMP@ 366		;RETURN



SPACEBCOMMAND: 1B3

;ADDRESSES WHICH REFERENCE THE INTERFACE
PCOMMAND:	177770
STATUSIN:	177771
DATAIN:	177772
DATAOUT:	177773

WATCHTIME:	180.
STOPDRIVE:	0
RUNDRIVE:	1B2
WRITECOMM:	1B2+1B5
NCOMMAND:	0
CRFNB:		1B1

WATCHACT:	2
PCHAN1:	502
P421:		421
P420:		420
PACT:		453

PPTIMER:	PTIMER



;SAVE DISPLAY STATE

SAVES:	LDA 0 @P420
	STA 0 SDP,2

	SUB 0 0
	STA 0 @P420		;TURN OFF DISPLAY

	LDA 0 @P421
	STA 0 SDIW,2		;DISPLAY INTERRUPT WORD

;SAVE INTERRUPTS ACTIVE AND CHANNEL 1 POINTER

	LDA 0 @PACT
	STA 0 SACT,2

	LDA 0 @PCHAN1
	STA 0 CHAN1,2

;SET UP WATCHDOG TIMER

	LDA 0 WATCHTIME	
	STA 0 WATCHCOUNT,2

	LDA 0 @PPTIMER
	STA 0 @PCHAN1

	LDA 0 WATCHACT
	STA 0 @PACT
	STA 0 @P421

;THE WATCHDOG TIMER IS NOW RUNNING.  WE HAVE 10 SECS TO RETURN

;CLEAR VARIOUS THINGS WHICH NEED TO BE CLEARED

	SUBO 0 0
	STA 0 PARITY,2
	STA 0 RDACTON,2
	STA 0 PARTIALOUTPUT,2
	LDA 0 BYTEBIT
	STA 0 PARTIALINPUT,2
	STA 0 CRFLAG
	STA 0 PARFLAG

;READ ONE BIT FROM THE CONTROLLER TO SET UP THE READ CIRCUITRY

	LDA 0 @DATAIN
	JMP 0,3



BYTEBIT:	000200
BYTEBIT1:	000400
BYTEMASK:	000377
CRMASK:	000144
CRFLAG:	000000
PARFLAG:	000000



;READ A RECORD.
;CALL WITH CASREAD(POINTER,COUNT).
;COUNT SHOULD BE BIGGER THAN THE RECORD EXPECTED.
;VECTOR FORMAT WILL BE <DATA><4xDEL><CR><PARITY>(<GARBAGE>).
;RETURNS -1 IF TIMER EXPIRED,COUNT EXHAUSTED,GENERATED PARITY BAD
;RETURNS 0 OTHERWISE.

READ:	STA 3 1 2
	JSR@ 370
	20
	JSR@ 367
	JSR SAVES

	LDA 0 READCOMMAND	;START DRIVE
	STA 0 @PCOMMAND

RLOOP:	LDA 0 @STATUSIN
	MOVR# 0 0 SNC		;DATA BIT READY
	JMP RCHKR		;NO CHECK READ ACTIVE

	LDA 1 @DATAIN		;GET A BIT
	LDA 3 PARTIALINPUT,2	;GET BYTE UNDER CONSTRUCTION
	MOVZR 3 3
	ADD 1 3 SZC		;CHECK FOR BYTE DONE
	JMP RSTDAT		;DONE

	STA 3 PARTIALINPUT,2
	JMP RLOOP

RSTDAT:	COM 3 3	;COMPLEMENT
	MOVS 3 3		;SWAP BYTES
	LDA 1 BYTEMASK
	AND 3 1
	STA 1 @INPOINTER,2
	LDA 0 CRFLAG		;CHECK IF CR READ YET
	MOV# 0 0 SNR
	JMP RNPAR

	LDA 0 CRMASK		;CHECK IF THIS CHAR CR
	AND 1 0
	LDA 3 CRMASK
	SUBZ 3 0
	MOVZ# 0 0 SNR		
	STA 0 CRFLAG		;SET CR FLAG
	
DOPAR:	LDA 0 PARITY,2		;FORM PARITY WITH DGN XOR CODE
	MOV 1 3
	ANDZL 0 3
	ADD 1 0
	SUB 3 0
	STA 0 PARITY,2
	JMP RNPAR1

RNPAR:	LDA 0 PARFLAG		;CHECK IF THIS CHAR PARITY
	MOV# 0 0 SNR
	JMP RNPAR1		;NO

	SUBO 0 0
	STA 0 PARFLAG
	JMP DOPAR

RNSTOP:	JMP STOP1
	
RNPAR1:	LDA 3 BYTEBIT
	STA 3 PARTIALINPUT,2	;INITIALIZE INPUT WORD
	ISZ INPOINTER,2		;INCREMENT POINTER
 	DSZ INPUTCOUNT,2
	JMP RLOOP

	ADC 0 0			;COUNT OVERFLOWED
	JMP STOP

RCHKR:	MOVL# 0 0 SNC		;CHECK READ ACTIVE
	JMP RRACTOFF

	STA 0 RDACTON,2
	JMP RLOOP

RRACTOFF:	LDA 1 RDACTON,2
	MOV 1 1 SNR
	JMP RLOOP		;READ ACT OFF NEVER ON

	JMP RNSTOP

READCOMMAND:	1B2+1B3