Google
 

Trailing-Edge - PDP-10 Archives - bb-bt99o-bb - cdrser.x21
There are 3 other files named cdrser.x21 in the archive. Click here to see a list.
TITLE	CDRSER - I/O BUS CARD READER SERVICE - V133
SUBTTL	T. WACHS/TW/CF/WM/JE  TS  25 OCTOBER 88

	SEARCH	F,S,DEVPRM
	$RELOC
	$HIGH

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1973,1988>

XP VCDRSR,133		;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP

CDRSER::ENTRY	CDRSER
COD029==5252		;12-0-2-4-6-8
COD026==4242		;12-2-4-8
CODEOF==7400		;12-11-0-1
NEWEOF==0017		;6-7-8-9 PUNCH.

;BITS IN LH OF S
COLUM1==100			;SET WHEN FIRST COL HAS NOT BEEN READ.
COLUM2==200			;SET WHEN SECOND COL HAS NOT BEEN READ.
CR029==400			;SET WHEN 029 TRANSLTN TO BE MADE.
FORGET==1000			;SET TO AVOID BUFFER ADVANCEMENT.
IGNRBT==2000			;SET TO AVOID USER BUFFER OVERFLOW.


CRTRBL==4000



;BITS IN RH OF S
SPIMBT==1B29			;IO STATUS BIT FOR SUPER-IMAGE MODE.

;BUFFER SIZES
ASBFSZ==^D18			;BUFFER SIZE FOR ASCII MODE.
BIBFSZ==^D27			;BUFFER SIZE FOR BINARY MODE.
IMBFSZ==^D28			;BUFFER SIZE FOR IMAGE MODE.
SIBFSZ==^D81			;BUFFER SIZE FOR SUPER-IMAGE MODE.


;HARDWARE STATUS FLAGS FOR CDR
ITREN==1B18			;TROUBLE ENABLED.
IRDEN==1B19			;READY-TO-READ ENABLED.
F27PK==1B20			;PICK FAILURE FLAG, SET WITH ITRBL.
F27PC==1B21			;PHOTO CELL ERROR, SET WITH ITRBL.
F27CM==1B22			;CARD MOTION ERROR, SET WITH ITRBL.
F27ST==1B23			;STOP FLAG, SET WITH ITRBL OR EXTERNALLY.
FCIRD==1B24			;CARD IN READ FLAG.
F27HS==1B25			;HOPPER EMPTY/STACKER FULL FLAG, SET WITH ITRBL.
FRDCD==1B26			;READING CARD FLAG.
ITRBL==1B27			;TROUBLE INTERRUPT.
IDMSD==1B28			;DATA MISSED INTERRUPT.
IRDYR==1B29			;READY-TO-READ INTERRUPT.
IEOFL==1B30			;END OF FILE INTERRUPT.
IEOCD==1B31			;END OF CARD INTERRUPT.
IDRDY==1B32			;DATA READY INTERRUPT.
NOTRDY==ITRBL+IDMSD+IEOFL+IEOCD	;SYMBOL FOR TEST IN DDB'S
SUBTTL	AUTOCONFIGURE


;DRIVER CHARARCTERISTICS
;	CR1	= CR1CNF
;	CDR	= CARD PUNCH
;	7	= MAXIMUM DEVICES IN SYSTEM
;	0	= KONTROLLER TYPE
;	0	= MAXIMUM DRIVES PER KONTROLLER
;	0	= HIGHEST DRIVE NUMBER ON KONTROLLER
;	MDSEC0	= SECTION FOR KDB/UDB
;	MDSEC0	= SECTION FOR DDB
DRVCHR	(CR1,CDR,7,0,0,0,MDSEC0,MDSEC0,<DR.GCC!DR.NET>)

	 .ORG	DEVLEN

CDRCHF:! BLOCK	1		;PI CHANNEL FLAGS
CDRRET:! BLOCK	1		;ADDRESS OF INTERRUPT EXIT
CDRCSO:! BLOCK	1		;ADDRESS OF INTERRUPT CODE
CDRSVE:! BLOCK	1		;ADDRESS OF ALTERNATE ENTRY TO INTERRUPT CODE
CDRCSF:! BLOCK	1		;ADDRESS OF INTERRUPT CODE FOR DATA
CDRCHK:! BLOCK	1		;CHECKSUM OF CURRENT INPUT BINARY CARD
CDRCNT:! BLOCK	1		;NUMBER OF CARDS READ
CDRCOL:! BLOCK	1		;COLUMN COUNT ON CURRENT CARD
CDRSUP:! BLOCK	1		;BLKI POINTER TO BUFFER FOR SUPER IMAGE
CDRMIS:! BLOCK	1		;-1 IF MISSED DATA ON CURRENT CARD
CDRSPU:! BLOCK	1		;COUNT FO SPURIOUS END-OF-CARD FLAGS
CDRSV2:! BLOCK	1		;SAVED AC 'U'
CDRIOB:!			;START OF I/O INSTRUCTIONS
CDRCNI:! BLOCK	1		;CONI
CDRCNO:! BLOCK	1		;CONO
CDRCST:! BLOCK	1		;CONSO
CDRCSZ:! BLOCK	1		;CONSZ
CDRDTI:! BLOCK	1		;DATAI
CDRBKI:! BLOCK	1		;BLKI FOR SUPER IMAGE
CDRRDY:! BLOCK	1		;SKIP IF DATA READY
CDRRTR:! BLOCK	1		;SKIP IF READY TO READ
CDRIOE:!			;END OF I/O INSTRUCTIONS
CR1LEN:!			;LENGTH OF PTP DDB

	 .ORG


	$LOW
CR1DDB:	DDBBEG	(CDR,CR1LEN)
	SETWRD	(DEVCHR,<2*HUNGST,,0>)		;DEVCHR
	SETWRD	(DEVSER,<MCSEC0+CDRDSP>)	;DEVSER
	SETWRD	(DEVMOD,<DVIN!DVCDR,,14403>)	;DEVMOD
	SETWRD	(DEVTYP,<<.TYCDR*.TYEST>!.SPCDR,,0>) ;DEVTYP
	SETWRD	(DEVCPU,<CDRCHN##>)		;DEVCPU
	SETWRD	(DEVHCW,<1B11>)			;BA10 CONTROLLER
	SETWRD	(CDRCHF,<CDRCHN##>)		;PI CHANNEL FLAGS
	SETWRD	(CDRCOL,<CRFCHN##-CDRCHN##>)	;OFFSET TO DATA CHANNEL
	SETWRD	(CDRCNI,<CONI  000,DEVSTS(F)>)	;CONI
	SETWRD	(CDRCNO,<CONO  000,(U)>)	;CONO
	SETWRD	(CDRCST,<CONSO 000,(U)>)	;CONSO
	SETWRD	(CDRCSZ,<CONSZ 000,(U)>)	;CONSZ
	SETWRD	(CDRDTI,<DATAI 000,U>)		;DATAI
	SETWRD	(CDRBKI,<BLKI  000,CDRSUP>)	;BLKI FOR SUPER IMAGE
	SETWRD	(CDRRDY,<CONSO 000,IDRDY>)	;SKIP IF DATA READY
	SETWRD	(CDRRTR,<CONSZ 000,NOTRDY>)	;SKIP IF READY TO READ
	DDBEND

	$HIGH


;CONSO SKIP CHAIN CODE (AUTCON WILL FILL IN THE BLANKS)
CR1ICD:	PHASE	0
	CONSO	000,0			;(00) SKIP IF INTERRUPT FOR THIS LPT
	JRST	.-1			;(01) GO TO NEXT SKIP CHAIN ELEMENT
	MOVEM	F,CR1SVF		;(02) SAVE AC 'F'
	SKIPA	F,.+1			;(03) SET UP DDB ADDRESS
CR1DDA:!EXP	0			;(04) DDB ADDRESS
	XJRST	.+1			;(05) CALL INTERRUPT HANDLER
CR1INR:!EXP	0			;(06) INTERRUPT HANDLER ADDRESS
CR1INE:!EXP	0,0			;(07,10) XPCW ENTRY
	EXP	IC.UOU			;(11) PC FLAG
	EXP	.+1			;(12) WHERE TO JUMP
	MOVE	F,CR1SVF		;(13) RESTORE AC 'F'
	JSR	PIERR##			;(14) SAVE ACS AND SETUP PDL
	MOVE	F,CR1DDA		;(15) RESET DDB ADDRESS
	XJRSTF	CR1INE			;(16) GO PROCESS INTERRUPT
CR1EXT:!MOVE	F,CR1SVF		;(17) RESTORE AC 'F'
	XJEN	-1			;(20) DISMISS INTERRUPT
CF1INX:!CONSO	000,0			;(21) SKIP IF CDR FLAG
	JRST	.-1			;(22) GO TO NEXT SKIP CHAIN ELEMENT
CF1SVR:!JSR	PIERR##			;(23) SAVE ACS AND SETUP PDL
	MOVE	F,CR1DDA		;(24) SET UP DDB ADDRESS
	XJRST	.+1			;(25) CALL INTERRUPT HANDLER
	EXP	CF1INT			;(26) INTERRUPT HANDLER ADDRESS
CR1SVF:!EXP	-1			;(27) SAVED 'F' FOR CR1INT
	DEPHASE
CR1ICL==.-CR1ICD			;LENGTH OF CONSO SKIP CHAIN CODE

EQUATE	(LOCAL,0,<CR1CKT,CR1KDB,CR1KLN,CR1UDB,CR1ULN>)
EQUATE	(LOCAL,0,<CR1ULB,CR1ULP>)

CR1DSP:	DRVDSP	(CR1,CDRCHN##,CR1DDB,CR1LEN,URDDIA##)

;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT:	MDKL10	(7,114,0,0,<MD.KON>,)	;DEVICE CODE 114
	MDKL10	(7,150,0,0,<MD.KON>,)	;DEVICE CODE 150
	MDKL10	(7,154,0,0,<MD.KON>,)	;DEVICE CODE 154
	EXP	0
CR1CFG:	XMOVEI	T1,CR1MDT##	;MONGEN'ED DEVICE TABLE
	XMOVEI	T2,DEFMDT	;DEFAULT TABLE
	MOVNI	T3,1		;NO MASSBUS UNIT OR DRIVE INFORMATION
	MOVEI	T4,MD.KON	;MATCH ON KONTROLLER DEFINITION
	PUSHJ	P,AUTMDT##	;SCAN THE TABLES
	  JRST	CPOPJ1##	;NO MATCHES
	PUSH	P,T1		;SAVE MDT DATA
	MOVEI	T1,CDRIOB	;WORD CONTAINING AN I/O INSTRUCTION
	PUSHJ	P,AUTFND##	;SEE IF THERE'S ALREADY A DDB
	  JRST	CR1CF1		;JUST MAKE SURE THE NUMBERS ARE OK
	PUSHJ	P,AUTADN##	;ALLOCATE A DEVICE NUMBER
	HRLI	T1,'CDR'	;INCLUDE GENERIC DEVICE NAME
	SETZ	T2,		;LOCAL DEVICE
	PUSHJ	P,AUTDDB##	;CREATE A DDB
	  JRST	[POP	P,T1	;NO CORE
		 PJRST	AUTDDN##] ;DEALLOCATE DEVICE NUMBER
CR1CF1:	MOVSI	T1,-<CDRIOE-CDRIOB> ;-LENGTH
	XMOVEI	T2,CDRIOB(F)	;STARTING ADDRESS
	HRRZ	T3,.CPDVC##	;DEVICE CODE
	PUSHJ	P,AUTDVC##	;FILL IN DEVICE CODES
	SKIPE	CDRCSO(F)	;BEEN HERE BEFORE?
	JRST	CR1CF3		;THEN DON'T MESS WITH THE SKIP CHAIN
	ADDM	F,CDRBKI(F)	;RELOCATE BLKI FOR SUPER IMAGE MODE
	MOVE	T1,F		;DATA BLOCK ADDRESS
	XMOVEI	T2,CR1INT	;INTERRUPT SERVICE
	PUSHJ	P,AUTICD##	;GENERATE INTERRUPT ROUTINES
	  SKIPA	T2,F		;NO CORE
	JRST	CR1CF2		;ONWARD
	MOVEI	T1,CR1LEN	;GET DDB LENGTH
	PUSHJ	P,AUTKIL##	;DELETE THE DDB
	PUSHJ	P,AUTDDN##	;DEALLOCATE DEVICE NUMBER
	JRST	TPOPJ##		;PHASE STACK AND RETURN
CR1CF2:	MOVEM	T1,CDRCSO(F)	;SAVE ADDRESS
	MOVEI	T2,CRFCHN##	;PI CHANNEL FOR DATA
	HRRZ	T2,.CPSAV##-1(T2) ;GET ASSOCIATED SAVE ROUTINE
	HRRM	T2,CF1SVR(T1)	;FIXUP INTERRUPT CODE
	MOVEI	T2,CR1INE(T1)	;INTERRUPT SAVE ROUTINE ADDRESS
	MOVEM	T2,CDRSVE(F)	;SAVE
	MOVEI	T2,CR1EXT(T1)	;INTERRUPT EXIT ADDRESS
	MOVEM	T2,CDRRET(F)	;SAVE
	MOVEI	T2,CDRCHN##	;PI CHANNEL
	PUSHJ	P,AUTCSO##	;LINK INTO CONSO SKIP CHAIN
	MOVE	T1,CDRCSO(F)	;START OF SKIP CHAIN CODE
	ADDI	T1,CF1INX	;OFFSET TO DATA CHANNEL INTERRUPT CODE
	MOVEM	T1,CDRCSF(F)	;SAVE FOR HACKING FLAGS CHANNEL
	MOVEI	T2,CRFCHN##	;PI CHANNEL
	PUSHJ	P,AUTCSO##	;LINK INTO CONSO SKIP CHAIN
CR1CF3:	POP	P,T1		;GET MDT DATA BACK
	POPJ	P,		;ALL DONE
;CDR SERVICE DISPATCH TABLE
	JRST	CDRONL		;CHECK TO SEE IF CDR IS ON LINE
	JRST	ECOD2##		;SPECIAL ERROR STATUS
	JRST	GTBFSZ		;GET BUFFER SIZE AS FCTN OF MODE
	JRST	CDRINI		;INITIALIZATION
	JRST	CDRHNG		;HUNG DEVICE
CDRDSP:	JRST	CDRREL		;RELEASE
	JRST	ILLOUT##	;CLOSE CALLED ONLY ON ILLEGAL OUTPUT
	JRST	ILLOUT##	;OUTPUT IS ILLEGAL
	JRST	CDRINP		;INPUT
;HERE ON INPUT UUO TO START READER.
CDRINP:	TLZN	S,CRTRBL	;TROUBLE DETECTED ON INTERRUPT?
	JRST	CDSET		;NO
	MOVEM	S,DEVIOS(F)	;YES, SAVE S (CRTRBL OFF)
	JRST	TKUSER		;AND CALL HNGSTP

CDSET:	PUSHJ	P,CDRONL	;CDR ON LINE?
	  JRST	TKUSER		;NO, READER MUST BE OFF, TELL USER.
CDSET1:	TLNN	S,IOBEG
	JRST	CDRGO
	TLZ	S,CR029+FORGET+IGNRBT	;YES. SET UP FOR 1ST TIME
	MOVSI	T2,PCDRAS##	;SET UP FOR ASCII CARDS
	TRNN 	S,10		;REALLY ASCII?
	JRST	SETPTR		;YES.
	MOVSI	T2,PCDRBI##	;BINARY AND IMAGE BYTE SIZE= 12.
	TRNE	S,SPIMBT	;IS THIS SUPER-IMAGE MODE?
	MOVSI	T2,PCDRSI##	;SUPER-IMAGE BYTE SIZE = 36.
SETPTR:	MOVEM	T2,DEVPTR(F)	;SET BYTE SIZE
CDRGO:	TLZ	S,IOBEG		;CLEAR VIRGIN DEVICE BIT.
	PUSHJ	P,NEWBUF##	;INITIALIZE NEW BUFFER
	  JRST	ADRERR##	;ADDRESS ERROR
CDRGO1:	SETZM	CDRMIS(F)
	MOVEI	U,IEOFL
	XCT	CDRCST(F)	;EOF BUTTON PRESSED?
	TLNE	S,IOEND		;EOF?
	JRST	EOF		;YES-PROCESS IT NOW
	TRNE	S,SPIMBT	;IS S SET FOR SUPER-IMAGE MODE?
	PUSHJ	P,SETSPI	;YES, SET UP THE BLKI PTR: SUPIMG.
	TLO	S,COLUM1+COLUM2	;NO. INIT FOR COLUMN 1
	MOVEI	T1,1670		;SET UP CONO FOR NEXT CARD
	MOVEI	U,ITREN+IRDYR
	XCT	CDRCST(F)	;WAS TROUBLE ENCOUNTERED OR CARD READY?
	MOVEI	T1,370		;YES. SET CONO FOR READY-TO-READ
	MOVE	U,T1		;GET BITS FOR CONO INTO U
	ANDI	T1,500		;GET INTERRUPT ENABLE BITS
	ADDI	T1,270		;GET OTHER INTERRUPT BITS
	PUSHJ	P,SETDLV	;SET UP DATA LEVEL INTERRUPT
	TRO	S,IOACT		;CANT USE SETACT AS IT ZEROES IOW
	JRST	STOIOS##	;WHICH MAY BE ON AFTER IGNORING A CARD
TKUSER:	HRRZ	T2,DEVBUF(F)	;ADR OF BUFFER HDR
	EXCTUX	<HRRZ T1,@T2>	;CURRENT USER BUFFER
	PUSHJ	P,UADRCK##
	EXCTUX	<SKIPGE @T1>	;DOES IT CONTAIN DATA?
	PJRST	RTEVM##		;YES, GIVE IT TO THE USER
	MOVSI	T1,DVOFLN	;OFF-LINE BIT
	IORM	T1,DEVCHR(F)	;LITE IT
	PUSHJ	P,HNGSTP##	;PROBLEM. OPR CAN CORRECT AND CONT.
	JRST	CDSET1		;TRY IT AGAIN.

;SUBROUTINE TO SEE IF THE CDR IS ON LINE
; RETURN CPOPJ1 IF IT IS

CDRONL:	MOVEI	U,F27ST+F27HS	;STOP CONDITION TO BE CONTINUED BY THE OPR?
	XCT	CDRCSZ(F)	;CONSZ FROM DDB
	POPJ	P,		;YES, TELL THE OPR
	MOVEI	U,IRDYR+IEOFL	;IF WE ARE HERE, READER CAN BE ON OR OFF
	XCT	CDRCST(F)	;BUT IF ON, THIS BETTER SKIP
	POPJ	P,		;OFF
	JRST	CPOPJ1##	;ON
;HERE TO GET BUFFER SIZE, CALLED DURING INIT UUO.
GTBFSZ:	MOVEI	T1,ASBFSZ	;ASSUME ASCII.
	TRNN	M,10		;C(UUO) IS USER'S INIT ARG.
	JRST	GPBFS1		;ASCII.
	MOVEI	T1,BIBFSZ	;NOT ASCII. ASSUME BINARY.
	TRNE	M,4		;BINARY?
	JRST	GPBFS1		;YES.
	MOVEI	T1,IMBFSZ	;MUST BE IMAGE MODE.
	TRNE	M,1B29		;SUPER-IMAGE?
	MOVEI	T1,SIBFSZ	;YES, 80 WORDS OF DATA/BUFFER.
	POPJ	P,		;RETURN WITH BUFFER SIZE IN TAC.
GPBFS1:	TRZ	M,1B29		;SUPER-IMAGE ALLOWED ONLY
	POPJ	P,		;IF INITIALIZED FOR IMAGE MODE.

;HERE TO INITIALIZE BLKI PTR USED FOR SUPER-IMAGE MODE.
SETSPI:	MOVN	T1,DEVCTR(F)	;NEG NUMBER OF BYTES.
	HRLZ	T1,T1		;MAKE IT THE NEG CNTR IN BLKI PTR.
	HRRI	T1,@DEVPTR(F)	;PICK UP ADDRESS TO FIRST SRD OF BUFFER.
	MOVEM	T1,CDRSUP(F)	;SET PTR.
	POPJ	P,		;AND PRETURN READY TO PROCESS A CARD.

;SUBROUTINE TO DISABLE INTERRUPTS ON FLAG LEVEL AND ENABLE INTERRUPTS
;ON DATA LEVEL. CALLED WITH CONO BITS IN AC(U) AND CONSO BITS
;IN AC(T1)

SETDLV:	HLLZS	@CDRCSF(F)	;DISABLE FLAG LEVEL PI
	ADD	U,CDRCHF(F)	;PIA
	CONO	PI,PI.OFF	;DISABLE PI'S WHILE CHANGING LEVELS
	HRRM	T1,@CDRCSO(F)	;AND SET UP INTERRUPT LOCATION
	XCT	CDRCNO(F)	;START CARD READER
	CONO	PI,PI.ON	;TURN PI SYSTEM BACK ON
	POPJ	P,		;AND RETURN
;THIS IS THE ENTRY POINT FOR THE INTERRUPT LEVEL SERVICE FOR THE CDR

CR1INT:	SKIPN	CDRMIS(F)	;DONT CHANGE STATUS IF ERROR
	XCT	CDRCNI(F)	;STORE STATUS.

	XCT	CDRRDY(F)	;SKIP IF DATA READY FLAG
	JRST	NOTDAT		;NOT DATA READY, FIND OUT WHAT
	AOS	CDRCOL(F)	;COUNT FOR DETECTION OF SPURIOS EOC INTERRUPTS.
	SKIPN	CDRSUP(F)	;SUPER-IMAGE MODE?
	JRST	NORMOD		;NO, PROCESS NORMALLY.
	XCT	CDRBKI(F)	;YES, XMIT TO USER'S BUFFER.
	JRST	.+2		;NON-SKIP IF DEVCTR COLUMNS PROCESSED.
	XJRST	CDRRET(F)	;ROOM FOR MORE COLUMNS, DISMISS INTERRUPT.

;HERE WHEN 80 CHARS HAVE BEEN XMTD TO USER.
	MOVEM	U,CDRSV2(F)	;SAVE AC(U)
	HRRZ	U,CDRSUP(F)	;PICK UP LAST PTR ADR
	HRRM	U,DEVPTR(F)	; AND STORE IT  FOR WRD CNT CALC.
	SETZM	CDRSUP(F)	;TURN OFF SUPER-IMAGE TEMPORARILY.
	MOVSI	U,IGNRBT	;IGNORE THE REST OF THE WORD
	IORM	U,DEVIOS(F)	;SAVE IOS
	JRST	CDRXIT		;RESTORE U AND EXIT

;HERE TO PROCESS NON SUPER-IMAGE MODE INPUT.

NORMOD:	MOVEM	U,CDRSV2(F)	;SAVE AC U
	MOVE	U,DEVIOS(F)	;GET STATUS WORD
	TLNE	U,FORGET+IGNRBT	;PROCESS IT?
	JRST	IGNORE		;NO, READ AND DISMISS
	TRNN	U,7		;SKIP IF NOT ASCII OR IMAGE
	TRNN	U,10		;SKIP IF IMAGE MODE
	JRST	NOTIMG		;ASCII OR BINARY
	XCT	CDRDTI(F)	;READ DATA INTO U
	IDPB	U,DEVPTR(F)	;PUT INTO USER'S BUFFER
	MOVSI	U,IGNRBT	;BIT TO IGNORE REST OF CARD
	SOSG	DEVCTR(F)	;ROOM FOR MORE?
	IORM	U,DEVIOS(F)	;NO, SET IGNORE BIT
	JRST	CDRXIT		;RESTORE IT AND EXIT

;HERE TO READ AND THROW AWAY THE COLUMN
IGNORE:	XCT	CDRDTI(F)	;READ THE COLUMN
CDRXIT:	MOVE	U,CDRSV2(F)	;RESTORE U
	XJRST	CDRRET(F)	;AND EXIT
;HERE IF DATA IS IN ASCII MODE, READ AND CONVERT
NOTIMG:	XCT	CDRDTI(F)	;READ THE COLUMN INTO U
	EXCH	U,CDRSV2(F)	;SAVE DATA, RESTORE U
	XPCW	@CDRSVE(F)	;SAVE INTERRUPT ACS
	HRRZ	U,CDRSV2(F)	;GET BACK DATA
	MOVE	S,DEVIOS(F)	;GET STATUS WORD TO S
	TLZE	S,COLUM1	;FIRST COLUMN?
	JRST	FSTCOL		;YES, MAKE SPECIAL CHECKS
CDRDIS:	TRNN	S,10		;ASCII?
	JRST	CDRASC		;YES, CONVERT IT
	JRST	DISRET		;NO, STORE BINARY DATA IN USER'S BUFFER
;HERE ON INTERRUPTS OTHER THAN DATA READY

NOTDAT:	XCT	CDRRTR(F)	;SKIP IF READY TO READ INTERRUPT
	JRST	CRFLAG		;GO PROCESS NON-DATA INTERRUPT.
	MOVEM	U,CDRSV2(F)	;READY TO READ, SAVE U
	MOVEI	U,670		;GET INTERRUPT MASK
	HRRM	U,@CDRCSO(F)	;AND SET UP INTERRUPT LOCATION
	MOVEI	U,1670		;GET CONO BITS
	ADD	U,CDRCHF(F)	;PIA
	XCT	CDRCNO(F)	;START CARD MOVING.
	JRST	CDRXIT		;RESTORE U AND EXIT
;HERE WHEN AN ASCII CHARACTER IS READ
CDRASC:	SETZB	T1,T2
	JUMPE	U,CDRAS2	;0-PICK UP AN ASCII BLANK
	CAIN	U,5000
	MOVEI	U,4202
	CAIN	U,3000
	MOVEI	U,2202
	LDB	T2,[XWD 110300,U]
	TRNE	U,3
	TRC	T2,7
	TRNE	U,74
	TRO	T2,10
	TRNE	U,314
	TRO	T1,2
	TRNE	U,525
	TRO	T1,1
	TLNE	S,CR029		;AN 029 CARD READ?
	TRO	T2,20		;NO. BUMP T2 TO 026 TABLE
CDRAS2:	LDB	U,CRCVPT##(T1)	;PICK UP ASCII CHAR FROM TABLE
DISRET:	IDPB	U,DEVPTR(F)	;STORE CHAR IN USERS BUFFER
	SOSLE	DEVCTR(F)	;ROOM FOR MORE?
	POPJ	P,		;YES, EXIT
	TLO	S,IGNRBT	;IGNORE REST OF CARD
STODIS:	MOVEM	S,DEVIOS(F)	;SAVE STATUS
	POPJ	P,		;AND EXIT

CRFLAG:	MOVEM	U,CDRSV2(F)	;SAVE AC
	HLLZS	@CDRCSO(F)	;DISABLE DATA LEVEL INTERRUPT
	MOVEI	U,660		;SET UP FLAG LEVEL INTERRUPT
	HRRM	U,@CDRCSF(F)	;TO CATCH CHANGE OF PI LEVELS
	MOVEI	U,CRFCHN##+ITRBL+IRDYR	;GET FLAG LEVEL PI
	XCT	CDRCNO(F)	;CHANGE INTERRUPT LEVELS
	JRST	CDRXIT		;RESTORE U
				;AND DISMISS
;HERE WHEN THE 1ST COLUMN OF A CARD HAS BEEN READ.
FSTCOL:	TLNN	S,COLUM2	;REALLY FIRST COL?
	JRST	NOTFST		;NO, IT'S THE 2ND COL.
	CAIE	U,CODEOF+NEWEOF	;YES, IS IT AN EOF?
	CAIN	U,CODEOF	;MAYBE, CHECK ANOTHER STYLE OF EOF.
	JRST	EOFCRD		;YES, GO PROCESS.
	CAIN	U,NEWEOF	;MAYBE, SEE IF ITS THE NEW EOF.
	JRST	EOFCRD		;YES, PROCESS.
NOTFST:	TRNE	S,10		;ASCII CARD?
	JRST	NOTASC		;NO
	CAIN	U,COD026	;YES. IS IT AN 026 CARD?
	JRST	SET026		;YES. HANDLE IT
	CAIE	U,COD029
	JRST	SETIOS
	TLZ	S,CR029
	TLO	S,FORGET
SETIOS:	MOVEM	S,DEVIOS(F)	;SAVE S
	TLNN	S,FORGET	;FORGET REST OF CARD?
	JRST	CDRDIS		;NO. PROCESS IT
	POPJ	P,		;YES. DISMISS INTERRUPT
SETFRG:	TLOA	S,FORGET	;SET BIT TO FORGET ABOUT CARD
NOTASC:	TRNN	S,4		;COL 1 OF A NOT ASCII CARD
	JRST	SETIOS		;IMAGE MODE - NO PROCESSING
	TLZN	S,COLUM2	;COLUMN1?
	JRST	COL2IN		;NO. COLUMN2 JUST READ
	MOVEI	T1,-5(U)	;COL1 - IS THERE A 7-9 PUNCH?
	TRNE	T1,17
	TRO	S,IOIMPM	;NO. SET ERROR BIT
	LSH	U,-6		;COLUMNS 12-3 ARE WORD COUNT
	JUMPE	U,SETFRG	;FORGET CARD IF WRDCNT=0
	PUSH	P,U		;SAVE U
	IMULI	U,3		;COMPUTE ITEM COUNT
	CAMGE	U,DEVCTR(F)	;MORE THAN THE BUFFER CAN HOLD?
	MOVEM	U,DEVCTR(F)	;NO. SAVE AS REAL COUNT
	POP	P,U		;GET WRDCNT
	HRRM	U,@DEVPTR(F)	;IN R.H. OF 1ST DATA WORD OF BUFFER
	TLO	S,COLUM1	;SET TO PICK UP COLUMN2 
	JRST	STODIS		;STORE S AND RETURN

;HERE WHEN COL 2 OF A BINARY CARD WAS READ
COL2IN:	MOVSM	U,CDRCHK(F)	;COLUMN2 IS CHECKSUM
	HRLM	U,@DEVPTR(F)	;ALSO IN L.H. OF 1ST DATA WORD
	JRST	STODIS		;STORE S AND RETURN
;HERE ON A NON-DATA CDR INTERRUPT

CF1INT:	MOVE	S,DEVIOS(F)	;AND GET STATUS INTO S
	MOVEI	U,IEOCD
	XCT	CDRCST(F)	;END OF CARD?
	JRST	NOTEOC		;NO
	MOVE	U,CDRCOL(F)	;YES, EOC INTERRUPT.
	SKIPE	CDRMIS(F)
	JRST	DONCNT
	CAIGE	U,^D79
	JRST	SPUEOC		;NO, ASSUME SPURIOUS INTERRUPT.
DONCNT:	SETOM	CDRCOL(F)	;YES, RE-INIT COL CNT.
	AOS	CDRCNT(F)
	TLZE	S,FORGET	;FORGET ABOUT CARD?
	JRST	CDRGO1		;YES, START TO READ NEXT CARD.
	SKIPN	CDRSUP(F)	;IF CDRSUP NON-ZERO, DEVPTR MUST BE SET.
	JRST	NTSUPI		;DEVPTR ALREADY SET OR NOT IN SUPER-IMAGE MODE.
	HRRZ	U,CDRSUP(F)	;PICK UP LWA OF XFR.
	MOVEM	U,DEVPTR(F)	;SET IN PTR FOR WORD CNT CALC.
	SETZM	CDRSUP(F)	;FLAG THAT ITS DONE.
NTSUPI:	TRNE	S,10		;BINARY?
	JRST	BINEOC		;YES. CHECK CHKSUM
	MOVEI	U,15		;NO. INSERT <CR>
	IDPB	U,DEVPTR(F)
	MOVEI	U,12		;INSERT <LF>
	IDPB	U,DEVPTR(F)
NXTCRD:	TLZ	S,IGNRBT	;SET UP TO READ NEXT CARD
	MOVEI	T1,@DEVPTR(F)	;LAST ADDRESS
	MOVEI	T2,@DEVIAD(F)	;FIRST ADDRESS (-1)
	SUBI	T1,1(T2)	;COMPUTE NUMBER OF WORDS STORED
	HRRM	T1,1(T2)	;STORE IN 1ST WORD OF BUFFER
				;IN IO WAIT?
	PUSHJ	P,SETIOD##	;YES. TAKE OUT
	PUSHJ	P,ADVBFF##	;ADVANCE BUFFERS
	  JRST	CDROFF		;NEXT BUFFER NOT EMPTY
	MOVEI	U,F27PC+F27CM+IDMSD
	XCT	CDRCSZ(F)
	TRO	S,IODERR
	MOVEI	U,F27ST+F27HS
	XCT	CDRCST(F)	;SKIP IF STOP CONDITION
	TRNE	S,IODERR+IOIMPM+IODTER	;BUFFER AVAILABLE, ANY ERRORS?
	JRST	CDROFF		;YES, TURN OFF CDR.
	JRST	CDRGO		;NO, PROCEES READING CARDS.

;HERE TO PROCESS SPURIOUS EOC INTERRUPTS.

SPUEOC:	AOS	CDRSPU(F)
	MOVEI	T1,IEOCD	;SET TO CLEAR EOC
	MOVEI	U,ITREN
	XCT	CDRCSZ(F)	;TROUBLE ENABLED?
	TRO	T1,ITRBL	;YES
	MOVEI	U,IRDEN
	XCT	CDRCSZ(F)	;RDY TO READ ENABLED?
	TRO	T1,IRDYR	;YES
	MOVE	U,T1
	ANDI	T1,500
	ADDI	T1,270
	PUSHJ	P,SETDLV	;GO BACK TO DATA LEVEL
	SKIPGE	CDRCOL(F)	;ARE WE ACTIVELY PROCESSING A CARD?
	POPJ	P,		;NO, DISMISS SINCE THIS SHOULDN'T HARM.
	MOVEI	U,^D79		;YES, FLAG IT AND LET ANY FURTHER
	MOVEM	U,CDRCOL(F)	; SPURIOUS INTERRUPTS FOR THIS CARD PASS THRU.
	JRST	SETERR		;FLAG IT AND DISMISS.
;HERE ON THE END OF A BINARY CARD

BINEOC:	TRNN	S,4		;REALLY BINARY?
	JRST	NXTCRD		;IMAGE MODE 
	MOVEI	T2,@DEVIAD(F)	;ADDRESS OF BUFFER
	PUSHJ	P,CKS12##	;COMPUTE CHECKSUM
	CAME	T1,CDRCHK(F)	;DOES IT COMPARE WITH CARD'S CHKSUM?
	TRO	S,IODTER	;NO. LIGHT A BIT
	JRST	NXTCRD		;START READ OF NEXT CARD
SET026:	TLOA	S,CR029		;026 - RESET 029 BIT
EOFCRD:	TLO	S,IOEND		;EOF - LIGHT BIT
	JRST	SETFRG		;FORGET REST OF CARD
NOTEOC:	MOVEI	U,IEOFL
	XCT	CDRCSZ(F)	;EOF BUTTON PRESSED?
	JRST	EOF		;YES.
	MOVEI	U,ITRBL
	XCT	CDRCST(F)	;TROUBLE?
	JRST	NOTRBL		;NO, PROCEED
	MOVEI	U,0
	MOVEI	T1,270
	PUSHJ	P,SETDLV	;GO BACK TO DATA LEVEL
NOTRBL:	MOVEI	U,F27PC+F27CM+IDMSD
	XCT	CDRCST(F)	;ERROR EXCEPT PICK OR STOP BUTTON?
	JRST	SETRDY		;NO. GO SET READY-TO-READ INTERRUPT
SETERR:	TRO	S,IODERR	;YES. SET  ERROR BIT
	MOVEI	T1,670
	MOVEI	U,IDMSD
	PUSHJ	P,SETDLV	;GO BACK TO DATA LEVEL
	SETOM	CDRMIS(F)
	PJRST	STOIOS##
STOERR:	PUSHJ	P,CDROFF	;DISABLE INTERRUPTS SINCE IOACT CLEARED BY DEVERR

	TLO	S,CRTRBL	;SET TROUBLE BIT IF CDR TROUBLE INTERCEPT

	MOVEM	S,DEVIOS(F)	;STORE STATUS
	PJRST	DEVERR##	;AND REPORT ERROR

EOF:	TLO	S,IOEND+IOBEG	;EOF - LIGHT BIT
CDRREL:	MOVEI	T1,0		;
	DPB	T1,PBUFSZ##	;ZERO OUT BUFFER SIZE.
	SETOM	CDRCOL(F)	;INITIALIZE COLUMN COUNT.
	SETZM	CDRSUP(F)	;TURN OFF SUPERIMAGE MODE.

	TLZ	S,CRTRBL	;CLEAR TROUBLE BIT

CDROFF:	MOVEI	U,10000		;CONTROLLER RESET BIT
	XCT	CDRCNO(F)
	HLLZS	@CDRCSO(F)	;RESET INTERUPT LOC
	HLLZS	@CDRCSF(F)	;ALSO FLAG LEVEL
	PUSHJ	P,SETIOD##	;TAKE OUT OF IO WAIT
	PUSHJ	P,RTEVM##	;RETRUN ANY EVM

	JRST	CLRACT##	;ZERO IOACT, STORE S AND RETURN

SETRDY:	MOVEI	U,F27HS
	XCT	CDRCSZ(F)
	JRST	TSTINR
	MOVEI	U,10000		;CONTROLLER RESET BIT
	XCT	CDRCNO(F)	;RESET READ-A-CARD FLOP
	JRST	CDRGO		;ENABLE FOR READY TO READ

;HERE ON HOPPER/STACKER ERROR
TSTINR:	MOVEI	U,FCIRD
	XCT	CDRCSZ(F)	;CARD IN READER?
	POPJ	P,		;YES, IGNORE INTERRUPT (TRBL NOT ENEBLED)
	PJRST	STOERR		;NO, GO INTERCEPT THE ERROR


CR1INI:!
CDRINI:	MOVEI	T1,CDRCNT	;OFFSET TO CARDS READ
	MOVEM	T1,CDROCR##	;SAVE FOR GETTABS
	MOVEI	U,10000		;CONTROLLER RESET BIT
	XCT	CDRCNO(F)
	HLLZS	@CDRCSO(F)	;CLEAR SKIP CHAIN MASK FLAGS
	HLLZS	@CDRCSF(F)	; FOR BOTH DATA AND FLAGS
IFN FTMP,<
	MOVE	T1,CDRCOL(F)	;INTERLOCK POINTS AT INTERRUPT CHAIN
	ADDM	T1,DEVCPU(F)	;POINT IT AT FLAGS CHAIN
>
	SETOM	CDRCOL(F)	;INITIALIZE COLUMN COUNT
	SETZM	CDRSUP(F)	;TURN OFF SUPERIMAGE MODE

	JRST	CPOPJ1##	;SKIP RETURN TO FORCE CALL FOR EACH CDR

;HERE ON HUNG DEVICE TIME OUT IF TROUBLE INTERCEPT ENABLED
CDRHNG:	MOVEI	U,F27PC+F27CM+FCIRD	;IF PHOTO CELL DARK, CARD MOTION
	XCT	CDRCSZ(F)	; ERROR, OR CARD IN READER AFTER TIME OUT
	TRO	S,IODERR	;LIGHT AN ERROR BIT
	PUSHJ	P,CDRREL	;RELEASE AND TURN OFF CDR
	AOS	(P)		;SKIP RETURN SO NO HUNG MESSAGE
	PJRST	STOERR		;AND RETURN

	END