Google
 

Trailing-Edge - PDP-10 Archives - bb-bt99o-bb - cd2ser.x21
There are 3 other files named cd2ser.x21 in the archive. Click here to see a list.
TITLE CD2SER - CARD READER SERVICE FOR CD20 CONTROLLER ON 2020 - V023
SUBTTL	D. DETROY/DBD	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 1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1978,1988>



;

XP VCD2SR,023		;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP

CD2SER:	ENTRY	CD2SER
SUBTTL	CD20 REGISTER DEFINITIONS

;OFFSETS INTO THE EXTERNAL PAGE REGISTERS

CDST==0				;STATUS AND CONTROL REGISTER
CDCC==2				;COLUMN COUNT REGISTER
CDBA==4				;BUS ADDRESS REGISTER
CDDB==6				;DATA BUFFER REGISTER

;STATUS REGISTER BIT DEFINITIONS

CS.ERR==100000			;ERROR
CS.RDK==040000			;READER CHECK
CS.EOF==020000			;END OF FILE
CS.OFL==010000			;OFF LINE
CS.DER==004000			;DATA ERROR
CS.DLT==002000			;DATA LATE
CS.NXM==001000			;NXM
CS.PWR==000400			;POWER CLEAR
CS.RDY==000200			;READY
CS.IEN==000100			;INTERRUPT ENABLE
CS.TOL==000010			;TRANSITION TO ON-LINE
CS.HCK==000004			;HOPPER CHECK
CS.DPK==000002			;DATA PACKING
CS.RED==000001			;READ

;DATA BUFFER REGISTER BIT DEFINITOONS

CB.RCK==040000			;READ CHECK
CB.PCK==020000			;PICK CHECK
CB.SCK==010000			;STACK CHECK
SUBTTL	SYMBOL DEFINITIONS

;COLUMN 1 SPECIAL CARD CODES

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.

;DEVICE DEPENDENT BITS IN LH OF DEVIOS

CRLAST==100			;SET WHEN PROCESSING LAST CARD BEFORE OFF-LINE
CR026==200			;SET WHEN 026 TRANSLTN TO BE MADE.
CRTRBL==4000			;TROUBLE AT INTERRUPT LEVEL
IOSMON==400000			;SET TO INDICATE MONITOR IO TO MAPIO

;DEVICE DEPENDENT BITS IN RH OF DEVIOS

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==^D41			;BUFFER SIZE FOR SUPER-IMAGE MODE.
SUBTTL	CD20 SYSERR DATA BLOCK DEFINITIONS

;WORDS ARE IN EACH CARD READER DDB FOR DAEMON ERROR REPORTING.

	.HCNAM==0			;DEVICE NAME
	.HCTYP==1			;CONTROLLER/DEVICE TYPE
	  HC.CTL==77B5			  ;CONTROLLER TYPE BYTE
	  .CTILL==0			  ;ILLEGAL
	  .CTB10==1			  ;BA10
	  .CTLP1==2			  ;LP100
	  .CTLP2==3			  ;LP20
	  .CTCD2==4			  ;CD20
	  HC.DEV==77B11			  ;DEVICE TYPE BYTE
	  .DEILL==0			  ;ILLEGAL
	  .DELPT==1			  ;LPT
	  .DECDR==2			  ;CDR
	  .DECDP==3			  ;CDP
	  .DEPLT==4			  ;PLT
	  HC.RTY==777777B35		  ;RETRY COUNT FIELD
	  .RTNON==1B17			  ;NON-RECOVERABLE FLAG
	.HCUID==2			;PPN OF USER
	.HCPGM==3			;PROGRAM NAME
	.HCSBP==4			;SUB-BLOCK POINTER
					; (XWD .HCL23-.HCSBP,,.HCL20)
	.HCL20==5			;UBA STATUS REGISTER
	.HCL21==6			;UBA MAP SLOT
	.HCL22==7			;CDST,,CDCC
	.HCL23==10			;CDBA,,CDDB

	.HCSIZ==11			;SIZE OF BLOCK
SUBTTL	AUTOCONFIGURE


;DRIVER CHARARCTERISTICS
;	CR2	= CR2CNF
;	CDR	= DEVICE TYPE (CARD READER)
;	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	(CR2,CDR,7,0,0,0,MDSEC0,MDSEC0,<DR.GCC!DR.NET>)

	 .ORG	DEVLEN

CDRCNT:!BLOCK	1		;NUMBER OF CARDS READ
CDRDAP:!BLOCK	1		;PLACE TO BUILD AOBJN POINTER TO CDRDAE
CDRDAE:!BLOCK	.HCSIZ		;SYSERR BLOCK
CDRCHK:!BLOCK	1		;CHECKSUM OF CURRENT INPUT BINARY CARD
CDRVEC:!BLOCK	1		;ADDRESS OF VECTOR INTERRUPT CODE
CDRBAS:!BLOCK	1		;CD20 BASE DEVICE ADDRESS
CDRCDB:!BLOCK	1		;ADDRESS OF CHANNEL DATA BLOCK
CDRBUF:!BLOCK	^D40		;INTERNAL BUFFER FOR ONE CARD
CDRBFZ==.-CDRBUF		;SIZE OF THE CDR BUFFER

CR2LEN:!			;LENGTH OF CDR DDB

	 .ORG


CR2DDB:	DDBBEG	(CDR,CR2LEN)
	SETWRD	(DEVCHR,<6*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,<3B11>)	;DEVHCW
	SETWRD	(CDRDAP,<-.HCSIZ,,CDRDAE>)	;CDRDAP
	DDBEND


;CONSO SKIP CHAIN CODE (AUTCON WILL FILL IN THE BLANKS)
CR2ICD:	PHASE	0
	EXP	0		;(00) OLD PC FLAGS
	EXP	0		;(01) OLD PC
	EXP	IC.UOU		;(02) NEW PC FLAGS
	EXP	.+1		;(03) NEW PC
	JSR	PIERR##		;(04) SAVE ACS AND SETUP PDL
	DMOVE	T1,0		;(05) GET INTERRUPT FLAGS AND PC
	DMOVEM	T1,-1		;(06) SAVE IN TRADITIONAL PLACE FOR XJEN CH'N
	SKIPA	F,.+1		;(07) SET UP DDB ADDRESS
	EXP	0		;(10) DDB ADDRESS
	XJRST	.+1		;(11) CALL INTERRUPT HANDLER
	EXP	0		;(12) INTERRUPT HANDLER ADDRESS
	DEPHASE
CR2ICL==.-CR2ICD		;LENGTH OF CONSO SKIP CHAIN CODE

EQUATE	(LOCAL,0,<CR2CKT,CR2KDB,CR2KLN,CR2UDB,CR2ULN>)
EQUATE	(LOCAL,0,<CR2ULB,CR2ULP>)

CD2DSP:	DRVDSP	(CR2,CDRCHN##,CR2DDB,CR2LEN,URDDIA##)

;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT:	MDKS10	(7,CDRIVT,CD11BA,0,0,<MD.KON>)
	EXP	0
CR2CFG:	XMOVEI	T1,CR2MDT##	;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,CDRBAS	;WORD CONTAINING AN I/O INSTRUCTION
	PUSHJ	P,AUTFND##	;SEE IF THERE'S ALREADY A DDB
	  JRST	CD2CF1		;JUST MAKE SURE THE NUMBERS ARE OK
	PUSHJ	P,AUTADN##	;ALLOCATE A DEVICE NUMBER
	HRLI	T1,'CDR'	;INCLUDE GENERIC NAME
	SETZ	T2,		;LOCAL DEVICE
	PUSHJ	P,AUTDDB##	;CREATE A DDB
	  JRST	TPOPJ##		;NO CORE
	ADDM	F,CDRDAP(F)	;FIX UP DAEMON ERROR POINTER
CD2CF1:	LDB	T1,[POINT 21,.CPDVC##,35] ;GET UNIBUS ADDRESS
	MOVEM	T1,CDRBAS(F)	;SAVE IN DDB
	MOVSI	T1,CP.CD2	;GET CHANNEL TYPE BITS
	PUSHJ	P,AUTCHN##	;ALLOCATE CHANNEL DATA BLOCK
	  JRST	CDRCF2		;NO CORE
	MOVE	T1,.CPCHA##	;GET CHANNEL DATA BLOCK ADDRESS
	MOVEM	T1,CDRCDB(F)	;SALT IT AWAY
	HLRZ	T1,CDRBAS(F)	;GET UNIBUS ADAPTER NUMBER
	MOVEI	T2,2		;NUMBER OF MAPPING REGISTERS NEEDED
	PUSHJ	P,AUTAMR##	;ALLOCATE MAPPING REGISTERS
	  JRST	CDRCF2		;NO CORE
	MOVE	T4,CDRCDB(F)	;GET CHANNEL DATA BLOCK ADDRESS BACK
	MOVEM	T1,CHNIMR(T4)	;STORE THE DATA AWAY
	MOVEM	T2,CHNMRC(T4)
	MOVEM	T3,CHNIEA(T4)
	SKIPE	CDRVEC(F)	;BEEN HERE BEFORE?
	JRST	CDRCF4		;THEN DON'T MESS WITH INTERRUPT CODE
	MOVE	T1,F		;DATA BLOCK ADDRESS
	XMOVEI	T2,CR2INT	;INTERRUPT SERVICE
	PUSHJ	P,AUTICD##	;GENERATE INTERRUPT ROUTINES
CDRCF2:	  SKIPA	T2,F		;NO CORE
	JRST	CDRCF3		;ONWARD
	MOVEI	T1,CR2LEN	;GET DDB LENGTH
	PUSHJ	P,AUTKIL##	;DELETE THE DDB
	PUSHJ	P,AUTDDN##	;DEALLOCATE DEVICE NUMBER
	JRST	TPOPJ##		;PHASE STACK AND RETURN
CDRCF3:	MOVEM	T2,CDRVEC(F)	;SAVE IN CASE ANYONE IS INTERESTED
	PUSHJ	P,AUTVII##	;COMPUTE VECTOR INSTRUCTION ADDRESS
	MOVE	T2,CDRVEC(F)	;GET VECTOR ROUTINE ADDRESS
	HRLI	T2,(XPCW)	;INTERRUPT INSTRUCTION
	MOVEM	T2,(T1)		;SAVE IN VECTOR TABLE
	MOVE	T1,DEVNAM(F)	;GET DEVICE NAME
	MOVEM	T1,CDRDAE+.HCNAM(F) ;SET IT UP
	MOVE	T1,[XWD .HCL23-.HCSBP,.HCL20] ;GET SUB-BLOCK POINTER
	MOVEM	T1,CDRDAE+.HCSBP(F) ;SET IT UP
	SETZ	T3,		;CLEAR T3
	MOVEI	T2,.CTCD2	;INDICATE CD20
	DPB	T2,[POINT 6,CDRDAE+.HCTYP(F),5] ;STORE CONTROLLER TYPE
	MOVEI	T2,.DECDR	;INDICATE CDR DEVICE
	DPB	T2,[POINT 6,CDRDAE+.HCTYP(F),11] ;STORE IT
CDRCF4:	POP	P,T1		;GET MDT DATA BACK
	POPJ	P,		;ALL DONE
SUBTTL	CDR SERVICE DISPATCH TABLE

;CARD READER SERVICE DISPATCH TABLE

;DISPATCH TABLE
	JRST	CDRONL		;ON-LINE CHECK
	JRST	ECOD2##		;SPECIAL ERROR STATUS
	JRST	GTBFSZ		;GET BUFFER SIZE AS FCTN OF MODE
	JRST	CR2INI		;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
SUBTTL	INITIALIZATION

CR2INI:	MOVEI	T1,CDRCNT	;OFFSET TO CARDS READ
	MOVEM	T1,CDROCR##	;SAVE FOR GETTABS
	CAIN	F,CR2DDB	;PROTOTYPE?
	JRST	CPOPJ1##	;YES, SKIP RETURN SO INI ROUTINE CALLED AGAIN
	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	MOVEI	T2,CS.PWR	;POWER CLEAR BIT
	WRIO	T2,CDST(T1)	;RESET THE THING
	MOVSI	T3,DVOFLN	;OFF-LINE BIT
	ANDCAM	T3,DEVCHR(F)	;ASSUME CDR IS ON-LINE
	PUSHJ	P,CDRONL	;IS IT REALLY?
	  IORM	T3,DEVCHR(F)	;NO--SET OFF-LINE BIT
	MOVEI	T2,CS.IEN	;INTERRUPT ENABLE BIT
	WRIO	T2,CDST(T1)	;ALLOW THEM
	PJRST	CPOPJ1##	;SKIP RETURN TO FORCE CALL FOR EACH CDR
SUBTTL	IN/INPUT UUO

CDRINP:	MOVSI	T1,DVOFLN	;OFF-LINE BIT
	TLZN	S,CRTRBL	;TROUBLE AT INTERRUPT LEVEL
	TDNE	T1,DEVCHR(F)	; OR OFF-LINE?
	  JRST	TKUSER		;YES--TELL USER
	TLZN	S,IOBEG		;FIRST INPUT?
	JRST	CDRGO		;NO--JUST DO NEXT BUFFER
	TLZ	S,CR026		;YES--ASSUME ANSI CARD CODE
	MOVSI	T2,PCDRAS##	;SET UP FOR ASCII CARDS
	TRNN 	S,10		;REALLY ASCII?
	JRST	CDRIN0		;YES--PROCEED
	MOVSI	T2,PCDRBI##	;NO--BINARY AND IMAGE BYTE SIZE= 12.
	TRNE	S,SPIMBT	;IS IT REALLY SUPER-IMAGE MODE?
	HRLI	T2,(POINT 16,)	;YES--BYTE SIZE IS 16
CDRIN0:	MOVEM	T2,DEVPTR(F)	;SET BYTE SIZE

;HERE TO START THE CDR GOING
CDRGO:	PUSH	P,J		;SAVE J
	PUSHJ	P,NEWBUF##	;INITIALIZE NEW BUFFER
	  PJRST	ADRERR##	;ADDRESS ERROR
	POP	P,J		;RESTORE J
	HRRI	T2,CDRBUF-1(F)	;BUFFER ADDRESS-1 TO T2
	HRLI	T2,-CDRBFZ	;FORM COMPLETE IOWD FOR MAPIO
	TLO	S,IOSMON	;INDICATE MONITOR IO TO MAPIO
	SETZB	P1,P4		;FIRST CALL,NO FRAME COUNT
	MOVE	P3,CDRCDB(F)	;GET POINTER TO CHANNEL DATA BLOCK
	PUSHJ	P,MAPIO##	;SET UP UNIBUS ADAPTOR REGISTERS
	  JRST	CDRSTP		;SHOULDN'T HAPPEN
	TLZ	S,IOSMON	;CLEAR MONITOR IO BIT
	TRO	S,IOACT		;SET IO ACTIVE
	MOVEM	S,DEVIOS(F)	;UPDATE DDB
	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	MOVNI	T2,^D80		;80 COLUMNS/CARD
	WRIO	T2,CDCC(T1)	;SET COLUMN COUNT REGISTER
	MOVE	T2,CHNIEA(P3)	;GET -11 STYLE ADDRESS
	WRIO	T2,CDBA(T1)	;SET IN BUS ADDRESS REGISTER
	LSH	T2,-14		;ISOLATE TWO HIGH ORDER BITS OF ADDRESS
	TRZ	T2,777717	; ON PROPER POSITION FOR CDST
	IORI	T2,CS.IEN+CS.RED ;INCLUDE INTERRUPT ENABLE AND READ BITS
	WRIOB	T2,CDST(T1)	;READ A CARD!
	PJRST	SETHNG##	;SET HUNG TIMER & EXIT
;HERE ON OFF-LINE CARD READER

TKUSER:	MOVEM	S,DEVIOS(F)	;UPDATE DDB
	HRRZ	T2,DEVBUF(F)	;ADDRESS OF BUFFER HEADER
	EXCTUX	<HRRZ T1,@T2>	;CURRENT USER BUFFER
	PUSHJ	P,UADRCK##	;ADDRESS CHECK IT
	EXCTUX	<SKIPGE @T1>	;ANY DATA THERE?
	  PJRST	RTEVMI##	;YES--RETURN IT TO USER
	PUSHJ	P,HNGSTP##	;NO--NOTIFY OPERATOR
	JRST	CDRINP		;TRY AGAIN
SUBTTL	RELEASE UUO & HUNG DEVICE

CDRREL:	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	PUSHJ	P,UBGOOD##	;IS CD20 ALIVE ON THE UNIBUS?
	  PJRST	CDRST2		;NO--DO SHORT VERSION OF CDRSTP
	PJRST	CDRSTP		;YES--SHUT DOWN I/O NORMALLY

CDRHNG:	TLO	S,CRTRBL	;SET TROUBLE BIT
	AOS	(P)		;SKIP RETURN TO AVOID HUNG MESSAGE
	MOVSI	T1,DVOFLN	;OFF-LINE BIT
	IORM	T1,DEVCHR(F)	;MARK CDR OFF-LINE
	PJRST	CDRREL		;DO RELEASE CODE
SUBTTL	GENERAL INTERRUPT ROUTINE

;ENTER HERE ON ALL INTERRUPTS

CR2INT:	PUSHJ	P,IOSET##	;SETUP ACS R AND S
	LDB	J,PJOBN##	;SET UP J WITH JOB NUMBER
	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	RDIO	T2,CDST(T1)	;READ STATUS REGISTER
	HRRM	T2,DEVSTS(F)	;SAVE IN DEVSTS
	RDIO	T3,CDDB(T1)	;READ SECONDARY STATUS REGISTER
	HRLM	T3,DEVSTS(F)	;SAVE IN DEVSTS
	TRNE	T2,CS.ERR!CS.TOL ;ERROR OR COMING ON-LINE?
	PJRST	CDRERR		;YES--GO PROCESS
	PJRST	CONVRT		;NO--PERFORM ANY DATA CONVERSIONS

CDRDON:	MOVEI	T1,@DEVPTR(F)	;LAST ADDRESS
	MOVEI	T2,@DEVIAD(F)	;FIRST ADDRESS (-1)
	SUBI	T1,1(T2)	;COMPUTE NO. OF WORDS STORED
	HRRM	T1,1(T2)	;STORE IN 1ST WORD OF BUFFER
	AOS	CDRCNT(F)	;INCREMENT THE CARD COUNTER
	PUSHJ	P,ADVBFF##	;ANY BUFFERS LEFT?
	  PJRST	CDRSTP		;NO--SHUT DOWN IO
	TLNE	S,CRLAST	;YES--IS THIS A "LAST CARD" CONDITION?
	  PJRST	CDRSTP		;YES--SHUT DOWN I/O
	PUSHJ	P,SETIOD##	;NO--ARRANGE FOR JOB TO RUN AGAIN
	PJRST	CDRGO		;GO READ NEXT CARD
SUBTTL	ERROR INTERRUPT ROUTINES -- DISPATCH

CDRERR:	TRNE	T2,CS.EOF	;EOF CONDITION?
	TLO	S,IOEND		;YES--SET FLAG
	TRNE	T2,CS.OFL	;OFF-LINE?
	JRST	CDRNOL		;YES--GO HANDLE

;HERE IF MUST BE ON-LINE INTERRUPT
	MOVE	T3,DEVCHR(F)	;GET OLD STATUS
	MOVSI	T1,DVOFLN	;OFF-LINE BIT
	ANDCAM	T1,DEVCHR(F)	;MARK ON-LINE
	TLNE	T3,DVOFLN	;WAS IT OFF-LINE?
	PUSHJ	P,PSIONL##	;YES--TELL USER CDR IS NOW ON-LINE
	POPJ	P,		;DISMISS
SUBTTL	ERROR INTERRUPT ROUTINES -- HANDLERS

;HERE TO GIVE USER AN ERROR
CDRSYE:	PUSHJ	P,CDRSYR	;DO SYSERR REPORTING
	MOVE	U,CDRCDB(F)	;GET CHANNEL DATA BLOCK
	MOVEI	T1,UNBTMO!UNBBME
	BSIO	T1,@CHNUBA(U)	;CLEAR POSSIBLE UBA ERRORS
CDRIOE:	TRO	S,IODERR	;SET DEVICE ERROR
	TLO	S,CRTRBL	;SET TROUBLE BIT
	PJRST	DEVERR##	;CAUSE UUOCON TO RETRY ON UUO LEVEL

;HERE WHEN CDR IS OFF-LINE
CDRNOL:	MOVSI	T1,DVOFLN	;MARK CDR OFF-LINE
	IORM	T1,DEVCHR(F)	; FOR ON-LINE INTERRUPT
	TRNE	T2,CS.NXM!CS.DLT!CS.DER ;IS IT BECAUSE OF ANY OF THESE?
	JRST	CDRSYE		;YES--LET USER AND F/S KNOW
	TRNE	T3,CB.RCK!CB.PCK!CB.SCK ;NO--IS IT A HARD READER CHECK?
	JRST	CDRIOE		;YES--LET USER KNOW
	TLO	S,CRLAST	;NO--NOW PROCESSING LAST CARD READ BEFORE HOPPER
	JRST	CONVRT		; EMPTY/STACKER FULL OR STOP BUTTON PUSHED
SUBTTL	DATA CONVERSION ROUTINES

CONVRT:	MOVEI	T4,^D80		;80 COLS./CARD
	CAMLE	T4,DEVCTR(F)	;BUFFER SMALLER THAN CARD?
	MOVE	T4,DEVCTR(F)	;YES--USE SMALLER NUMBER
	MOVE	T3,[POINT 18,CDRBUF(F)] ;BYTE POINTER TO INPUT
	TRNN	S,7		;SKIP IF NOT ASCII OR IMAGE
	TRNN	S,10		;SKIP IF IMAGE MODE
	  JRST	NOTIMG		;ASCII OR BINARY

;FALL INTO HERE TO PROCESS IMAGE/SUPER-IMAGE MODE CARD
CDRIMG:	ILDB	U,T3		;GET A COLUMN
	IDPB	U,DEVPTR(F)	;PUT INTO USER BUFFER
	SOJG	T4,CDRIMG	;LOOP THRU CARD
	PJRST	CDRDON		;FINISH UP
;HERE IF DATA IS IN ASCII OR BINARY MODE
NOTIMG:	ILDB	U,T3		;GET COLUMN 1
	MOVE	T1,U		;SAVE HERE
	TRZ	U,770000	;JUST COLUMN DATA
	CAIE	U,CODEOF+NEWEOF	;IS IT AN EOF CARD?
	CAIN	U,CODEOF	;OR THIS TYPE?
	  PJRST	EOFCRD		;YES--SET FLAGS
	CAIN	U,NEWEOF	;IS IT NEW TYPE EOF?
	  PJRST	EOFCRD		;YES--SET FLAGS
	TRNE	S,14		;BINARY MODE?
	  PJRST	CDRBIN		;YES--GO PROCESS IT

;HERE TO PROCESS AN ASCII CARD
	CAIN	U,COD026	;026 CARD?
	  PJRST	SET026		;YES--SET MODE
	CAIN	U,COD029	;029 CARD?
	  PJRST	SET029		;YES--SET MODE
	SKIPA	U,T1		;RESTORE COLUMN 1 AND SKIP NEXT
ASCLOP:	ILDB	U,T3		;GET NEXT COLUMN
	TRNE	U,100000	;MULTI-PUNCHED COLUMN?
	JRST	[MOVEI U,"\"	;YES--GET INVALID CHARACTER
		 JRST ASCLO1]	; AND STORE THAT
	SETZB	T1,T2
	CAIN	U,5000		;CONVERT "["
	MOVEI	U,24202		; TO INTERNAL FORM
	CAIN	U,3000		;CONVERT "]"
	MOVEI	U,22202		; TO INTERNAL FORM
	LDB	T2,[POINT 3,U,26] ;GET ZONES PLUS LOW ENCODED BIT
	TRNE	U,3		;AN 8 OR 9 PUNCH?
	TRC	T2,7		;YES--ENCODE THAT
	TRZE	U,40000		;COPY THIS BIT
	TRO	T2,10		; TO HERE
	TRNE	U,1		;THIS BIT ON
	TRO	U,10000		; MEANS THIS BIT SHOULD BE ON
	LSH	U,-^D12		;POSITION REMAINING CODE BITS
	TLNE	S,CR026		;026 MODE?
	TRO	T2,20		;YES--BUMP T2 TO 026 TABLE
	LDB	U,CRCVPT##(U)	;PICK UP ASCII CHAR FROM TABLE
ASCLO1:	IDPB	U,DEVPTR(F)	;PUT INTO USER BUFFER
	SOJG	T4,ASCLOP	;LOOP THRU CARD
	MOVEI	T1,15		;INSERT <CR>
	IDPB	T1,DEVPTR(F)
	MOVEI	T1,12		;INSERT <LF>
	IDPB	T1,DEVPTR(F)
	PJRST	CDRDON		;FINISH UP
;HERE TO PROCESS A BINARY CARD

CDRBIN:	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,CDRGO		;FORGET CARD IF WRDCNT=0
	HRRM	U,@DEVPTR(F)	;PUT IN R.H. OF 1ST DATA WORD OF BUFFER
	IMULI	U,3		;COMPUTE BYTE COUNT
	CAMGE	U,DEVCTR(F)	;MORE THAN THE BUFFER CAN HOLD?
	MOVE	T4,U		;NO--USE AS REAL COUNT
	ILDB	U,T3		;GET COLUMN 2
	TRZ	U,770000	;ONLY COLUMN DATA
	HRLM	U,@DEVPTR(F)	;STORE CHECKSUM IN USER BUFFER
	MOVSM	U,CDRCHK(F)	; AND SAVE IN DDB
CDRBI2:	ILDB	U,T3		;GET NEXT COLUMN
	IDPB	U,DEVPTR(F)	;PUT INTO USER BUFFER
	SOJG	T4,CDRBI2	;LOOP THRU CARD
	MOVEI	T2,@DEVIAD(F)	;ADDRESS OF BUFFER
	PUSHJ	P,CKS12##	;COMPUTE THE CHECKSUM
	CAME	T1,CDRCHK(F)	;DOES IT COMPARE WITH THAT ON CARD?
	TRO	S,IODTER	;NO--SET DATA ERROR
	PJRST	CDRDON		;FINISH UP
SUBTTL	VARIOUS UTILITY ROUTINES

;SET CARD CODE MODE
SET026:	TLOA	S,CR026		;SET 026 MODE
SET029:	TLZ	S,CR026		;SET 029 MODE
	TLNN	S,CRLAST	;WAS THIS LAST CARD?
	PJRST	CDRGO		;NO--READ ANOTHER CARD
	PJRST	CDRSTP		;YES--SHUT DOWN I/O

;HERE TO SET EOF
EOFCRD:	TLO	S,IOEND		;SET END OF FILE
	PJRST	CDRSTP		;BACK TO USER

;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,SPIMBT	;SUPER-IMAGE?
	MOVEI	T1,SIBFSZ	;YES, 80 WORDS OF DATA/BUFFER.
	POPJ	P,		;RETURN WITH BUFFER SIZE IN TAC.
GPBFS1:	TRZ	M,SPIMBT	;SUPER-IMAGE ALLOWED ONLY
	POPJ	P,		;IF INITIALIZED FOR IMAGE MODE.

;HERE TO STOP THE CDR AND START USER
CDRSTP:	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	MOVEI	T2,CS.PWR	;POWER CLEAR BIT
	WRIO	T2,CDST(T1)	;RESET THE CDR
	MOVEI	T2,CS.IEN	;INTERRUPT ENABLE
	WRIO	T2,CDST(T1)	;SET IT
CDRST2:	TLZ	S,CRLAST	;CLEAR LAST CARD BIT
	PUSHJ	P,SETIOD##	;TAKE OUT OF IO WAIT
	PUSHJ	P,CLRACT##	;CLEAR IOACT
	PJRST	RTEVMI##	;RETURN ANY EVM

;HERE TO SEE IF THE CDR IS ON-LINE
CDRONL:	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	PUSHJ	P,UBGOOD##	;IS CD20 ALIVE ON THE UNIBUS?
	  POPJ	P,		;NO--RETURN OFF-LINE
	RDIO	T2,CDST(T1)	;READ STATUS REGISTER
	TRNN	T2,CS.OFL	;IS READER OFF-LINE?
	  AOS	(P)		;NO--IT'S ON-LINE, SO SKIP RETURN
	POPJ	P,		;RETURN ON-LINE OR OFF-LINE
;HERE TO DO DAEMON ERROR REPORTING FOR SYSERR
CDRSYR:	MOVE	U,CDRCDB(F)	;GET CHAN DATA BLOCK
	RDIO	T1,@CHNUBA(U)	;READ UBA STATUS REGISTER
	MOVEM	T1,CDRDAE+.HCL20(F) ;SAVE IT
	LSH	T2,-4		;POSITION 2 BIT ADDRESS EXTENSION
	MOVE	T1,CDRBAS(F)	;GET BASE ADDRESS OF I/O REGISTERS
	RDIO	T3,CDBA(T1)	;GET ENDING BUS ADDRESS
	DPB	T2,[POINT 2,T3,19] ; AND PUT IN HIGH ORDER BITS
	IDIVI	T3,UBAMUL	;COMPUTE MAP REGISTER OFFSET
	ADDI	T3,UBAEXP	;ADD IN THE BASE ADDRESS
	HLL	T3,CHNUBA(U)	;PUT IN PROPER UBA NUMBER
	RDIO	T2,(T3)		;READ OUT MAP SLOT OF LAST WORD XFER'ED
	MOVEM	T2,CDRDAE+.HCL21(F) ;SAVE IT
	RDIO	U,CDST(T1)	;GET CDST
	RDIO	T2,CDCC(T1)	;GET CDCC
	HRLI	T2,(U)		;PUT IN LH(T2)
	MOVEM	T2,CDRDAE+.HCL22(F) ;SAVE IT
	RDIO	U,CDBA(T1)	;GET CDBA
	RDIO	T2,CDDB(T1)	;GET CDDB
	HRLI	T2,(U)		;PUT IN LH(T2)
	MOVEM	T2,CDRDAE+.HCL23(F) ;SAVE IT
	MOVE	T2,JBTPPN##(J)	;PICK UP PPN
	MOVEM	T2,CDRDAE+.HCUID(F) ;SAVE IT
	MOVE	T2,JBTPRG##(J)	;PICK UP PROGRAM NAME
	MOVEM	T2,CDRDAE+.HCPGM(F) ;SAVE IT
	MOVEI	T1,.ERHCC	;LOAD SYSERR TYPE
	HRLI	T1,CDRDAP(F)	;POINTER TO AOBJN POINTER
	PJRST	DAEERR##	;CALL DAEMON

	END