Google
 

Trailing-Edge - PDP-10 Archives - cust_sup_cusp_bb-x130c-sb - 10,7/unsmon/cdpser.mac
There are 6 other files named cdpser.mac in the archive. Click here to see a list.
TITLE	CDPSER  CARD PUNCH SERVICE ROUTINE V114
SUBTTL	T WACHS/TW/CF/GH/JE/DAL  21 JUNE 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 VCDPSR,114		;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP

CDPSER::ENTRY	CDPSER
;CONI/CONO BITS
CO.INI==1B20		;INITIALIZE
CO.RJT==1B21		;REJECT/OFFSET A CARD
CO.EJT==1B23		;EJECT A CARD
CO.PID==1B24		;DISABLE PI INTERRUPTS ON TROUBLE
CO.PIE==1B25		;ENABLE PI INTERRUPTS ON TROUBLE
CO.CLR==1B26		;CLEAR ERROR FLOP
CO.DIE==1B27		;DISABLE EOC INTERRUPTS
CO.EIE==1B28		;ENABLE EOC INTERRUPTS
CO.CEO==1B29		;CLEAR EOC FLOP
CO.PON==1B30		;TURN ON PUNCH MOTOR
CO.CDR==1B31		;CLEAR DATA REQUEST FLOP
CO.SDR==1B32		;SET DATA REQUEST FLOP

CI.OFL==1B18		;OFF LINE
CI.HSC==1B21		;HOPPER/STACKER FULL OR CHAD BOX FULL
CI.PIK==1B22		;PICK FAILURE
CI.EJT==1B23		;EJECT FAILURE
CI.TRB==1B24		;TROUBLE
CI.TIE==1B25		;TROUBLE INTERRUPTS ENABLED
CI.ERR==1B26		;DATA OR TIMING ERROR
CI.CIP==1B27		;CARD IN PUNCH
CI.ECI==1B28		;EOC INTERRUPTS ENABLED
CI.EOC==1B29		;END OF CARD
CI.PON==1B30		;PUNCH IS ON
CI.BSY==1B31		;BUSY
CI.DRQ==1B32		;DATA REQUEST

CDTRY==3		;NUMBER OF RETRIES BEFORE CALLING IT A HARD ERROR

;BITS IN S
PCHBIT==2000	;RH - ON IF PUNCH AN ASCII CARD (SAW A LINE-FEED)

;LEFT HAND BITS
NOADV==1000	;ON IF MORE IN THE BUFFER TO PUNCH
CLSBIT==2000	;CLOSE HAS HAPPENNED
FILPRT==4000	;CURRENT BUFFER (MONITOR) IS PARTIALLY FULL
CDPTBL==10000	;TROUBLE DETECTED ON INTERRUPT LEVEL
CDPRCV==20000	;RECOVERY FROM TROUBLE IN PROGRESS
SUBTTL	AUTOCONFIGURE


	CP10D==:1		;CSS CP10D CONTROLLER FLAG

;DRIVER CHARARCTERISTICS
;	CDP	= CDPCNF
;	CDP	= 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	(CDP,CDP,7,0,0,0,MDSEC0,MDSEC0,<DR.GCC!DR.NET>)

	 .ORG	DEVLEN

CDPCHF:! BLOCK	1		;PI CHANNEL FLAGS
CDPRET:! BLOCK	1		;ADDRESS OF INTERRUPT EXIT
CDPNTR:! BLOCK	1		;BYTE POINTER TO CURRENT OUTPUT BUFFER
CDPCTR:! BLOCK	1		;BYTE COUNT
CDPCNT:! BLOCK	1		;CARD COUNT
CDPBUF:! BLOCK	33		;BUFFER FOR ASSEMBLING CARD IMAGE
CDPOCT:! BLOCK	1		;OUTPUT COLUMN COUNT
CDPOPT:! BLOCK	1		;POINTER TO DATA IN BUFFER
CDPTMP:! BLOCK	1		;OFFSET TO DATA CHANNEL
CDPECT:! BLOCK	1		;ERROR RETRY COUNT
CDPFCD:! BLOCK	1		;FREE CARD
CDPFCT:! BLOCK	1		;FREE CARD COLUMN COUNT
CDPCCT:! BLOCK	1		;CURRENT CARD COLUMN
CDPSVJ:! BLOCK	1		;SAVED AC 'J'
CDPSVT:! BLOCK	1		;SAVED AC 'U'
CDPEOC:! BLOCK	1		;EOC INTERRUPT FLAG
CDPBNB:! BLOCK	1		;BINARY CARD WORD COUNT, CHECKSUM
CDP10D:! BLOCK	1		;NON-ZERO IF CP10D
CDPCSO:! BLOCK	1		;ADDRESS OF INTERRUPT CODE
CDPCSF:! BLOCK	1		;ADDRESS OF INTERRUPT CODE FOR DATA
CDPIOB:!			;START OF I/O INSTRUCTIONS
CDPXST:! BLOCK	1		;CONI TO READ DEVICE STATUS
CDPCNO:! BLOCK	1		;CONO
CDPOAT:! BLOCK	1		;CHECK FOR TROUBLE
CDPZTE:! BLOCK	1		;TEST FOR EOT OR TROUBLE
CDPZPE:! BLOCK	1		;TEST FOR PUNCH ERROR
CDPZTB:! BLOCK	1		;TEST FOR TROUBLE
CDPZER:! BLOCK	1		;TEST FOR ERROR
CDPZCP:! BLOCK	1		;TEST CARD IN PUNCH
CDPOTN:! BLOCK	1		;TROUBLE BUT DON'T RESET BUFFERS
CDPOER:! BLOCK	1		;TEST ERROR
CDPDOU:! BLOCK	1		;DATAO
CDPDFC:! BLOCK	1		;PUNCH FREE CARD
CDPDSV:! BLOCK	1		;DATAO CDP,SEVENS
CDPIOE:!			;END OF I/O INSTRUCTIONS
CDPLEN:!			;LENGTH OF CDP DDB

	 .ORG


	$LOW
CDPDDB:	DDBBEG	(CDP,CDPLEN)
	SETWRD	(DEVCHR,<4*HUNGST,,CDPSIZ##>)	;DEVCHR
	SETWRD	(DEVSER,<MCSEC0+CDPDSP>)	;DEVSER
	SETWRD	(DEVMOD,<DVOUT!DVCDR,,14403>)	;DEVMOD
	SETWRD	(DEVTYP,<<.TYCDP*.TYEST>!.SPCDP,,0>) ;DEVTYP
	SETWRD	(DEVCPU,<CDPCHN##>)		;DEVCPU
	SETWRD	(CDPCHF,<CDPCHN##>)		;PI CHANNEL FLAGS
	SETWRD	(CDPTMP,<CPFCHN##-CDPCHN##>)	;OFFSET TO DATA CHANNEL
	SETWRD	(CDPBNB,<EXP 50000>)		;WORD COUNT, CHECKSUM
	SETWRD	(CDPXST,<CONI  000,DEVSTS(F)>)	;READ DEVICE STATUS
	SETWRD	(CDPCNO,<CONO  000,(U)>)		;CONO
	SETWRD	(CDPOAT,<CONSO 000,474000>)	;CHECK FOR TROUBLE
	SETWRD	(CDPZTE,<CONSZ 000,4100>)	;TEST FOR EOT OR TROUBLE
	SETWRD	(CDPZPE,<CONSZ 000,1000>)	;TEST FOR PUNCH ERROR
	SETWRD	(CDPZTB,<CONSZ 000,CI.TRB>)	;TEST FOR TROUBLE
	SETWRD	(CDPZER,<CONSZ 000,CI.ERR>)	;TEST FOR ERROR
	SETWRD	(CDPZCP,<CONSZ 000,CI.CIP>)	;TEST CARD IN PUNCH
	SETWRD	(CDPOTN,<CONSO 000,470000>)	;TEST FOR TROUBLE
	SETWRD	(CDPOER,<CONSO 000,CI.ERR>)	;TEST ERROR
	SETWRD	(CDPDOU,<DATAO 000,U>)		;DATAO
	SETWRD	(CDPDFC,<DATAO 000,CDPFCD(F)>)	;PUNCH FREE CARD
	SETWRD	(CDPDSV,<DATAO 000,SEVENS>)
	DDBEND

	$HIGH


;CONSO SKIP CHAIN CODE (AUTCON WILL FILL IN THE BLANKS)
CDPICD:	PHASE	0
	CONSO	000,0			;(00) SKIP IF INTERRUPT FOR THIS LPT
	JRST	.-1			;(01) GO TO NEXT SKIP CHAIN ELEMENT
	MOVEM	F,CDPSAV		;(02) SAVE AC 'F'
	SKIPA	F,.+1			;(03) SET UP DDB ADDRESS
CDPDDA:!EXP	0			;(04) DDB ADDRESS
	XJRST	.+1			;(05) CALL INTERRUPT HANDLER
	EXP	0			;(06) INTERRUPT HANDLER ADDRESS
CDPEXT:!MOVE	F,CDPSAV		;(07) RESTORE AC 'F'
	XJEN	-1			;(10) DISMISS INTERRUPT
CPFINX:!CONSO	000,0			;(11) SKIP IF CDP FLAG
	JRST	.-1			;(12) GO TO NEXT SKIP CHAIN ELEMENT
CPFSVR:!JSR	PIERR##			;(13) SAVE ACS AND SETUP PDL
	MOVE	F,CDPDDA		;(14) SET UP DDB ADDRESS
	XJRST	.+1			;(15) CALL INTERRUPT HANDLER
	EXP	CPFINT			;(16) INTERRUPT HANDLER ADDRESS
CDPSAV:!EXP	-1			;(17) STORAGE FOR AC F
	DEPHASE
CDPICL==.-CDPICD			;LENGTH OF CONSO SKIP CHAIN CODE

EQUATE	(LOCAL,0,<CDPCKT,CDPKDB,CDPKLN,CDPUDB,CDPULN>)
EQUATE	(LOCAL,0,<CDPULB,CDPULP>)

CPXDSP:	DRVDSP	(CDP,CDPCHN##,CDPDDB,CDPLEN,CPOPJ##)

;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT:	MDKL10	(7,110,0,0,<MD.KON>,<CP10D>)	;DEVICE CODE 110
	EXP	0
CDPCFG:	XMOVEI	T1,CDPMDT##	;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		;REMEMBER DATA WORD FOR LATER
	MOVEI	T1,CDPIOB	;WORD CONTAINING AN I/O INSTRUCTION
	PUSHJ	P,AUTFND##	;SEE IF THERE'S ALREADY A DDB
	  JRST	CDPCF1		;JUST MAKE SURE THE NUMBERS ARE OK
	PUSHJ	P,AUTADN##	;ALLOCATE A DEVICE NUMBER
	HRLI	T1,'CDP'	;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
IFN FTMP,<
	MOVE	T1,CDPTMP(F)	;INTERLOCK COMES OUT ON 'DATA CHAN'
	ADDM	T1,DEVCPU(F)	;SWITCH IT TO FLAGS CHAN
>
CDPCF1:	MOVSI	T1,-<CDPIOE-CDPIOB> ;-LENGTH
	XMOVEI	T2,CDPIOB(F)	;STARTING ADDRESS
	HRRZ	T3,.CPDVC##	;DEVICE CODE
	PUSHJ	P,AUTDVC##	;FILL IN DEVICE CODES
	SKIPE	CDPCSO(F)	;BEEN HERE BEFORE?
	JRST	CDPCF3		;THEN DON'T MESS WITH THE SKIP CHAIN
	MOVE	T1,F		;DATA BLOCK ADDRESS
	XMOVEI	T2,CDPINT	;INTERRUPT SERVICE
	PUSHJ	P,AUTICD##	;GENERATE INTERRUPT ROUTINES
	  SKIPA	T2,F		;NO CORE
	JRST	CDPCF2		;ONWARD
	MOVEI	T1,CDPLEN	;GET DDB LENGTH
	PUSHJ	P,AUTKIL##	;DELETE THE DDB
	PUSHJ	P,AUTDDN##	;DEALLOCATE DEVICE NUMBER
	JRST	TPOPJ##		;PHASE STACK AND RETURN
CDPCF2:	MOVEM	T1,CDPCSO(F)	;SAVE ADDRESS
	MOVEI	T2,CPFCHN##	;PI CHANNEL FOR DATA
	HRRZ	T2,.CPSAV##-1(T2) ;GET ASSOCIATED SAVE ROUTINE
	HRRM	T2,CPFSVR(T1)	;FIXUP INTERRUPT CODE
	MOVEI	T2,CDPEXT(T1)	;INTERRUPT EXIT ADDRESS
	MOVEM	T2,CDPRET(F)	;SAVE
	MOVEI	T2,CDPCHN##	;PI CHANNEL
	PUSHJ	P,AUTCSO##	;LINK INTO CONSO SKIP CHAIN
	MOVE	T1,CDPCSO(F)	;START OF SKIP CHAIN CODE
	ADDI	T1,CPFINX	;OFFSET TO DATA CHANNEL INTERRUPT CODE
	MOVEM	T1,CDPCSF(F)	;SAVE FOR LATER
	MOVEI	T2,CPFCHN##	;PI CHANNEL
	PUSHJ	P,AUTCSO##	;LINK INTO CONSO SKIP CHAIN
CDPCF3:	POP	P,CDP10D(F)	;SET CP10D FLAG FROM MDT
	POPJ	P,		;ALL DONE
;CDP SERVICE DISPATCH TABLE
	JRST	CDPONL		;SEE IF NOW ON LINE
	JRST	ECOD2##		;SPECIAL ERROR STATUS
	JRST	CDPSTL		;DDB SETUP ROUTINE
	JRST	CDPINI		;INITIALIZE
	JRST	CDPHNG		;HUNG DEVICE
CDPDSP:	JRST	CDPRST		;RELEASE
	JRST	CDPCLS		;CLOSE
	JRST	CDPOUT		;OUTPUT
	JRST	ILLINP##	;INPUT IS ILLEGAL
;CLOSE UUO
CDPCLS:	TLO	S,CLSBIT	;CLOSE IS HAPPENING
	TLZ	S,CDPTBL	;CLEAR TROUBLE BIT

	MOVEM	S,DEVIOS(F)	;SAVE IN DDB
	PUSHJ	P,OUT##		;OUTPUT LAST PARTIAL BUFFER
	PUSHJ	P,WAIT1##	;WAIT FOR CARD TO BE PUNCHED
	TLZ	S,NOADV+CLSBIT+FILPRT	;ZERO SOME S BITS
	MOVEI	T1,7417		;SET TO PUNCH AN EOF CARD
	PUSHJ	P,SETFRE
	JRST	CDPON		;PUNCH IT AND RETURN TO USER


;HERE TO INITIALIZE
CDPINI:	MOVEI	T1,CDPDDB	;ADDRESS OF PROTOTYPE
	CAIN	T1,(F)		;IF CALLED FOR PROTOTYPE,
	JRST	CPOPJ1##	;WAIT FOR THE NEXT CALL
	MOVE	T1,[CDPDDB,,CDPCNT] ;OFFSET TO CARD COUNT
	MOVEM	T1,CDPOCC##	;SAVE FOR GETTAB
	AOS	(P)		;CALL FOR EACH CDP (AS IF THERE WERE TWO)

;HERE TO RESET DDB
CDPRST:	SETZ	T1,		;GET A WORD OF ZEROES
	DPB	T1,PBUFSZ##	;RESET SIZE TO ZERO
	TLZ	S,37010		;CLEAR ALL BITS IN S
	PUSHJ	P,STOIOS##	;AND SAVE IN DDB

	MOVSI	T1,DEPADV	;CLEAR DONT-ADVANCE BUFFERS BIT
	ANDCAM	T1,DEVADV(F)	; FROM DDB
	JRST 	CDPOFF		;GO TURN OFF PUNCH


;HERE TO SETUP DDB BUFFERSIZE
CDPSTL:	MOVEI	T1,21		;SET FOR ASCII
	TRNN 	M,10		;SKIP IF NOT ASCII
	POPJ	P,		;EXIT IF ASCII, T1=BUFFER SIZE
	MOVEI	T1,33		;SET FOR BINARY
	TRNN	M,4		;SKIP IF BINARY
	MOVEI	T1,34		;MUST BE IMAGE
	POPJ 	P,		;RETURN WITH T1=BUFFER SIZE

;SEE IF THE CDP IS ON-LINE
CDPONL:	MOVEI	U,CO.INI	;CLEAR PUNCH
	XCT	CDPCNO(F)
	XCT	CDPOAT(F)	;CHECK FOR TROUBLE
	JRST	CPOPJ1##	;CONTINUE IF READY
	MOVE	J,.CPJOB##	;SET FOR MSG IF NOT
	POPJ	P,		;OFF-LINE
;OUTPUT UUO
CDPOUT:
	TLZN	S,CDPTBL	;TROUBLE DETECTED ON INTERRUPT LEVEL?
	JRST	CDPOU1		;NO
	MOVEM	S,DEVIOS(F)	;YES, SAVE S (CDPTBL OFF)

CDPSTP:	MOVSI	T1,DEPADV	;BIT TO TELL HNGSTP NOT TO DE-ADVANCE BUFFERS
	IORM	T1,DEVADV(F)	;PUT IN DEVADV (=DEVADV(F))
	TLNE	S,IOBEG		;UNLESS VIRGIN BUFFERS
	ANDCAM	T1,DEVADV(F)	;THEN LET DE-ADVANCE HAPPEN
	MOVSI	T1,DVOFLN
	IORM	T1,DEVCHR(F)
	PUSHJ	P,HNGSTP##	;HALT JOB AND PRINT MESSAGE
	MOVSI	T1,DEPADV
	ANDCAM	T1,DEVADV(F)	;RESET DEPADV
	TLZ	S,IOSTBL	; AND S
CDPOU1:	TLO	S,IO		;TELL THE WORLD THIS IS OUTPUT
	PUSHJ	P,CDPONL	;ON LINE?
	  JRST	CDPSTP		;GO WAIT FOR "CONT" TO BE TYPED
	TLZE	S,CDPRCV	;RECOVERING
	JRST	CDPON		;YES, USE CURRENT BUFFER
	TLZN	S,IOBEG		;VIRGIN DEVICE?
	JRST	CDPSET		;NO
	MOVEI	T1,4242		;YES. SET TO PUNCH A FREE CARD
	TRNE	S,100		;029 CHAR SET?
	MOVEI	T1,5252		;YES.
	TRNN	S,14		;ASCII?
	PUSHJ	P,SETFRE	;YES. PUNCH A FREE CARD
;COME HERE TO SET UP THE MONITOR BUFFER
CDPSET:	MOVEM	S,DEVIOS(F)	;IOSET LOADS S
	PUSHJ	P,IOSET##	;SET UP J, S
	MOVEI	T3,44		;ASSUME BINARY
	TRNN	S,10		;IS IT?
	MOVEI	T3,7		;NO, SET BYTE SIZE FOR ASCII
	MOVEI	U,@DEVOAD(F)	;FIRST WORD OF BUFFER
	AOS	U		;POINT TO WDCNT WORD
	HRRZ	J,(U)		;WORD COUNT
	CAILE	J,33		;26 2/3 WORDS ALLOWED - IMAGE BIN
	MOVEI	J,33
	DPB	J,WDCPTR	;STORE IN WDCNT OF BINARY CARD
	MOVE	T2,T3
	PUSHJ	P,ITMCT1##	;NUMBER OF DATA ITEMS
	JUMPE	J,BUFADV	;TRY NEXT BUFFER IF NULL
	LSH	T3,6		;SET SIZE INTO POINTER
	HRLM	T3,U		;POINTER TO DATA
	TLZE	S,FILPRT	;CONTINUE IN SAME BUFFER?
	JRST	NXTCON		;YES. SET POINTER AND CONTINUE
NXTSET:	SETZM	CDPCCT(F)	;START AT COLUMN 1
	MOVSI	T1,CDPBUF(F)
	HRRI	T1,CDPBUF+1(F)
	SETZM	CDPBUF(F)	;ZERO THE BUFFER OF EXTRANEOUS DATA
	BLT	T1,CDPBUF+32(F)
	MOVEI	T3,CDPBUF-1(F)
	HLL	T3,U		;SET UP SIZE FIELD
	TLNE	T3,100		;IF ASCII, SET SIZE TO 14
	HRLI	T3,1400
TEMSET:	ILDB	T1,U		;DATA ITEM FROM USER
	TRNN	S,14		;ASCII?
	PUSHJ	P,ASCONV	;YES. CONVERT TO 12 BITS
	IDPB	T1,T3		;STORE IN MONITOR BUF
	SOJG	J,TEMSET	;LOOP ON COUNT
	TRNN	S,14
	JRST	SETPTR		;NO - IMAGE BIN OR ASCII
	TRNN	S,4
	JRST	TEMS2
	HRRZ	T2,DEVOAD(F)	;YES. COMPUTE CHKSUM
	PUSHJ	P,CKS12##
	MOVSS	T1		;IT COMES BACK IN LH(T1)
	DPB	T1,CKSPTR	;SAVE IN COLUMN 2 LOC
TEMS2:	LDB	T2,WDCPTR	;CONVERT WORDCOUNT TO
	IMULI	T2,3		;NUMBER OF COLS TO PUNCH
	ADDI	T2,2		;COLS 1 AND 2 ARE FREE
	TRNE	S,4
	SKIPA	T1,BINPTR	;OUTPUT POINTER IS BUF-1
SETPTR:	MOVE	T1,[POINT 12,CDPBUF(F),] ;ASCII POINTER IS BUF
	TDNN	S,[XWD CLSBIT,PCHBIT+10]
	JRST	PRTFUL		;NO. ASCII WITH NO LINE FEED
	MOVEM	T1,CDPNTR(F)	;POINTER TO DATA IN BUF
	MOVEM	T1,CDPOPT(F)	;SAVE FOR ERROR
	CAILE	T2,^D80		;ONLY PUNCH 80 COLUMNS
	MOVEI	T2,^D80
	MOVEM	T2,CDPCTR(F)	;NUMBER OF COLUMNS TO PUNCH
	MOVEM	T2,CDPOCT(F)	;SAVE FOR ERROR RECOVERY
	SETZM	CDPECT(F)
CDPON:	MOVEI	T1,5110		;DATA OR EOC INTERRUPTS
	SETZM	CDPEOC(F)	;INDICATE AN EOC INTERRUPT HERE IS SPURIOUS
	CONO	PI,PI.OFF
	HRRM	T1,@CDPCSO(F)	;

;(IF AN EJECT WAS GIVEN FOR THE PREVIOUS CARD, IT MAY STILL BE MOVING
;OUT OF THE PUNCH, AND WHEN IT FINALLY DOES CLEAR, AN END-OF-CARD INTERRUPT
;WILL BE GENERATED)
	MOVEI	U,3340		;START THE PUNCH, CLEAR ALL FLOPS
	ADD	U,CDPCHF(F)	; ENABLE ALL, SET PIA
	XCT	CDPCNO(F)
	CONO	PI,PI.ON
	TRO	S,IOACT		;SETACT ZEROES IOW, WHICH MIGHT BE ON
	TRZ	S,PCHBIT
	JRST	STOIOS##
;HERE TO CONVERT ASCII TO 12 BITS TO PUNCH
ASCONV:	AOS	T2,CDPCCT(F)	;PRESENT COLUMN
	JUMPE	T1,NOPUN	;FORGET IT IF A NULL
	CAIN	T1,12		;LINE FEED?
	JRST	PNCHCD		;YES. SET UP TO PUNCH
	CAIE	T1,15		;NO,CAR RET?
	CAIN	T1,14		;OR FORM FEED?
	JRST	NOPUN		;YES. IGNORE CHAR
	CAIN	T1,177		;RUB-OUT?
	JRST	NOPUN		;YES,IGNORE CHAR.
	CAILE	T2,^D80		;OVERFLOW?
	JRST	OVERFL		;YES. LIGHT IOBKTL
	CAIL	T1,40		;REGULAR CHARACTER?
	CAILE	T1,140
	JRST	SPEC		;NO. SPECIAL HANDLING
	SUBI	T1,40		;YES. CONVERT FROM TABLE
ASCNV2:	IDIVI	T1,3		;3 CHARS PER TABLE WORD
	TRNE	S,100		;029 SET?
	ADDI	T2,3		;YES. BUMP TO 029 TABLE
	LDB	T1,CRDPTR(T2)	;GET 12 BITS
	POPJ	P,		;AND RETURN


SPEC:	CAIL	T1,40		;LOWER CASE LETTER?
	CAILE	T1,172
	JRST	SPEC2		;NO. CONTROL CHAR
	TRZ	T1,100		;YES. CONVERT TO UPPER CASE, SUBI 40
	JRST	ASCNV2		;GET TABLE WORD

SPEC2:	CAIN	T1,11		;TAB?
	JRST	TAB		;YES. PUNCH SOME SPACES
	MOVEI	T1,100		;ILLEGAL CHAR - PUNCH "\"
	JRST	ASCNV2

TAB:	SETZ	T1,		;SET TO PUNCH A BLANK
	IDPB	T1,T3		;STORE A BLANK IN BUF
	TRNE	T2,7		;AT A TAB STOP ?
	AOJA	T2,.-2		;NO, SET NEXT COLUMN
	MOVEM	T2,CDPCCT(F)	;YES, SAVE UPDATED COLUMN
	JRST	CPOPJ1##	;AND CONTINUE
PNCHCD:	TRO	S,PCHBIT	;LIGHT PUNCH-A-CARD BIT
	SOJLE	J,NOPUN		;THROUGH WITH BUFFER IF 0
	ILDB	T1,U		;LOOK AT NEXT CHAR
	JUMPE	T1,.-2		;LOOP IF NULL
	TLO	S,NOADV		;REAL CHAR. - DONT ADVANCE BUFFERS
	MOVEM	U,CDPSVT(F)	;SAVE POINTERS TO DATA
	MOVEM	J,CDPSVJ(F)
	MOVEI	J,0		;SET TO DROP THROUGH LOOP
NOPUN:	SOSN	T2,CDPCCT(F)	;LAST CHAR SEEN IS NOT PUNCHED
	MOVEI	T2,1		;ALWAYS PUNCH 1 COLUMN
	JRST	CPOPJ1##	;RETURN

NXTPRT:	MOVE	U,CDPSVT(F)	;RESTORE POINTERS TO DATA
	MOVE	J,CDPSVJ(F)	;COUNT OF DATA LEFT
	JRSTF	@.+1		;LIGHT BYTE-INCREMENT-SUPPRESSION FLAG
	XWD	24000,NXTSET	;AND GO PUNCH NEXT CARD

PRTFUL:	MOVEM	T3,CDPSVT(F)
	TLO	S,FILPRT
	JRST	BUFADV


;CONTINUE IN SAME MONITOR BUFFER
NXTCON:	MOVE	T3,CDPSVT(F)	;POINTER TO LAST CHAR STORED
	JRST	TEMSET		;GO FILL REST

;SET UP TO PUNCH A FREE CARD
SETFRE:	MOVEM	T1,CDPFCD(F)	;WHAT TO PUNCH
	MOVEI	T1,^D80		;PUNCH 80 COLS.
	MOVEM	T1,CDPFCT(F)	;(EJECT ON 81ST DATA REQ)
	POPJ	P,
;INTERRUPT PROCESSING SECTION 
CDPINT:	XCT	CDPXST(F)	;STORE CONI STATUS IN DDB
	MOVEM	U,CDPTMP(F)	;SAVE U
	XCT	CDPZTE(F)	;EOC OR TROUBLE?
	JRST	NOTDAT		;NON-DATA INTERRUPT
	XCT	CDPZPE(F)	;NO, PUNCH ERROR?
	JRST	LACE		;YES, LACE REST OF CARD
	SKIPE	CDPFCD(F)	;DATA REQUEST. PUNCHING A FREE CARD?
	JRST	FREINT		;YES. PUNCH IT
	SOSGE	CDPCTR(F)	;ANY DATA TO PUNCH?
	JRST	CRDUN		;NO. THROUGH WITH CARD
	ILDB	U,CDPNTR(F)	;NEXT BYTE TO PUNCH
	XCT	CDPDOU(F)	;GIVE IT TO PUNCH
INTXIT:	SETOM	CDPEOC(F)	;ANY EOC INTERRUPT AFTER THIS IS LEGAL
INTXI1:	MOVE	U,CDPTMP(F)	;RESTORE U
	XJRST	CDPRET(F)	;AND DISMISS INTERRUPT

;HERE WHEN ALL DATA FOR A CARD IS PUNCHED
CRDUN:	MOVEI	U,10020		;EJECT A CARD
	SETOM	CDPEOC(F)	;ANY EOC INTERRUPT AFTER THIS IS LEGAL
	JRST	CRDUNX


;HERE FOR A DATA REQUEST WHILE PUNCHING A FREE CARD
FREINT:	SOSGE	CDPFCT(F)	;PUNCHED 80 COLS.
	JRST	CRDUN		;YES, EJECT
	XCT	CDPDFC(F)	;NO, PUNCH A COLUMN
	JRST	INTXIT		;EOC INTERRUPT IS LEGAL, DISMISS THE INTERRUPT

LACE:	SKIPE	CDP10D(F)	;IS THIS A CP10D?
	JRST	NOTDAT		;YES, CARD IS AUTOMATICALLY REJECTED
	XCT	CDPDSV(F)	;NO, LACE REST OF CARD
	XJRST	CDPRET(F)	;DISMISS INTERRUPT
;HERE ON A NON DATA-REQUEST INTERRUPT
NOTDAT:	CONO	PI,PI.OFF	;TURN OFF PI FOR SAFETY'S SAKE
	MOVEI	U,2220		;SWITCH CDP TO LOW PI LEVEL
CRDUNX:	ADDI	U,CPFCHN##	;PIA
	XCT	CDPCNO(F)
	HLLZS	@CDPCSO(F)	;FOR END-OF-CARD PROCESSING
	MOVEI	U,5100		;ENABLE FOR ALL BUT DATA REQUEST
	HRRM	U,@CDPCSF(F)
	CONO	PI,PI.ON	;RESTORE PI SYSTEM
	JRST	INTXI1		; AND GO AWAY

;INTERRUPT HERE ON LOWER LEVEL PI REQUEST
CPFINT:	XCT	CDPXST(F)
	HLLZS	@CDPCSF(F)	;YES, WE WONT WANT THIS PI INTRPT AGAIN
	MOVE	S,DEVIOS(F)	;SET S
	LDB	J,PJOBN##
	XCT	CDPZTB(F)	;TROUBLE?
	JRST	TRBL		;YES
	XCT	CDPZER(F)	;ERROR?
	JRST	ERROR		;YES. TOO BAD

;HERE ON AN END OF CARD INTERRUPT
	SKIPN	CDPEOC(F)	;SPURIOUS END-OF-CARD INTERRUPT?
	JRST	CDPON		;YES. CLEAR EOC AND TRY AGAIN
	AOS	CDPCNT(F)	;COUNT THE CARDS
				;AND FALL INTO CRDUN1

;HERE ON EOC INTERRUPT
	XCT	CDPZTB(F)	;PUNCH ERROR?
	JRST	ERROR		;YES. TOUGH
	MOVEI	U,10020
	XCT	CDPZCP(F)	;CARD IN PUNCH?
	XCT	CDPCNO(F)	;YES, EJECT IT
SEVENS:	SETZ	T1,1414
	EXCH	T1,CDPFCD(F)	;DONE WITH A FREE CARD IF T1 NOT 0
	JUMPN	T1,FREDUN
BUFADV:	TLZE	S,NOADV
	JRST	NXTPRT		;PUNCH MORE FROM SAME BUFFER
				;IO WAIT?
	PUSHJ	P,SETIOD##	;YES. WAKE IT UP
	PUSHJ	P,ADVBFE##	;ADVANCE BUFFERS
	  JRST	CDPOFF		;NEXT IS NOT READY
	JRST	CDPSET		;GO PUNCH THIS BUFFER

FREDUN:	SKIPG	CDPCTR(F)	;MORE DATA TO PUNCH?
	JRST	TRNOFF		;NO. SHUT DOWN PUNCH
	XCT	CDPZCP(F)	;CARD STILL IN PUNCH
	JRST	.-1		;YES, WAIT FOR IT TO CLEAR
	JRST	CDPON		;YES. DO NEXT CARD
OVERFL:	POP	P,T1
	TROA	S,IOBKTL	;YES. ERROR
TOOBAD:	TRO	S,IODERR	;DEVICE ERROR
TRNOFF:	PUSHJ	P,SETIOD##	;TAKE OUT OF IO WAIT

CDPOFF:	MOVEI	U,CO.INI	;RESET PUNCH
	XCT	CDPCNO(F)
	HLLZS	@CDPCSO(F)	;DONT LOOK AT INTERRUPTS
	TRZ	S,IOACT		;CLEAR IOACT (ION MAY BE ON)
	PUSHJ	P,RTEVMO##
	JRST	STOIOS##	;AND RETURN



;HERE ON TROUBLE OR PUNCH ERROR
ERROR:	MOVEI	U,51120		;PUNCH ERROR - EJECT OFFSET
	XCT	CDPCNO(F)
	AOS	T1,CDPECT(F)	;BUMP RETRY COUNT
	CAIL	T1,CDTRY	;TRIED ENOUGH?
	JRST	TOOBAD		;YES. SHUT DOWN
	MOVE	T1,CDPOPT(F)	;NO. RESET TO TRY AGAIN
	MOVEM	T1,CDPNTR(F)
	MOVE	T1,CDPOCT(F)
	MOVEM	T1,CDPCTR(F)
	JRST	CDPON		;TRY TRY AGAIN
CDPHNG:	AOS	(P)		;SKIP RETURN SO NO HUNG MESSAGE
TRBL:	TLO	S,CDPTBL+CDPRCV	;YES, SET TROUBLE
	XCT	CDPOTN(F)	;SKIP IF TROUBLE CONDITION WHICH DOES
				; NOT REQUIRE RESETTING BUFFERS.
	XCT	CDPOER(F)	;SKIP IF ERROR ON
	JRST	CDPHG1		;NO
	MOVE	T1,CDPOPT(F)	;YES, RESET POINTERS FOR NEXT CARD
	MOVEM	T1,CDPNTR(F)
	MOVE	T1,CDPOCT(F)
	MOVEM	T1,CDPCTR(F)
CDPHG1:	PUSHJ	P,CDPOFF	;TURN OFF CDP
	JRST	DEVERR##	;CAUSE UUOCON TO RETRY AT UUO LEVEL


CRDPTR:	POINT	12,TBL26(T1),11
	POINT	12,TBL26(T1),23
	POINT	12,TBL26(T1),35
	POINT	12,TBL29(T1),11
	POINT	12,TBL29(T1),23
	POINT	12,TBL29(T1),35

TBL26:	BYTE	(12)	0,4006,1022	;SPACE ! "
	BYTE	(12)	1012,2102,1006	;# $ %
	BYTE	(12)	2006,12,1042	;& ' (
	BYTE	(12)	4042,2042,4000	;) * +
	BYTE	(12)	1102,2000,4102	;, - .
	BYTE	(12)	1400,1000,400	;/ 0 1
	BYTE	(12)	200,100,40	;2 3 4
	BYTE	(12)	20,10,4		;5 6 7
	BYTE	(12)	2,1,3000	;8 9 :
	BYTE	(12) 	1202, 4012, 102	;; < =
	BYTE	(12)	2012,5000,42	;> ? @
	BYTE	(12)	4400,4200,4100	;A B C
	BYTE	(12)	4040,4020,4010	;D E F
	BYTE	(12)	4004,4002,4001	;G H I
	BYTE	(12)	2400,2200,2100	;J K L
	BYTE	(12)	2040,2020,2010	;M N O
	BYTE	(12)	2004,2002,2001	;P Q R
	BYTE	(12)	1200,1100,1040	;S T U
	BYTE	(12)	1020,1010,1004	;V W X
	BYTE	(12)	1002,1001,2022	;Y Z [
	BYTE	(12)	6,4022,22	;\ ] ^
	BYTE	(12)	202,6,0		;_ (100=\)

TBL29:	BYTE	(12)	0,4006,6	;SPACE ! "
	BYTE	(12)	102,2102,1042	;# $ %
	BYTE	(12)	4000,22,4022	;& ' (
	BYTE	(12)	2022,2042,4012	;) * +
	BYTE	(12)	1102,2000,4102	;, - .
	BYTE	(12)	1400,1000,400	;/ 0 1
	BYTE	(12)	200,100,40	;2 3 4
	BYTE	(12)	20,10,4		;5 6 7
	BYTE	(12)	2,1,202		;8 9 :
	BYTE	(12)	2012,4042,12	;; < =
	BYTE	(12)	1012,1006,42	;> ? @
	BYTE	(12)	4400,4200,4100	;A B C
	BYTE	(12)	4040,4020,4010	;D E F
	BYTE	(12)	4004,4002,4001	;G H I
	BYTE	(12)	2400,2200,2100	;J K L
	BYTE	(12)	2040,2020,2010	;M N O
	BYTE	(12)	2004,2002,2001	;P Q R
	BYTE	(12)	1200,1100,1040	;S T U
	BYTE	(12)	1020,1010,1004	;V W X
	BYTE	(12)	1002,1001,4202	;Y Z [
	BYTE	(12)	1202,2202,2006	;\ ] ^
	BYTE	(12)	1022,1202,0	;_ (100=\)
WDCPTR:	POINT	5,CDPBNB(F),17
CKSPTR:	POINT	12,CDPBNB(F),35
BINPTR:	POINT	12,CDPBNB(F),11
	$LIT

	END