/COPYRIGHT DIGITAL EQUIPMENT CORPORATION    1969
/MAYNARD,MASS.
/CDB -- IOPS ASCII ONLY CARD READER HANDLER.
/TALKS TO CR01E, CR02B, AND CR03B CARD READERS.
/7-31-68
/IOPS4:
/	HOPPER EMPTY
/	STACKER FULL
/	NOT READY:	STOP BUTTON DEPRESSED
/			START BUTTON NOT DEPRESSED
/			VALIDITY CHECK WITH VALID. BUTTON ON
/	FEED CHECK
/	READ CHECK
/
/END-OF-MEDIUM:
/	EOF CARD (ALL 1'S IN COLUMN 1)
/	EOF BUTTON DEPRESSED WITH HOPPER EMPTY
.MED=3
/
/--------------- CRO3B
/
	.IFUND	NOTGDI
CRSC=706722	/SELECT A CARD
CROR=706702	/IOR DATA AND STATUS INTO AC
CRCS=706704	/CLEAR STATUS REGISTER AND DATA BUFFER
CRSI=706721	/SKIP IF COR INTERRUPT IS SET
CRLA=706724	/IOR DATA BUFFER AND STATUS REGISTER INTO AC.
CROC=706716	/CLEAR AC,IOR DATA+STATUS,CLEAR STATUS
	.ENDC
/-----
/
	.IFDEF	NOTGDI
CRSI=706701		/SKIP ON COLUMN READY FLAG.
CRSD=706721		/SKIP ON CARD DONE FLAG.
CRCD=706724		/CLEAR CARD DONE FLAG.
CRSC=706744		/SELECT CARD, BINARY MODE.
CRRB=706752		/READ BUFFER, BINARY MODE.
CRSR=706741		/SKIP ON READER READY.
CREF=706761		/SKIP ON EOF BUTTON (CR02 ONLY)
	.ENDC
	.GLOBL CDB.
CDB.	DAC CDCALP	/SAVE POINTER TO CAL INSTRUCTION.
	DAC CDARGP	/POINTER TO ARGUMENT LIST ALSO.
	ISZ CDARGP	/BUMP TO FUNCTION CODE.
	LAC* CDARGP	/PICK UP FUNCTION CODE.
	ISZ CDARGP	/BUMP TO NEXT ARGUMENT OR TO RETURN.
	ADD (JMP CDBDSP	/FORM DISPATCH ADDRESS.
	DAC .+1		/SET UP JMP INTO DISPATCH TABLE.
CDBDSP	XX		/DISPATCH ON FUNCTION.
	JMP CDINIT	/1 -- .INIT
CD7700	LAW 10000		/2 -- .OPER (IGNORED)
	JMP CDRBMP	/3 -- .SEEK (IGNORED)
	JMP CDERR6	/4 -- .ENTER (ILLEGAL)
	JMP CDERR6	/5 -- .CLEAR (ILLEGAL)
	JMP CDWAIT	/6 -- .CLOSE
	JMP CDIGNR	/7 -- .MTAPE (IGNORED)
	JMP CDREAD	/10 -- .READ
	JMP CDERR6	/11 -- .WRITE (ILLEGAL)
	JMP CDWATR	/12 -- .WAIT,.WAITR
CDERR6	LAW 6		/13 -- .TRAN (ILLEGAL)
CDRSKP	SKP		/GO TO .MED
CDERR7	LAW 7		/ILLEGAL DATA MODE.
	JMP* (.MED+1	/TO .MED.
/INITIALIZE CARD READER.
CDINIT	ISZ CDARGP	/BUMP TO BUFFER SIZE LOCATION.
	LAC (44		/GET STANDARD SIZE (36(10)).
	DAC* CDARGP	/INSERT BUFFER SIZE IN ARGUMENT LIST.
CDRBMP	ISZ CDARGP	/BUMP TO RETURN.
CDSETP	CAL+55		/ENTER ONE-TIME SECTION TO SET UP
CDLPTR	16		/SKIP CHAIN AND API CHANNEL REGISTER.
CDCPTR	CRSI
CDTLEN	CDRINT		/INTERRUPT HANDLER.
CDR7CT=CDTLEN
	.IFDEF	NOTGDI
CDRWD1	CAL+55		/SECOND CARD READER SKIP IOT.
CDRWD2	16		/CALL .SETUP AGAIN.
CDRWD3	CRSD		/FOR CARD DONE FLAG.
CDRLBH	CDRINT		/SAME PLACE.
	.ENDC
CDCOLC	LAC .+2		/GET JMP TO RETURN.
CDIPTR	DAC CDSETP	/SET TO IGNORE FURTHER CALLS.
CDWDCT	JMP CDIGNR	/RETURN TO CALLER.
/WAIT FOR CARD READER.
CDWATR	LAW 1000
	AND* CDCALP	/WAIT?
	SNA		/NO, WAITR
	JMP CDWAIT
	LAC (700000	/LINK, ETC
	AND CDCALP
	DAC CDCALP
	LAC* CDARGP	/WAITR ADDRESS
	AND (77777
	XOR CDCALP
	ISZ CDARGP
	DAC CDCALP
CDWAIT	JMS CDRMAP	/GO SEE IF PREVIOUS INPUT IS COMPLETE.
CDIGNR	DBR		/ALL FINISHED, DEBREAK FROM LEVEL 4.
	XCT .+1
	JMP* CDARGP	/AND RETURN BELOW ARGUMENT LIST.
CDRBSY	DBR		/NOT DONE YET, DEBREAK.
	XCT .+1
	JMP* CDCALP	/AND RETURN TO CAL.
/INITIATE READ TO CARD READER.
CDREAD	JMS CDRMAP	/ARE WE DONE YET WITH PREVIOUS READ?
	LAW 7000	/YES, PICK UP CAL -- DATA MODE IN 6-8.
	AND* CDCALP		/MASK OUT 6-8.
	XOR (2000		/ZERO IOPS ASCII INDICATOR.
	SZA		/WILL SKIP IF IOPS ASCII IS WANTED.
	JMP CDERR7	/NOT IOPS ASCII, COMPLAIN.
	LAC* CDARGP	/PICK UP LINE BUFFER ADDRESS.
	DAC CDRLBH	/GIVE TO LINE BUFFER POINTER.
	LAC CDSETP		/SET RETURN ADDRESS(JMP CDIGNR,NOW)
	DAC CDRRET		/FROM READ
	ISZ CDARGP	/BUMP TO WORD COUNT.
	LAC* CDARGP	/GET THAT,
	DAC CDWDSV	/SAVE IN CASE OF IOPS4.
	ISZ CDARGP	/BUMP TO RETURN.
	.IFDEF	NOTGDI
CDRRTN	CREF		/EOF BUTTON OR HOPPER EMPTY?
	JMP CDOK		/NO, GO ON
CDREOM	LAC (1006		/END-OF-MEDIUM, GET HEADER INDICATOR.
	DAC CDRMSW	/GIVE TO REMAPPER.
	DZM CDIOSW	/INDICATE NO IO IN PROGRESS.
	JMP CDIGNR	/THEN GO TO RETURN.
	.ENDC
/SET UP AND START I/O
CDOK	LAC (CDBUFF	/GET ADDR. OF HANDLER BUFFER
	DAC CDIPTR	/SET DESTINATION OF FIRST COLUMN
	DZM* CDIPTR	/CLEAR FIRST COLUMN
	.IFDEF NOTGDI
	LAW -120		/COUNT 80 COLUMNS MAXIMUM
	DAC CDCOLC	/..
	CRSR	/ENSURE THAT READER IS READY
	JMP CDR4		/NOT READY, IOPS 4
	.ENDC
	DZM CDRVAL
	.IFUND NOTGDI
	DZM CDERSW	/CLEAR ERROR SWITCH
	.ENDC
	LAC CDRLBH	/GET POINTER TO HEADER
	TAD (2		/AND RESET INPUT BUFFER
	DAC CDLPTR	/TO HEADER+2
	LAC CDWDSV	/RESET WORD PAIR COUNTER
	DAC CDWDCT
	LAW -1
	DAC CDIOSW
	CRSC		/SELECT A CARD
CDRRET	XX		/JMP CDIGNR OR CDRTRY(FROM IOPS4 COND.)
/IOPS 4
CDR4	LAC (CDRRTN	/SET RETURN IN .MED
	DAC* (.MED
	LAW -1
	DAC CDRMSW
	LAC (4
	JMP* (.MED+1
	.IFUND NOTGDI
CDRRTN=CDOK
	.ENDC
	.EJECT
/SUBROUTINE CDRMAP, SEE IF PREVIOUS INPUT IS COMPLETED AND, IF SO,
/SEE IF A CARD IMAGE IS WAITING TO BE REMAPPED.  IF INPUT IS NOT
/COMPLETE (CDIOSW .NE. 0), GO TO CDRBSY.
CDRMAP	0		/ENTRY TO REMAP FROM COLUMN TO ASCII.
	LAC CDIOSW	/IS IO STILL UNDERWAY?
	SPA		/SKIP IF NOT.
CDRJMP	JMP CDRBSY
	LAC CDRMSW	/IS THERE A CARD WAITING?
	SPA		/SKIP IF SO (CDRMSW=0).
	JMP* CDRMAP	/NO CARD, RETURN TO CALLER.
	SAD (1006		/EOM PREVIOUSLY FOUND?
	JMP CDPLBH	/YES, GO SET UP EMPTY LINE.
	LAC CDRJMP
	DAC CDRRET
	.IFUND NOTGDI
	LAC CDERSW
	SZA
	JMP CDR4
	.ENDC
/A CARD IS PRESENT. REMAP IT.
	LAC (CDBUFF	/GET COLUMN-DATA BUFFER.
	DAC CDIPTR	/SET UP INPUT POINTER.
	LAW -20
	DAC CDCOLC
CDRM5	LAW -5		/5-CHARACTER COUNTER.
	DAC CDR5CT	/..
CDRML2	LAC* CDIPTR	/ALT MODE(12,1,8 PUNCH)?
	SAD CDRALT
	JMP CDGALT	/YES
	LAC CDTABL	/GET TOP OF TABLE.
	DAC CDTPTR	/SET TOP OF CURRENT TABLE
	LAC CDTLN1	/SET INITIAL (FULL) TABLE LENGTH.
CDRML4	DAC CDTLEN	/CURRENT LENGTH/2.
	ADD CDTPTR	/CURRENT TABLE TOP + LENGTH/2
	DAC CDCPTR	/CURRENT ITEM IN TABLE
	LAC* CDCPTR	/GET CURRENT ITEM.
	AND (7777		/THROW AWAY JUNK.
	SZA!CLL
	ADD CD7700	/REST OF 2'S COMPLEMENT WORD.
	TAD* CDIPTR	/CURRENT COLUMN
	SNA!CLA
	JMP CDCFND	/MATCH FOUND.
	SAD CDTLEN	/COLUMN .L. TABLE ENTRY AND CDTLEN .E. 0,
	JMP CDR4
	SNL		/L=0 JMP UP,L=1 JMP DOWN TABLE.
	JMP CDDPTR	/COLUMN .L. ENTRY.
	LAC CDCPTR	/SET TABLE TOP TO LOWER HALF.
	DAC CDTPTR	/NEW TABLE TOP.
CDDPTR	LAC CDTLEN	/UPDATE NEW TABLE LENGTH.
	CLL!RAR		/LENGTH = LENGTH/2
	JMP CDRML4	/GO GET NEW TABLE ENTRY.
CDGALT	LAW 4000		/ALT MODE
	JMP CDCPUT
/COME HERE ON MATCH FOUND.
CDCFND	LAC* CDCPTR	/FOUND, GET CURRENT ENTRY.
	CMA!CLL
	TAD CDTABL+1	/GENERATE LEFTMOST BIT.
	CMA
	XOR CDTABL+1	/RESTORE SIXTH BIT.
	RAR
CDCPUT	DAC CDRWD3
CDCLAW	LAW -7		/IN HEADER WORD.
	DAC CDR7CT	/SET UP FOR SHIFTING THE
CDCPL1	LAC CDRWD3
	RAL		/LEFTMOST 7-BITS OF
	DAC CDRWD3	/CDRWD3 INTO THE TWO
	LAC CDRWD2	/WORD BUILDER SET AT
	RAL		/CDRWD2+1.
	DAC CDRWD2
	LAC CDRWD1
	RAL
	DAC CDRWD1	/BUILD THE 5/7 ASCII
	ISZ CDR7CT
	JMP CDCPL1	/DOUBLE WORD
	ISZ CDIPTR
	ISZ CDR5CT
	JMP CDRML2
	LAC CDWDCT
	TAD (2
	DAC CDWDCT
	SMA
	JMP CDVER2
	LAC CDRWD2
	CLL!RAL
	DAC CDRWD2
	LAC CDRWD1
	RAL
	DAC* CDLPTR
	ISZ CDLPTR
	LAC CDRWD2
	DAC* CDLPTR
	ISZ CDLPTR
	ISZ CDCOLC
	JMP CDRM5
	.EJECT
/THE BUFFER HAS BEEN REMAPPED.
/STORE A CARRIAGE RETURN IN
/THE TRAILER WORD AND SET UP
/THE HEADER WORD.
/
CDCLOS	LAC (64000
	DAC* CDLPTR
	LAC (22
	TAD CDCOLC
	CLL!RAL
	RTL
	RTL
	RTL
	RTL
	TAD CDRVAL
	TAD (2
CDPLBH	DAC* CDRLBH
	CLA!CMA
	DAC CDRMSW
	JMP* CDRMAP
CDVER2	LAW -2
	TAD CDLPTR
	DAC CDLPTR
	LAC (60
	DAC CDRVAL
	JMP CDCLOS
	.EJECT
/TABLE OF CODES.
CDTABL	CDTABL+1
	400000		/BLANK
	710001\7777+1	/9	/THIS TABLE REPRESENTS A SIX-BIT CODE (LEFT-MOST)
	700002\7777+1	/8	/AND THE 2'S COMPLEMENT OF VALID ASCII
	670004\7777+1	/7	/CARD PUNCHES (RIGHTMOST 12 BITS). 7777+1 IS
	.IFUND DEC026
	420006\7777+1	/"	/ADDED TO THE 12 BIT CARD CODE TO GENERATE ITS
	.ENDC
	.IFDEF DEC026
	340006\7777+1	/(\) BACKSLASH 026 MODE
	.ENDC
	660010\7777+1	/6	/(12-BIT) RECIPROCAL BY THE ASSEMBLER.
	.IFUND DEC026
	750012\7777+1	/=	/
	.ENDC
	.IFDEF DEC026
	470012\7777+1	/(') APOSTROPHE 026 MODE
	.ENDC
	650020\7777+1	/5	/IF THE PUNCHES IN A CARD COLUMN WERE
	.IFUND DEC026
	470022\7777+1	/,	/12-1 (A OR BINARY 4400) THE PROGRAM
	.ENDC
	.IFDEF DEC026
	360022\7777+1	/(^) UP-ARROW 026 MODE
	.ENDC
	640040\7777+1	/4	/WOULD JUMP HALFWAY INTO THIS TABLE AND
	000042\7777+1	/@	/PULL OUT A WORD. THE LEFTMOST 6-BITS.
	630100\7777+1	/3	/WOULD BE STRIPPED OFF AND REPLACED BY 77
	.IFUND DEC026
	430102\7777+1	/#	/TO COMPLETE THE NEGATION STARTED AT THE
	.ENDC
	.IFDEF DEC026
	750102\7777+1	/(=) EQUAL SIGN 026 MODE
	.ENDC
	620200\7777+1	/2	/ASSEMBLER LEVEL. THIS (NOW 18-BIT) NEGATIVE
	.IFUND DEC026
	720202\7777+1	/:	/NUMBER IS ADDED TO THE COLUMN BINARY A 0
	.ENDC
	.IFDEF DEC026
	370202\7777+1	/(_) LEFT ARROW 026 MODE
	.ENDC
	610400\7777+1	/1	/RESULT INDICATES A MATCH. A NON ZERO
	601000\7777+1	/0	/RESULT CAUSES A DECISION WHETHER TO JMP
	321001\7777+1	/Z	/HALFWAY INTO THE UPPER OR LOWER HALF,
	311002\7777+1	/Y	/EFFECTIVELY SHRINKING THE TABLE, UNTIL A
	301004\7777+1	/X	/MATCH IS FOUND.
	.IFUND DEC026
	771006\7777+1	/?	/
	.ENDC
	.IFDEF DEC026
	451006\7777+1	/(%) PER CENT SIGN 026 MODE
	.ENDC
	271010\7777+1	/W	/WHEN A MATCH OCCURS THE TABLE WORD IS
	.IFUND DEC026
	761012\7777+1	/>	/REFERENCED AGAIN TO GET THE ASCII
	.ENDC
	.IFDEF DEC026
	431012\7777+1	/(#) NUMBER SIGN 026 MODE
	.ENDC
	261020\7777+1	/V	/EQUIVALENT. IN THE EXAMPLE ABOVE
	.IFUND DEC026
	371022\7777+1	/RIGHT ARROW	/THE WORD POINTED TO BY A IS (013400).
	.ENDC
	.IFDEF DEC026
	421022\7777+1	/(") DOUBLE QUOTE 026 MODE
	.ENDC
	251040\7777+1	/U	/COMPLEMENT THIS NUMBER, CLEAR THE LINK,
	.IFUND DEC026
	451042\7777+1	/%	/AND ADD 400000 TO IT. (013400=764377)
	.ENDC
	.IFDEF DEC026
	501042\7777+1	/(()LEFT PAREN 026 MODE
	.ENDC
	241100\7777+1	/T	/(764377+400000)=364377 WITH LINK=1.
	541102\7777+1	/,	/
	231200\7777+1	/S	/COMPLEMENT THE RESULT (364377=413400)
	.IFUND DEC026
	351202\7777+1	/]	/XOR THE LEFTMOST BIT (41300=013400)
	.ENDC
	.IFDEF DEC026
	731202\7777+1	/(;) SEMI COLON 026 MODE
	.ENDC
	571400\7777+1	//	/ROTATE THE LINK INTO THE WORD AND
	552000\7777+1	/-	/STRIP OFF LOW ORDER 11-BITS.
	222001\7777+1	/R	/RESULT: A=(40400).
	212002\7777+1	/Q	/THIS RESULT IS SAVED AND SHIFTED LEFT
	202004\7777+1	/P	/7 TIMES. (404000=000101).
	.IFUND DEC026
	342006\7777+1	/\
	.ENDC
	.IFDEF DEC026
	462006\7777+1	/(&) AMPERSAND 026 MODE
	.ENDC
	172010\7777+1	/O
	.IFUND DEC026
	732012\7777+1	/;
	.ENDC
	.IFDEF DEC026
	762012\7777+1	/(>) GREATER THAN  026 MODE
	.ENDC
	162020\7777+1	/N
	.IFUND DEC026
	512022\7777+1	/)
	.ENDC
	.IFDEF DEC026
	332022\7777+1	/([) LEFT BRACKET  026 MODE
	.ENDC
	152040\7777+1	/M
	522042\7777+1	/*
	142100\7777+1	/L
	442102\7777+1	/$
	132200\7777+1	/K
	.IFUND DEC026
	412202\7777+1	/!
	.ENDC
	.IFDEF DEC026
	722202\7777+1	/(:) COLON  026 MODE
	.ENDC
	122400\7777+1	/J
	.IFUND DEC026
	464000\7777+1	/&
	.ENDC
	.IFDEF DEC026
	534000\7777+1	/(+) PLUS SIGN  026 MODE
	.ENDC
	114001\7777+1	/I
	104002\7777+1	/H
	074004\7777+1	/G
	.IFUND DEC026
	364006\7777+1	/^
	.ENDC
	.IFDEF DEC026
	414006\7777+1	/(!) EXCLAMATION  026 MODE
	.ENDC
	064010\7777+1	/F
	.IFUND DEC026
	534012\7777+1	/+
	.ENDC
	.IFDEF DEC026
	744012\7777+1	/(<)  .LESS THAN.  026 MODE
	.ENDC
	054020\7777+1	/E
	.IFUND DEC026
	504022\7777+1	/(
	.ENDC
	.IFDEF DEC026
	354022\7777+1	/(]) RIGHT BRACKET  026 MODE
	.ENDC
	044040\7777+1	/D
	.IFUND DEC026
	744042\7777+1	/<
	.ENDC
	.IFDEF DEC026
	514042\7777+1	/()) RIGHT PAREN  026 MODE
	.ENDC
	034100\7777+1	/C
	564102\7777+1	/.
	024200\7777+1	/B
	.IFUND DEC026
	334202\7777+1	/[
	.ENDC
	.IFDEF DEC026
	774202\7777+1	/(?) QUESTION MARK  026 MODE
	.ENDC
	014400\7777+1	/A
CDTLN1	.-1-CDTABL/2
CDRALT	4402
	.EJECT
/CARD READER INTERRUPT SECTION.
CDRINT	SKP		/CONTROL COMES HERE ON PIC INTERRUPT.
	JMP CDRAPI	/CONTROL COMES HERE ON API INTERRUPT.
	DAC CDRAC		/PIC INTERRUPT, SAVE AC.
	LAC (700042	/GET ION CODE.
	DAC CDRSW		/SET TO TURN PIC BACK ON AT EXIT.
	LAC* CDTABL+1	/GET LOCATION ZERO.
	JMP CDSVPC	/SAVE AS INTERRUPT PC.
CDRAPI	DAC CDRAC		/API ENTRY, SAVE AC.
	LAC CDRNOP	/GET NOP CODE.
	DAC CDRSW		/SET TO LEAVE PIC ALONE AT EXIT.
	LAC CDRINT	/GET ENTRY.
CDSVPC	DAC CDROUT	/SAVE AS RETURN.
	.IFDEF	NOTGDI
	CRSI		/SKIP ON COLUMN READY
	JMP CRDONE	/MAYBE DONE
	LAC CDCOLC	/COLUMN FLAG, GET CURRENT COUNT.
	RAL		/PUT OVERFLOW INDICATION IN LINK (0 IF SO).
	CRRB		/READ COLUMN, TURN OFF FLAG.
	SZL		/SKIP IF OVERFLOW HAS OCCURRED.
	.ENDC
/
/--------------------CRBB
/
	.IFUND	NOTGDI
	CROC		
	SPA		/IF ERROR FLAG ON
	SAD (600002	/ERR,HE,AND CARD DONE FLAG
	SKP		/YES..NORMAL CONDITION
	JMP CDRERR
	RCR
	SML
	JMP CRDONE
	RAR
	AND (7777
	.ENDC
/
/-----
/
	DAC* CDIPTR	/OTHERWISE, INSERT THIS COLUMN IN BUFFER.
	ISZ CDIPTR	/BUMP BUFFER POINTER FOR NEXT TIME.
	.IFDEF NOTGDI
	ISZ CDCOLC	/COUNT 80 COLUMNS SERVICE.
	.ENDC
CDRNOP	NOP
CDIRET	LAC CDRSKP	/GET SKIP CODE.
	DAC CDRINT	/RESTORE ENTRY IN CASE OF API INTERRUPT.
	LAC CDRAC		/RESTORE AC.
CDRSW	XX		/ION (IF ENTERED VIA PIC) OR NOP (IF ENTERED VIA API).
	DBR
	XCT .+1
	JMP* CDROUT
	.IFDEF	NOTGDI
CRDONE	CRCD		/CLEAR CARD DONE FLAG
	LAC CDBUFF	/EOF CARD(COLUMN 1=ALL 1'S)?
	.ENDC
/
/--------------------CR03B
/
	.IFUND	NOTGDI
CDRERR	ISZ CDERSW	/TURN ERROR SWITCH ON
CRDONE	LAC CDBUFF
	.ENDC
/-----
/
	XOR (7777
	SNA!CLA		/NO
	LAC (1006	/EOM CONDITION
	DAC CDRMSW	/REMAP REQUIRED SWITCH (0=OFF)
	DZM CDIOSW	/CLEAR I/O UNDERWAY SW
	JMP CDIRET	/EXIT
CDROUT
CDBUFF	.BLOCK 120
CDARGP
CDCALP
CDDTPT
CDIOSW
CDTPTR
CDR5CT
CDRAC
CDRMSW	-1
CDRVAL
CDWDSV	
	.IFUND	NOTGDI
CDRWD1		/LOW ORDER 5/7 ASCII BUILDER
CDRWD2		/HIGH "     "    "      "
CDRWD3		/7-LEFT MOST BITS=1 CARD COLUMN
CDRLBH		/LINE BUFFER POINTER (HEADER)
CDERSW	/ERROR FLAG ,TESTED AT CDRMAP(WAIT TIME)
	.ENDC
	.END
