Google
 

Trailing-Edge - PDP-10 Archives - BB-X140B-BB_1986 - 10,7/703anf/dncrd.p11
There are 3 other files named dncrd.p11 in the archive. Click here to see a list.
.SBTTL	DNCRD - CARD READER ROUTINES  28 MAR 79

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980,1981,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.

VRCRD=004			;FILE EDIT NUMBER

.IF NE CDRN

DRESET=0
	DDBGEN	CDR,CR,CDRN,0,<0>	;MAKE A DEVICE BLOCK FOR THE CDR

;DATA SENT TO DECSYSTEM-10 IS ESSENTIALY IMAGE MODE
;	REPRESENTATION	MEANING
;	1CCCCCCC	CCCCCCC = SEVEN BIT ENCODED CHARACTER
;			PUNCH 12=B6; PUNCH 11=B5; PUNCH 0=B4
;			CODE	PUNCHES IN ROWS 1-9
;			0	NONE
;			1	1
;			2	2
;			3	3
;			4	4
;			5	5
;			6	6
;			7	7
;			10	8
;			11	9
;			12	8-2
;			13	8-3
;			14	8-4
;			15	8-5
;			16	8-6
;			17	8-7
;	01XXXXXX	XXXXXX =COUNT OF BLANKS
;	001XXXXX	XXXXX = COUNT OF REPETITIONS, 0-31
;	0000CCCC
;	CCCCCCCC	CCCCCCCCCCCC = TWELVE BIT ENCODED CHARACTER
;
;	DB.DCS - DEVICE CONTROL STATUS BITS
	CS.ERR=0001	;CARD READER ERROR(MASTER ERROR)
	CS.HEM=0002	;HOPPER EMPTY
	CS.RER=0004	;REGISTRATION ERROR
;	0010	INVALID PUNCH
	CS.FUL=0020	;STACKER FULL
	CS.JAM=0040	;JAM WHILE FEEDING
	CS.PCK=0100	;PICK FAILURE
	CS.EOF=0200	;END OF FILE CARD
;	0400	HDW EOF
;	1000	CDR OVERRAN THE PROCESSOR
	CS.OFL=2000	;CDR HAS GONE OFF LINE
	CS.STP=4000	;CDR STOPPED (CLEARED BY 10 WITH CLEAR STATUS MSG)
.IF NE DGUTS
CDRNCE:	TST	#0
CDRNCC=.-2
	BNE	CDRGBY
	CTYMSG	NCL
	MOVB	NCLMSG,CDRNCC
	BR	CDRGBY
.ENDC ;.IF NE DGUTS

CDRSER:	MOVB	#1,DB.DVV(J)		;CR-11 IS CONTROLLER TYPE 1
	JSR	PC,DVCCFM		;SEND CONNECT CONFIRM

;HERE USUALLY TO CHECK ON THE CARD READER

	BIT	#DS.ACT,@J		;IS CARD READER ACTIVE
	BEQ	5$
	RTS	PC
5$:	BIT	#DS.DIE!DS.DSC,@J	;ARE WE THROUGH ?
	BEQ	CDRGBY
	JMP	DVCCFM			;CLEAN OUT DEVICE BLOCK AND EXIT
CDRGBY:	JSR	PC,DVGBYT		;GET STATUS MESSAGE IF ANY
.IF EQ DGUTS
	TRAP				;SHOULD BE NO DATA YET !
.IFF
	BR	CDRNCE			;REPORT ERROR
.ENDC ;.IF EQ DGUTS
	BR	12$			;THERE IS ONE !
	BR	30$			;NONE PENDING
12$:	ASSERT	R0 EQ #3		;MUST BE STATUS MSG
.IF NE DGUTS
	CMP	#3,R0
	BNE	CDRNCE			;IF NOT STATUS MSG, CHUCK IT
.ENDC ;.IF NE DGUTS
20$:	JSR	PC,DVRSTS		;GO GET IT
	BR	CDRGBY			;GO CHECK FOR MORE

;HERE TO SEE IF 10 WANTS TO READ ANOTHER CARD
30$:	BIT	#DS.ACT,@J		;IS READER ACTIVE
	BNE	CDRSR9			;IF SO NOTHING MORE
	TSTB	DB.IDR(J)		;HAS 10 ASKED FOR CARDS ?
	BEQ	CDRSR9
	MOV	DB.IBF(J),R0		;GET ADDRESS OF BUFFER
	BEQ	40$
	JSR	PC,NCLIN1		;QUEUE MESSAGE
	CLR	DB.IBF(J)
	DECB	DB.IDR(J)
	BEQ	CDRSR9			;IF NOT WE ARE DONE FOR NOW

;HERE TO TRY TO READ ANOTHER CARD
40$:	MOV	DB.DCS(J),R0		;GET DEVICE STATUS
	BIT	#CS.STP,R0		;IS READER STOPPED ?
	BNE	42$
	BIC	#CS.EOF,R0		;IF NOT STOPPED CLEAR EOF-CARD FLAG
	CLR	@DB.HDW(J)		;CLEAR STICKY ERROR BITS
42$:	BIC	#CS.OFL!CS.PCK!CS.JAM!CS.FUL!CS.RER!CS.ERR,R0	;CLEAR ERROR BITS
	MOV	@DB.HDW(J),R1		;GET HDW STATUS BITS
	BIT	#CR.HCK,R1		;HOPPER CHECK ?
	BEQ	44$
	BIS	#CS.HEM!CS.FUL,R0	;SET HOPPER FLAGS
44$:	BIT	#CR.RDY,R1		;IS NOT READY UP ?
	BEQ	48$			;IF NO OK
	BIS	#CS.OFL,R0		;OFF-LINE
48$:	BIT	#CR.MCK!CR.TIM,R1	;TIMING OR MOTION ERROR DETECTED ?
	BEQ	50$
	BIS	#CS.RER,R0		;CALL THAT A REGISTRATION ERROR
50$:	BIT	#CR.ERR,R1		;HDW GENERAL ERROR BIT UP ?
	BNE	52$			;IF SO SET GENERAL ERROR
	BIT	#CS.OFL!CS.PCK!CS.JAM!CS.FUL!CS.RER,R0	;ARE ANY ERROR BITS SET ?
	BEQ	54$
52$:	BIS	#CS.STP!CS.ERR,R0	;SET MASTER ERROR BIT
54$:	CMP	R0,DB.DCS(J)		;DID STATUS CHANGE ?
	BEQ	60$
	BIS	#DS.XDS,@J		;YES SO SEND TO 10
	MOV	R0,DB.DCS(J)		;SAVE UPDATED STATUS
60$:	JSR	PC,DVXDCS		;SEND DEVICE CONTROL STATUS IF WE NEED TO
	BIT	#CS.STP,DB.DCS(J)	;IS READER STOPPED ?
	BNE	CDRSR9			;IF SO DON'T TRY TO READ
	MOV	DB.SCB(J),SB		;DESTINATION
	MOV	SB,DNA
	MOV	#OURSCB,SNA
	CLR	R1			;SENDING NUMBERED DATA MESSAGE
	JSR	PC,NCLBMS		;TRY TO BEGIN NCL MESSAGE
.IF EQ DGUTS
	ASSERT	NE
.IFF
	BNE	62$
	MOV	DB.DCS(J),R0		;GET STATUS
	BR	52$			;AND SEND ERROR STATUS
62$:
.ENDC ;.IF EQ DGUTS
	MOV	(P)+,DB.IBF(J)		;SAVE INPUT BUFFER POINTER
	MOV	DB.RLA(J),R0		;GET DESTINATION LINK ADDRESS
	JSR	PC,PUTEXN		;PUT IT INTO THE MESSAGE
	MOV	R3,DB.ICN+4(J)		;SAVE ADDRESS OF COUNT FIELD
	CLR	R0
	JSR	PC,PUTBYT		;FOR COUNT
	JSR	PC,PUTBYT
	MOV	R2,DB.ICN(J)		;SAVE INPUT BYTE COUNT
	MOV	#1,R0			;DATA W EOR
	MOV	R0,DB.ICN+2(J)		;SAVE COUNT FOR DATA PORTION
	JSR	PC,PUTBYT
	MOV	R3,DB.IAD(J)		;SAVE INPUT BYTE POINTER
	MOVB	#^D80,DB.COL(J)		;COLUMN COUNTER
	BIC	#CS.EOF,DB.DCS(J)	;CLEAR SAW EOF CARD BIT
	BIS	#DS.ACT,@J		;SET CARD READER ACTIVE
	MOVB	#-4,DB.TIM(J)		;4 SECONDS TO READ A CARD
	BIS	#CR.INE!CR.CFD,@DB.HDW(J)	;ENABLE INTERRUPTS AND MOVE CARD
CDRSR9:	RTS	PC
;HERE IF CARD READER TIMES OUT = PICK CHECK
CDRTIM:	PIOFF				;DISABLE INTERRUPTS FOR WHILE
	BIT	#DS.ACT,@J		;IS DEVICE ACTIVE ?
	BEQ	80$			;IF NOT QUEUE UP DEVICE ROUTINE
	BIS	#CS.STP!CS.ERR,DB.DCS(J)	;PICK CHECK BIT
	BIS	#DS.XDS,@J		;NEED TO SEND STATUS
	BIC	#DS.ACT,@J		;NO LONGER ACTIVE
	BIC	#CR.INE,@DB.HDW(J)	;CLEAR INTERRUPT ENABLE
	MOV	DB.IBF(J),R0		;GET POINTER TO MSG
	CLR	DB.IBF(J)		;LOSE POINTER TO INPUT
	JSR	PC,FRECKS		;LOSE INPUT
80$:	JSR	PC,QUEDEV
	PION
	RTS	PC
;HERE ON AN INTERRUPT FROM THE CDR

DEVINT	CDR,CR

CDRINT:	SAVE	<R0,R1,R2,R3>
	BIT	#CR.ERR!CR.DNE,@DB.HDW(J)	;CARD DONE OR ERROR ?
	BNE	20$			;BRANCH FOR DONE OR ERROR
	MOV	CR.DAT,R3		;GET DATA FROM CARD
	CMPB	#^D80,DB.COL(J)		;IS THIS 1ST COLUMN ?
	BNE	12$
;	CMP	#17,R3			;CHECK FOR EOF
;	BEQ	10$			;IF SO SET BIT
;	CMP	#7400,R3		;ANOTHER TYPE
;	BEQ	10$
	CMP	#7417,R3		;LAST TYPE
	BNE	12$
10$:	BIS	#CS.STP!CS.EOF,DB.DCS(J)	;REMEMBER THAT
	BIS	#DS.XDS,@J		;SEND STATUS TO 10
12$:	DECB	DB.COL(J)		;COUNT COLUMN
	BMI	99$			;IGNORE IF TOO MUCH
	TSTB	DB.CCN(J)		;COMPRESEED ANY YET ?
	BEQ	90$			;IF NOT JUST SAVE THIS DATA
	CMP	R3,DB.CHR(J)		;IS DATA SAME AS LAST COLUMN ?
	BEQ	92$			;IS SO JUST COUNT IT
	MOV	R3,-(P)			;SAVE CURRENT DATA
	JSR	PC,CRIN50		;PUT OLD DATA INTO MESSAGE
	MOV	(P)+,R3			;GET OLD DATA BACK
90$:	MOV	R3,DB.CHR(J)		;SAVE THIS DATA FOR LATER
92$:	INCB	DB.CCN(J)		;COUNT CHARACTER
	CMPB	DB.CCN(J),#37		;CHECK SIZE OF COUNT
	BMI	99$			;IF OK DISMISS
	TST	DB.CHR(J)		;WAS CHAR BLANK
	BNE	97$			;IF NOT PUT OUT NOW
	CMPB	DB.CCN(J),#77		;GET MORE WITH BLANKS
	BMI	99$
97$:	JSR	PC,CRIN50		;PUT OUT DATA SO FAR
99$:	RESTORE	<R3,R2,R1,R0>
	RESTORE	<J>
	RTI

;HERE BECAUSE OF READER ERROR OR DONE
20$:	TSTB	DB.CCN(J)		;CHARS NEED TO GO INTO MSG ?
	BEQ	22$
	JSR	PC,CRIN50		;IF SO PUT THEM
22$:	MOV	DB.ICN+2(J),R0		;GET COUNT FOR MESSAGE
	MOV	R0,R3			;COPY COUNT
	BIS	#200,R3			;SET EXTENSIBLE BIT
	MOV	DB.ICN+4(J),R2		;GET ADR OF COUNT FIELD
	MOVB	R3,(R2)+		;PUT LOW ORDER COUNT IN FIELD
	MOV	R0,R3			;COPY COUNT FIELD AGAIN
	ASL	R3
	SWAB	R3
	MOVB	R3,(R2)+		;PUT HIGH ORDER PART OF COUNT IN MSG
	MOV	DB.IBF(J),R1		;GET ADDRESS OF CHUNK
	ADD	DB.ICN(J),R0		;MAKE MSG COUNT
	MOV	R0,CN.LEN(R1)
	BIC	#CR.INE,@DB.HDW(J)
	BIC	#DS.ACT,@J
	JSR	PC,QUEDEV
	BR	99$

;HERE TO PUT COMPRESSED(MAYBE) DATA INTO THE MESSAGE
CRIN50:	MOV	DB.CHR(J),R3		;GET CHAR TO PUT INTO MESSAGE
	BEQ	56$			;BRANCH IF WE NEED TO COMPRESS BLANKS
	CMPB	#1,DB.CCN(J)		;ARE WE DOING COMPRESSION ?
	BEQ	52$			;NO SO JUST PUT CHAR INTO MESSAGE
	MOVB	DB.CCN(J),R3		;GET COUNT
	BIS	#040,R3			;FLAG THIS IS REP COUNT
	JSR	PC,70$			;PUT INTO MESSAGE
	MOV	DB.CHR(J),R3		;GET CHAR AGAIN
52$:	MOV	R3,R2			;COPY BITS
	BIC	#^C<17>,R2		;STRIP EXTRA BITS
	MOVB	CD2TAB(R2),R0		;GET TRANSLATE BITS
	BMI	54$			;BRANCH IF NOGO
	MOV	R3,R2			;COPY BITS AGAIN
	ASR	R2			;POSITION BITS
	ASR	R2
	ASR	R2
	ASR	R2
	BIC	#^C37,R2		;STRIP EXTRA BITS
	MOVB	CD1TAB(R2),R2		;GET BITS FOR THIS PORTION
	BMI	54$
	ADD	R0,R2			;GET COMBINED BITS
	TSTB	R2			;SEE IF NICE
	BMI	54$			;BRANCH IF NASTY
	BIC	#^C17,R2		;STRIP EXTRA BITS
	BIC	#^C7000,R3		;STRIP LOW BITS
	SWAB	R3			;POSITION BITS 12/11/0
	ASL	R3
	ASL	R3
	ASL	R3
	BIS	R2,R3
	BIS	#200,R3			;SET FLAG
	BR	59$
54$:	SWAB	R3			;GIVE HIM HIGH ORDER BITS FIRST
	JSR	PC,70$			;PUT INTO MESSAGE
	SWAB	R3			;NOW LOW ORDER BITS
	BR	59$			;HAVE PUT IT INTO MESSAGE
56$:	MOV	#100,R3			;FLAG WE ARE DOING COMPREESED BLANKS
	BISB	DB.CCN(J),R3		;INCLUDE COUNT
59$:	JSR	PC,70$			;PUT BYTE INTO MESSAGE
	CLRB	DB.CCN(J)		;NO COMPRESSED COUNT NOW
	RTS	PC

;HERE TO PUT A BYTE INTO THE MESSAGE
70$:	INC	DB.ICN+2(J)		;COUNT COLUMN
	MOV	DB.IAD(J),R1		;GET INPUT BYTE ADDRESS
	MOVB	R3,(R1)+		;PUT BYTE INTO MESSAGE
	ADVCNK R1 EXTEND		;GET ANOTHER CHUNK IF NECESSARY
77$:	MOV	R1,DB.IAD(J)		;SAVE UPDATED BYTE POINTER
	RTS	PC
;CARD CODE TRANSLATION TABLES
; TRICK IS USE ROWS TO INDEX INTO THE TABLES
; IF THE RESULT HAS THE SIGN BIT ON CAN'T COMPRESS COLUMN
;TABLE TO TRANSLATE ROWS 1/2/3/4/5
CD1TAB:	.BYTE	000	;
	.BYTE	105	; 5
	.BYTE	104	; 4
	.BYTE	200	; 4/5
	.BYTE	103	; 3
	.BYTE	200	; 3/5
	.BYTE	200	; 3/4
	.BYTE	200	; 3/4/5
	.BYTE	102	; 2
	.BYTE	200	; 2/5
	.BYTE	200	; 2/4
	.BYTE	200	; 2/4/5
	.BYTE	200	; 2/3
	.BYTE	200	; 2/3/5
	.BYTE	200	; 2/3/4
	.BYTE	200	; 2/3/4/5
	.BYTE	141	; 1
	.BYTE	200	; 1/5
	.BYTE	200	; 1/4
	.BYTE	200	; 1/4/5
	.BYTE	200	; 1/3
	.BYTE	200	; 1/3/5
	.BYTE	200	; 1/3/4
	.BYTE	200	; 1/3/4/5
	.BYTE	200	; 1/2
	.BYTE	200	; 1/2/5
	.BYTE	200	; 1/2/4
	.BYTE	200	; 1/2/4/5
	.BYTE	200	; 1/2/3
	.BYTE	200	; 1/2/3/5
	.BYTE	200	; 1/2/3/4
	.BYTE	200	; 1/2/3/4/5

;TABLE TO TRANSLATE ROWS 6/7/8/9
CD2TAB:	.BYTE	000	;
	.BYTE	111	; 9
	.BYTE	050	; 8
	.BYTE	200	; 8/9
	.BYTE	107	; 7
	.BYTE	200	; 7/9
	.BYTE	117	; 7/8
	.BYTE	200	; 7/8/9
	.BYTE	106	; 6
	.BYTE	200	; 6/9
	.BYTE	116	; 6/8
	.BYTE	200	; 6/8/9
	.BYTE	200	; 6/7
	.BYTE	200	; 6/7/9
	.BYTE	200	; 6/7/8
	.BYTE	200	; 6/7/8/9
.ENDC;.IF NE CDRN