Google
 

Trailing-Edge - PDP-10 Archives - BB-T573C-DD_1986 - 10,7/tcxkon.mac
There are 14 other files named tcxkon.mac in the archive. Click here to see a list.
TITLE TCXKON - TC10C DEVICE DEPENDENT CODE FOR TAPSER V2016
SUBTTL T.HESS/TAH/TW	10 SEP 85
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1975,1986>
;COPYRIGHT (C) 1975,1976,1977,1978,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
;
;
XP VTCXKN,2016		;DEFINE VERSION NUMBER FOR STORAGE MAP
	SALL

TCXKON::	ENTRY	TCXKON

;DISPATCH TABLE FOR TAPSER CALLS

TCXDSP::IFIW	TCXINI		;00 - INITIALIZE
	IFIW	TCXRES		;01 - RESET ACTIVE I/O
	IFIW	TCXSIO		;02 - START I/O
	IFIW	TCXINT		;03 - INTERRUPT SERVICE
	EXP	0		;04 - SET DEVICE COMMAND
	IFIW	TCXIDL		;05 - KONTROLLER IS IDLE
	IFIW	CPOPJ1##	;06 - TEST IF CTL ON-LINE
	IFIW	TCXSCH		;07 - FORCE A SCHEDULE CYCLE
	IFIW	CPOPJ##		;10 - RE-INITIALIZATION
	IFIW	CPOPJ##		;11 - LOAD MICROCODE
	IFIW	CPOPJ##		;12 - ENABLE/DISABLE MICROCODE LOADING
IFN FTAUTC,<IFIW CPOPJ##>	;13 - AUTOCONFIGURE

;BYTE POINTERS

CTYUNI:	POINT	CI.UNS,T1,CI.UNP	;UNIT # IN STATUS REG
CTYFCN:	POINT	CI.CMS,T1,CI.CMP	;FCN CODE IN STATUS REG

;OFFSETS INTO TKBCCL

TKBUNI==TKBCCL##+2	;CURRENT UNIT SELECTED (-1 IF NONE)
;DEFINITIONS FOR CONI/CONO STATUS REGISTER

;CONI BITS LH

CI.EOF==1B0		;TAPE MARK SEEN
CI.EOT==1B1		;END OF TAPE
CI.BOT==1B2		;LOAD POINT
CI.FPT==1B3		;FILE PROTECT (WRITE LOCK)
CI.HNG==1B4		;XPORT HUNG
CI.REJ==1B5		;COMMAND REJECT
CI.REW==1B6		;TAPE REWINDING
CI.RCC==1B7		;READ STATUS
CI.WCC==1B8		;WRITE STATUS
CI.DPE==1B9		;DATA PARITY ERROR
CI.CER==1B10		;PE CORRECTED ERROR
CI.RCE==1B11		;READ/COMPARE ERROR
CI.RLD==1B12		;RECORD LENGTH DIFFERS
CI.OVR==1B13		;DATA LATE (OVERRUN)

CI.CES==2		;CHANNEL ERROR BYTE SIZE
CI.CEP==^D15		;CHANNEL ERROR BYTE POSITION
  CE.DPE==1		;DATA PARITY ERROR
  CE.CWE==2		;CONTROL WORD PARITY ERROR
  CE.NXM==3		;NON-EXISTENT MEMORY

CI.RDY==1B17		;UNIT READY
;CONI BITS RH
CI.UNS==3		;UNIT # BYTE SIZE
CI.UNP==^D20		;UNIT # BYTE POSITION

CI.CMS==5		;COMMAND BYTE SIZE
CI.CMP==^D25		;COMMAND BYTE POSITION
  CM.FNO==00		;NO-OP / CLEAR FORMATTER
  CM.FUR==10		;UNIT READY
  CM.FRW==01		;REWIND
  CM.FUN==11		;REWIND / UNLOAD
  CM.FRD==02		;READ FORWARD
  CM.FR1==12		;READ FORWARD TO EOF
  CM.FRB==22		;READ REVERSE
  CM.FRC==03		;READ / COMPARE FORWARD
  CM.FR2==13		;READ / COMPARE FORWARD TO EOF
  CM.FBC==23		;READ / COMPARE REVERSE
  CM.FB1==33		;READ / COMPARE REVERSE TO EOF
  CM.FWR==04		;WRITE
  CM.FWL==14		;WRITE AFTER LONG ERG
  CM.FTM==05		;WRITE TAPE MARK
  CM.FLG==15		;WRITE 3" BLANK TAPE
  CM.FFB==06		;SPACE FORWARD RECORD
  CM.FFF==16		;SPACE FORWARD FILE
  CM.FBB==07		;SPACE BACKWARD RECORD
  CM.FBF==17		;SPACE BACKWARD FILE

CI.CDS==1B26		;CORE DUMP STATUS
CI.CWW==1B27		;CONTROL WORD WRITTEN
CI.WEP==1B28		;WRITE EVEN PARITY
CI.NRZ==1B29		;PE/NRZI STATUS
CI.CKS==1B31		;CHECK STATUS
CI.JBD==1B32		;JOB DONE

CI.PIA==7		;MASK FOR PIA

NOPMSK==701000		;PRESERVE UNIT AND MODE
;CONO BITS

CO.UNS==CI.UNS		;UNIT # BYTE SIZE
CO.UNP==CI.UNP		;UNIT # BYTE POSITION

CO.CMS==CI.CMS		;COMMAND BYTE SIZE
CO.CMP==CI.CMP		;COMMAND BYTE POSITION

CO.CDM==1B26		;CORE DUMP MODE
CO.WCW==1B27		;WRITE CONTROL WORD
CO.WEP==1B28		;WRITE EVEN PARITY
CO.GO==1B30		;EXECUTE COMMAND
CO.LCR==1B31		;LOAD COMMAND REGISTER
CO.JBD==1B32		;JOB DONE

CO.PIA==7		;MASK FOR PIA

;DATAO / DATAI BITS

DO.STP==1B21		;ABORT CURRENT OPERATION

DI.IDB==1B17		;PE ID BURST DETECTED
DI.CHS==3		;CHAR CNT BYTE SIZE
DI.CHP==^D20		;CHAR CNT BYTE POSITION
;COUNTER FOR WAIT AT TCXSIO
MTWTTM==4000
SUBTTL TAPE INTERUPT SERVICE
;CALLED FROM TAPSER WITH W := KDB

TCXINT:	XCT	TTCCIS##(W)	;GET STATUS REGISTER
	MOVE	T2,T1		;GET COPY
	ANDI	T2,76017	;GET BITS OF INTEREST
	CAIN	T2,CI.JBD+TAPCHN## ;CHECK FOR IDLE INTERUPT
	JRST	[PUSHJ P,CKSTRT	;CHECK IF STARTED
		   POPJ	P,	;NOT STARTED - RETURN
		 JRST .+1]
	LDB	T2,CTYUNI	;GET UNIT SELECTED
	PUSHJ	P,SETUDB##	;SET UP U
	  JRST	SETM1		;NON-EX UNIT
	XCT	TTCCIS##(W)	;GET STATUS AGAIN
	MOVEM	T1,TTCFCS##(U)	;SAVE IN UDB
	LDB	T2,CTYFCN	;GET FCN
	CAIE	T2,CM.FUR	;UNIT READY?
	CAIN	T2,CM.FNO	; OR NO-OP
	JRST	TCXSEL		;YES - START I/O IF OK
	PUSHJ	P,CHKIRB##	;GET IORB
	  JRST	TAPDIS##	;NONE - DISMISS INT.
	MOVE	T3,TTCFCS##(U)	;GET STATUS IN T3
	MOVSI	T2,TUSBOT##	;CLEAR BOT INDICATION
	ANDCAM	T2,TUBSTS##(U)	;  WE WILL SET IT AGAIN IF NECESSARY
	LDB	T2,PRBFCN##	;GET DESIRED FCN
	CAILE	T2,TCIMAX	;CHECK VALIDITY
	JRST	TAPIFI##	;ILLEGAL TRANSFER VECTOR
	JRST	@TCIDSP(T2)	;DO IT

TCIDSP:	TAPIFI##		;0 - ILLEGAL
	TCIRD			;1 - READ
	TCIWT			;2 - WRITE
	TAPIFI##		;3 - READ BACKWARDS (ILLEGAL)
	TCISR			;4 - SKIP RECORD
	TCIBR			;5 - BACKSPACE RECORD
	TAPIFI##		;6 - SKIP FILE
	TAPIFI##		;7 - BACKSPACE FILE
	TCIEG			;10 - ERASE GAP
	TAPIFI##		;11 - DSE (ILLEGAL)
	TCIRW			;12 - REWIND
	TCIUN			;13 - REWIND / UNLOAD
	TCITM			;14 - WRITE TAPE MARK
	TAPIFI##		;15 - ILLEGAL
	TCIRD			;16 - CORRECTION READ
	TCIRD			;17 - READ LOW THRESHOLD

TCIMAX==.-TCIDSP-1
;HERE TO CHECK FOR IDLE STATUS INTERUPT - SEE IF ALREADY STARTED
;C(T1) IS STATUS REGISTER - PRESERVED IF CHL STARTED

CKSTRT:	MOVSI	T2,TKSSTD##
	TDNE	T2,TKBSTS##(W)	;STARTED?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	LDB	T2,CTYUNI	;GET UNIT #
	PUSHJ	P,SETUDB##	;SET UP U := UDB
	  JRST	SETM1
	XCT	TTCCIS##(W)	;GET STATUS REG
	MOVSI	T2,TKSOFL##
	TLNN	T1,(CI.RDY!CI.REW) ;CHECK GOODNESS
	IORM	T2,TUBSTS##(U)	;UNIT WENT OFF-LINE!
	PUSHJ	P,CLRCTL	;CLR CTL
SETM1:	MOVNI	T1,1		;CAUSE SCHEDULING
	POPJ	P,		;RETURN
;ROUTINE TO MAKE CONTROLLER IDLE

CLRCTL:
TCXIDL:	PUSH	P,T1		;SAVE IORB
	HLLZS	TKBCSO##(W)	;NO MORE INTS
	XCT	TTCCIS##(W)	;GET CTL STATUS REG
	ANDI	T1,NOPMSK	;PRESERVE UNIT # ETC.
	IORI	T1,CO.LCR!CO.GO	;...
	XCT	TTCCOS##(W)	;DO NO-OP TO DRIVE W/ PIA=0
	SETOM	TKBUNI(W)	;NO UNIT SELECTED
	PJRST	TPOPJ##		;RETURN

;HERE TO RESET ACTIVE I/O

TCXRES:	MOVEI	T1,DO.STP	;STOP CURRENT COMMAND
	XCT	TTCDOS##(W)	;AND CLEAR CHL ICP
	MOVSI	T2,TKSSEL##	;SELECT BIT
	HRRZ	T1,TUBQUE##(U)	;GET HEAD OF Q
	JUMPE	T1,CLRCTL	;NONE - EXIT
	TDNE	T2,TKBSTS##(W)	;SELECTED?
	PUSHJ	P,ZAPEXL	;YES - FIX IOLIST
	PJRST	CLRCTL		;CLEAR WORLD & EXIT

;HERE AT SYSTEM STARTUP

TCXINI:	PUSHJ	P,CLRCTL	;CLEAR WORLD
	POPJ	P,		;RETURN


;ROUTINE TO CAUSE AN INTERUPT TO FORCE A SCHEDULE CYCLE

TCXSCH:	HRRZ	T1,TUBADR##(U)	;GET UNIT ADDRS
	LSH	T1,^D35-CO.UNP
	IORI	T1,<CM.FNO>B<CO.CMP>!CO.GO!CO.LCR+TAPCHN## ;DO NO-OP TO UNIT
	MOVEI	T2,CI.JBD	;ENABLE FOR JOB DONE
	CONO	PI,PIOFF##	;AVOID RACE
	HRRM	T2,TKBCSO##(W)	;...
	XCT	TTCCOS##(W)	;...
	PJRST	ONPOPJ##	;EXIT
SUBTTL START I/O

;ROUTINE TO START I/O
;USER JOB MUST BE NAILED DOWN - CAUSE SELECTION INTERUPT
;OR JUST START I/O IF UNIT ALREADY SELECTED

TCXSIO:	LDB	T3,PRBFCN##	;GET FCN
	MOVEI	T2,<CM.FUR>B<CO.CMP>	;ASSUME UNIT READY WANTED
	MOVSI	T1,TKSOFL##	;BETTER SEND NO-OP IF UNIT
	TDNN	T1,TUBSTS##(U)	;  WAS DISCOVERED OFF-LINE
	CAIN	T3,RB.FYB	;JUST WANT STATUS?
	JRST	[MOVEI	T2,<CM.FNO>B<CO.CMP> ;YES - USE NO-OP
		 SETOM TKBUNI(W)	;CLEAR SELECTED UNIT
		 JRST .+1]
	HLRZ	T1,TUBAKA##(U)	;GET UNIT ADDRS DESIRED
	CAMN	T1,TKBUNI(W)	;SELECT OR START?
	JRST	TMSTRT		;START IT
	LSH	T1,^D35-CO.UNP	;PUT IN PROPER PLACE
	IORI	T1,CO.GO!CO.LCR+TAPCHN##(T2) ;INT ON UNIT READY OR NOOP
	MOVE	T2,TTCCIS##(W)	;GET CONI FOR TU'S KONTROLLER
	TLO	T2,(CONSO 0)	;CHANGE TO CONSO
	HRRI	T2,CI.JBD	;JOB DONE BIT
	MOVEI	T3,MTWTTM	;UPPER LIMIT WAIT COUNTER
	XCT	T2		;DONE YET
	SOJG	T3,.-1		;WAIT SOME MORE
	MOVEI	T2,CI.JBD	;THIS SHOULD COME UP
	CONO	PI,PIOFF##	;AVOID RACE
	HRRM	T2,TKBCSO##(W)	;SET IN CONSO
	XCT	TTCCOS##(W)	;SELECT UNIT
	PJRST	ONPOPJ##	;WAIT FOR INT

;HERE TO START AN ALREADY SELECTED UNIT

TMSTRT:	XCT	TTCCIS##(W)	;GET CTL STATUS
	MOVEM	T1,TTCFCS##(U)	;SAVE IN UDB
				;;; FALL INTO TCXSEL
;HERE WHEN DESIRED DRIVE HAS BEEN SELECTED
;CHECK FOR ERRORS AND UNIT IDLE

TCXSEL:	PUSHJ	P,CHKIRB##	;GET IORB
	  JRST	TAPDIS##	;NONE
	MOVSI	T2,TKSOFL##	;CHECK IF OFF-LINE
	TDNE	T2,TUBSTS##(U)	;...
	JRST	TCXOFL		;YES - TELL UPPER LEVEL
	MOVE	T3,TTCFCS##(U)	;GET STATUS REG
	MOVSI	T4,TUSWTL##	;WRITE LOCKED BIT
	MOVE	T2,[ANDCAM T4,TUBSTS##(U)]
	TLNE	T3,(CI.FPT)	;WRITE LOCKED?
	MOVE	T2,[IORM T4,TUBSTS##(U)] ;YES - CORRECT INSTR
	XCT	T2		;SET/CLEAR BIT
	LDB	T2,PRBFCN##	;SEE WHAT FCN
	CAIN	T2,RB.FYB	;STATUS CHECK?
	JRST	TCXSTS		;YES - GO HANDLE
	TLNE	T3,(CI.HNG!CI.REJ!<CE.NXM>B<CI.CEP>)
	JRST	TCXOFL		;UNIT OFFLINE
	PUSH	P,T1		;SAVE IORB PNTR
	HRRZ	T1,TKBICP##(W)	;SET UP ICPC
	XCT	TTCDOS##(W)	;...
	POP	P,T1		;RESTORE IORB PNTR
	PUSHJ	P,SETCMD	;SET UNIT,PAR,DENS,COMPAT,FCN
	  PJRST	TCIDON		;WRITE LOCKED
	MOVEI	T1,CO.GO!CO.LCR+TAPCHN##(T2) ;ADD PIA & MOVE TO T1
	MOVEI	T2,CI.JBD
	CONO	PI,PIOFF##	;SAVE US FROM OTHERS
	HRRM	T2,TKBCSO##(W)	;SET UP INT MASK
	XCT	TTCCOS##(W)	;START DEVICE
	CONO	PI,PION##	;OK NOW
NXTINT:	MOVEI	T1,0		;MORE INTS COMING
	POPJ	P,		;EXIT THIS INT

;HERE TO GET UNIT STATUS UPDATE ON REQUEST

TCXSTS:	TLNE	T3,(CI.HNG)	;IF HUNG?
	JRST	TCXOFL		;MUST BE OFF-LINE
	TLNN	T3,(CI.RDY)	;UNIT READY?
	JRST	TCIDON		;NO - DISMISS
	TLNN	T3,(CI.BOT)	;AT LOAD POINT?
	TLNN	T3,(CI.REW)	;OR NOT REW'D
	PUSHJ	P,REWDON##	;YES - SET BOT / CLR REW
	PJRST	TCIDON		;EXIT INTERUPT

;HERE IF NO STATUS WORTH REMEMBERING

TCXOFL:	MOVSI	T2,RB.SOL	;SET OFF-LINE STATUS
	IORM	T2,TRBSTS(T1)
	MOVSI	T2,TKSOFL##	;CLEAR BIT IN UDB
	ANDCAM	T2,TUBSTS##(U)
	PUSHJ	P,CLRCTL	;RESET CTL
	PJRST	TCIDON		;AND RETURN
SUBTTL COMMAND SETUP
;ROUTINE TO SET UP CMD
;T1 := IORB FOR THIS REQUEST
;T3 CONTAINS CONI MTS,  - DESTROYED
;T2 := COMMAND FOR CTL ON EXIT

SETCMD:	LDB	T4,PRBFCN##	;GET DESIRED FCN
	SKIPN	T2,IOFTAB(T4)	;CHECK LEGAL
	JRST	SETILG		;NOPE - ERROR
	TLNE	T2,(WRTOP)	;WRITING?
	JRST	SETCMW		;YES - CHECK WRITE-LOCKED
	TLNE	T2,(REWOP)	;REWINDING?
	JRST	CHKBOT		;YES - CHECK BOT
SETCM1:	HLRZ	T2,TUBAKA##(U)	;UNIT ADDRS
	LSH	T2,^D35-CO.UNP	;WHERE IT WILL DO THE MOST GOOD
	IOR	T2,IOFTAB(T4)	;GET FCN CODE
	TLZ	T2,(REWOP!WRTOP) ;CLEAR UNWANTED BITS
	HRRZ	T4,TRBXCW(T1)	;GET DATA ADDRS OR SPACING COUNT
	TLZE	T2,(DATOP)	;DATA?
	JRST	[PUSHJ P,SETCBX	;DO CTL SPECIFIC SETUP
		 JRST SETCM2]	;PROCEED
	TLZN	T2,(SPCOP)	;SPACING OP?
	JRST	[MOVEI T4,0	;NO - ILLEGAL DATA REQUEST
		 JRST SETCM2]	;SET IN CHL AREA
	MOVNI	T4,-1(T4)	;GET COUNT -1 NEGATED
	SKIPN	T4
	SETO	T4,
	HRRZ	T3,TKBCDB##(W)	;CHECK DF10C CHL
	SKIPGE	CHB22B##(T3)
	LSH	T4,4		;ONLY 14 BITS OF INFO

	HRLZM	T4,TKBCCL##(W)	;SAVE IN CHL PGM AREA
	HRRZI	T4,TKBCCL##(W)	;SET ADDRS
	SETZM	TKBCCL##+1(W)	;CHL HALT FOR DF10
SETCM2:	MOVEM	T4,@TKBICP##(W)	;PUT IN CORRECT PLACE
	LDB	T4,PRBMOD##	;GET DESIRED MODE
	CAIN	T4,RB.MCD	;CORE-DUMP?
	IORI	T2,CO.CDM	;YES - SET BIT
	MOVEI	T4,RB.D16	;1600 BPI
	DPB	T4,PRBDEN##	;CORRECT DENSITY
	PJRST	CPOPJ1##	;GIVE GOOD RETURN

;SET IMPROPER MODE AND RETURN

SETILG:	MOVSI	T2,RB.SIL!RB.SER ;ILLEGAL OP
	IORM	T2,TRBSTS(T1)	;SET IN IORB
	POPJ	P,		;ERROR RETURN
;HERE IF WRITING - CHECK WRLK

SETCMW:	TLNN	T3,(CI.FPT)	;WRITE LOCKED?
	JRST	SETCM1		;NO - PROCEED
	MOVSI	T2,RB.SLK!RB.SER ;AND IN IORB
	IORM	T2,TRBSTS(T1)	;...
	POPJ	P,		;ERROR RETURN

;ROUTINE TO SETUP CMD LIST TERMINATION WORD FOR DF10
;T4 := ADDRS OF CHL PGM

SETCBX:	HLRZ	T3,TRBEXL(T1)	;END OF XFER LIST
	HRLI	T3,TKBCCL##(W)	;HANDY ZERO
	HLRZM	T3,0(T3)	;CHL JUMP TO ZERO
	SETZM	TKBCCL##(W)	;GRNTEE ZERO
	POPJ	P,		;RETURN

;HERE TO CHECK ALREADY AT BOT - SUPPRESS REWIND

CHKBOT:	TLNE	T3,(CI.BOT)	;LOAD POINT?
	PJRST	REWDON##	;YES - NO NEED TO REWIND
	JRST	SETCM1		;NO - START REWIND
;TABLE FOR I/O FUNCTIONS - ALREADY IN POSITION

DEFINE IOT(CMD,FLGS) <
	FLGS+<CMD>B<CO.CMP>
>

DATOP==1B0	;DATA XFER OPERATION
SPCOP==1B1	;SPACING OPERATION
WRTOP==1B2	;WRTITE OPERATION
REWOP==1B3	;REWIND OPERATION

IOFTAB:	0			;0 - ILLEGAL
	IOT(CM.FRD,DATOP)	;1 - READ
	IOT(CM.FWR,DATOP!WRTOP)	;2 - WRITE
	0			;3 - ILLEGAL
	IOT(CM.FFB,SPCOP)	;4 - FORWARD SPACE BLOCK
	IOT(CM.FBB,SPCOP)	;5 - BACKWARD SPACE BLOCK
	IOT(CM.FFF,0)		;6 - FORWARD SPACE FILE
	IOT(CM.FBF,0)		;7 - BACKSPACE FILE
	IOT(CM.FLG,WRTOP)	;10 - WRITE LONG GAP
	0			;11 - ILLEGAL
	IOT(CM.FRW,REWOP)	;12 - REWIND
	IOT(CM.FUN,0)		;13 - REWIND / UNLOAD
	IOT(CM.FTM,WRTOP)	;14 - WRITE TAPE MARK
	0			;15 - ILLEGAL
	IOT(CM.FRD,DATOP)	;16 - CORRECTION READ
	IOT(CM.FRD,DATOP)	;17 - READ LOW THRESHOLD
SUBTTL READ
;HERE ON DONE INTERUPT FOR READ

TCIRD:	PUSHJ	P,TCCKMV	;SEE IF TAPE MOVED
	  JSP	T4,TCERD0	;NO - PROBS
	PUSHJ	P,CHRCT		;GET CHARACTER COUNT
	  JRST	[MOVSI T4,RB.STL
		 IORM T4,TRBSTS(T1)
		 JRST .+1]
	MOVEM	T2,TRBRCT(T1)	;SAVE COUNT IN IORB
	MOVE	T3,TTCFCS##(U)	;RESTORE STATUS
	TLNE	T3,(<CE.NXM>B<CI.CEP>) ;CHL ERRORS?
	JRST	TCECHN		;YES - HANDLE
	PUSHJ	P,TCSTM		;ENCOUNTER EOF?
	  JRST	TCIRD1		;NO - GO ON
	AOS	TUBFIL##(U)	;PLUS 1 MORE FILE
TCIRD1:	TRNE	T3,CI.CKS	;CHECK BADNESS
	JSP	T4,TCERD1	;ERROR - HANDLE
	MOVE	T2,TRBRCT(T1)	;GET CHAR COUNT FOR THIS RECORD
	ADDM	T2,TUBCRD##(U)	;AND UPDATE STATISTICS

;HERE TO FINISH INTERUPT AND EXIT TO TAPSER

TCIDON:	PUSHJ	P,ZAPEXL	;CLEAN UP
	HLRZ	T3,TUBAKA##(U)	;GET LAST UNIT REF'D
	MOVEM	T3,TKBUNI(W)	;AND SAVE IT FOR LATER CHECK
	HLRZ	T3,TRBSTS(T1)	;LOOK AT FLAGS
	JUMPE	T3,CPOPJ##	;RETURN IF NONE
	MOVSI	T2,RB.EXC	;ELSE SET EXCEPTION
	IORM	T2,TRBLNK(T1)	;IN IORB
	POPJ	P,		;AND RETURN

;ROUTINE TO FIXUP DF10 XFER LIST

ZAPEXL:	HLRZ	T2,TRBEXL(T1)	;PNTR TO END OF XFER LIST
	JUMPE	T2,CPOPJ##	;RETURN IF NONE
	SETZM	0(T2)		;CLEAR IT
	POPJ	P,		;RETURN
SUBTTL WRITE
;HERE ON DONE INTERUPT FOR WRITE

TCIWT:	PUSHJ	P,TCCKMV	;DID IT MOVE
	  JSP	T4,TCEWT0	;NO - TRY TO FIX
	TLNE	T3,(<CE.NXM>B<CI.CEP>) ;CHL ERROR?
	JRST	TCECHN		;YES - LOOK AT THAT
	MOVSI	T2,RB.SET	;NOW CHECK EOT
	TLNE	T3,(CI.EOT)	;???
	IORM	T2,TRBSTS(T1)	;SET INFO IN IORB
	TRNE	T3,CI.CKS	;EVERYTHING OK?
	JSP	T4,TCEWT1	;NO - TRY TO FIX
	PUSHJ	P,CHRCT		;GET CHARACTER COUNT
	  JFCL			;DON'T CARE
	ADDM	T2,TUBCWR##(U)	;ADD TO STATS
	PJRST	TCIDON		;AND EXIT

;HERE ON DONE INTERUPT FOR WRITE TAPE MARK

TCITM:	MOVSI	T2,RB.SET	;JUST IN CASE
	TLNE	T3,(CI.EOT)	;WE SAW A TI
	IORM	T2,TRBSTS(T1)	;SET FLG IF SEEN
	TRNE	T3,CI.CKS	;ANYTHING WRONG?
	JSP	T4,TCEWT1	;YES - SORRY
	SETZM	TUBREC##(U)	;ZEROTH RECORD
	AOS	TUBFIL##(U)	;AND 1 MORE FILE
	PJRST	TCIDON		;EXIT

;ROUTINE SET SAY WE'VE SEEN A TAPE MARK
;ALSO RESETS RECORD COUNTER

TCSTM:	TLNN	T3,(CI.EOF)	;SEEN EOF?
	POPJ	P,		;NO - RETURN
	MOVSI	T2,RB.STM	;IORB FLAG ALSO
	IORM	T2,TRBSTS(T1)	;...
	SETZM	TUBREC##(U)	;CLEAR RECORD COUNT
	PJRST	CPOPJ1##	;SKIP RETURN FOR FURTHER PROCESSING
SUBTTL REWIND/UNLOAD/BACKSPACE RECORD
;HERE ON INTERUPT AFTER STARTING REWIND

TCIRW:	TLNE	T3,(CI.HNG!CI.REJ) ;CHECK BADNESS
	JSP	T4,TCERW	;HANDLE PROBLEM
TCIUN:	MOVSI	T2,TUSREW##	;SAY WE ARE REWINDING
	IORM	T2,TUBSTS##(U)	;...
	TLNE	T3,(CI.BOT)	;ALREADY DONE?
	PUSHJ	P,REWDON##	;YES - CLEAN UP THEN
	SETZM	TUBREC##(U)	;IN CASE WE DON'T FINISH
	SETZM	TUBFIL##(U)	;CLEAR THESE NOW
	PJRST	TCIDON		;AND EXIT

;HERE ON DONE INTERUPT FROM BACKSPACE RECORD

TCIBR:	TLNE	T3,(CI.HNG!<CE.NXM>B<CI.CEP>) ;DEVICE PROBS?
	JSP	T4,TCERD1	;WHOOPS PROBLEM
	PUSHJ	P,TCSTM		;LOOK FOR TM
	  JRST	TCIBR1		;NONE SEEN
	SOS	TUBFIL##(U)	;ONE  LESS FILE
TCIBR1:	SOS	TUBREC##(U)	;ALSO ONE LESS RECORD
	TLNN	T3,(CI.BOT)	;SEE IF WE CRASHED INTO BOT
	PJRST	TCIDON		;NO - DONE
	MOVSI	T2,RB.SBT!RB.SNM ;YES - LITE BITS
	SKIPN	TUBREC##(U)	;TRY TO GUESS IF TAPE MOVED
	SKIPE	TUBFIL##(U)	;  BY SEEING IF AT LOGICAL BOT
	TLZ	T2,RB.SNM	;FIRST TIME HERE
	IORM	T2,TRBSTS(T1)	;SET RESULT IN IORB
	MOVSI	T2,TUSBOT##	;AND UDB
	IORM	T2,TUBSTS##(U)	;...
	SETZM	TUBREC##(U)	;GET THINGS RIGHT
	SETZM	TUBFIL##(U)
	PJRST	TCIDON		;EXIT
SUBTTL SKIP RECORD/ERASE GAP
;HERE ON DONE INTERUPT FROM SKIP FORWARD RECORD

TCISR:	PUSHJ	P,TCCKMV	;SEE IF WE MOVED?
	  JSP	T4,TCERD0	;NOPE
	TRNE	T3,CI.CKS	;CHECK ERRORS
	JSP	T4,TCERD1	;HANDLE IT
	PUSHJ	P,TCSTM		;CHECK FOR TAPE MARK
	  JRST	TCIDON		;NO TAPE MARK
	AOS	TUBFIL##(U)	;INCR FILE COUNTER
	JRST	TCIDON		;AND EXIT

;HERE ON DONE INTERUPT FROM ERASE GAP

TCIEG:	MOVSI	T2,RB.SET	;IN CASE TAPE INDICATE
	TLNE	T3,(CI.EOT)	;SEEN ONE?
	IORM	T2,TRBSTS(T1)	;YES - SET BIT
	TLNE	T3,(CI.HNG!CI.REJ!<CE.NXM>B<CI.CEP>) ;ERROR ALLOWED
	JRST	TCEWT1		;YES - TREAT IT
	PJRST	TCIDON		;EXIT INT
SUBTTL ERROR PROCEDURES

;HERE FOR CHANNEL ERROR

TCECHN:	PUSHJ	P,SAVE1##	;SAVE P1
	MOVEI	T2,CHNNXM##	;ASSUME NXM
	TLC	T3,(<CE.NXM>B<CI.CEP>) ;COMPLEMENT BITS
	TLCE	T3,(<CE.NXM>B<CI.CEP>) ;NXM IF BOTH ON!
	MOVEI	T2,CHNMPE##	;ELSE PARITY ERROR
	PUSH	P,T1		;SAVE IORB
	HRRZ	T1,TKBICP##(W)	;PNTR TO CCW
	HRRZ	P1,TKBCDB##(W)	;PNTR TO CHL DATA BLOCK
	PUSHJ	P,0(T2)		;CALL ROUTINE
	POP	P,T1		;RESTORE IORB PNTR
	MOVSI	T2,RB.SER!RB.SED
	IORM	T2,TRBSTS(T1)	;SET BITS
	PJRST	TCIDON		;RETURN

;ROUTINE TO DETERMINE IF TAPE MOVED (DIVINATION)

TCCKMV:	TLNE	T3,(CI.HNG!CI.REJ)
	POPJ	P,		;TRY THIS FOR NOW
	AOS	TUBREC##(U)	;MOVIN' ALONG
	JRST	CPOPJ1##	;SKIP RETURN
;ERRORS DETECTED DURING WRITE OPERATIONS

TCEWT0:	MOVSI	T2,RB.SNM!RB.SED ;TAPE DIDN'T MOVE
	IORM	T2,TRBSTS(T1)
TCEWT1:	PUSHJ	P,TCEANL	;ANALYSE ERROR
	MOVSI	T2,RB.SLK	;CHECK FOR WRITE LOCK
	TLNE	T3,(CI.FPT)
	IORM	T2,TRBSTS(T1)	;YES - SET BIT
	PJRST	TCIDON		;EXIT INTERUPT

;ERRORS DETECTED DURING READ / SPACING OPS

TCERD0:	MOVSI	T2,RB.SNM!RB.SED ;TAPE DIDN'T MOVE
	IORM	T2,TRBSTS(T1)
TCERD1:	PUSHJ	P,TCEANL	;ERROR ANALYSIS
	PJRST	TCIDON		;EXIT INT

;PROBLEM STARTING REWIND

TCERW:	MOVSI	T2,RB.SED!RB.SNM!RB.SOL
	IORM	T2,TRBSTS(T1)	;SET OFF-LINE ETC.
	PUSHJ	P,CLRCTL	;RESET CTL
	PJRST	TCIDON		;EXIT INT
;ROUTINE TO ANALYSE ERROR BITS IN RH(T3)

TCEANL:	MOVEI	T2,0		;SET INITIAL ZERO
	TLNE	T3,(CI.HNG)
	JRST	TCEOFL		;DRIVE OFF-LINE
	TLNE	T3,(CI.REJ)
	JRST	TCECMR		;COMMAND REJECT
	TLNE	T3,(CI.OVR)
	JRST	TCEOVR		;OVERRUN
	TLNE	T3,(CI.DPE!CI.RCE)
	JRST	TCEDC		;DATA CHECK
TCEXIT:	IORM	T2,TRBSTS(T1)	;SET SELECTED BITS
	POPJ	P,		;RETURN

TCEOFL:	PUSHJ	P,TCXOFL	;SET UNIT OFF-LINE
TCECMR:	MOVSI	T2,RB.SNM!RB.SED ;SET BITS (TAPE DIDN'T MOVE)
	PJRST	TCEXIT

TCEDC:	TLO	T2,RB.SDE	;DATA ERROR
TCEOVR:	TLO	T2,RB.SED	;ERROR DETECTED - RETRY
	PJRST	TCEXIT
SUBTTL COMPUTE CHARACTER COUNTS
;ROUTINE COMPUTES CHARACTER COUNT
;RETURNS COUNT IN T2 , T1 SAVED
;CALLED WITH C(T3) := CONI MTS,

CHRCT:	PUSH	P,T1		;SAVE IORB PNTR
	PUSHJ	P,WRDCTB	;GET WORDCOUNT
	  SKIPA			;LENGTH ERROR RETURN
	AOS	-1(P)		;SET FOR SKIP RETURN
	MOVEI	T2,-1(T1)	;WORD COUNT -1 INTO T2
	XCT	TTCDIS##(W)	;GET BYTE RESIDUE
	LDB	T4,[POINT DI.CHS,T1,DI.CHP]
	JUMPE	T4,[AOJA T2,CHRCT1] ;IF ZERO RE-ADJUST WORD COUNT
	TRCE	T4,5		;ELSE EXCHANGE HIGH & LOW ORDER BITS
	TRCE	T4,5		;...
	TRC	T4,5		;BYTE RESIDUE NOW IN T4
CHRCT1:	DPB	T4,PMTNCR##	;SAVE RESIDUE FOR MTCHR.
	HRLM	T2,TUBCHR##(U)	;STORE LAST WORD COUNT FOR MTCHR.
	XCT	TTCCIS##(W)	; SEE WHAT MODE
	MOVEI	T3,5		;ASSUME CORE-DUMP
	TRNN	T1,CI.CDS	;IS IT?
	MOVEI	T3,4		;NO - COMPAT THEN
	IMUL	T2,T3		;CONVERT TO BYTES
	ADD	T2,T4		;PLUS REMAINDER
	MOVEI	T1,0		;CAN'T GET CRC
	DPB	T1,PMTCRC##	;STORE IT FOR MTCHR.
	PJRST	TPOPJ##		;RESTORE T1 AND EXIT
;ROUTINE TO COMPUTE WORD COUNT FOR DF10
;RETURNS WORD COUNT IN T1 , T3 PRESERVE
;CALLED WITH T1 := IORB

WRDCTB:	MOVE	T1,TKBICP##(W)	;PNTR TO INITIAL CONTROL WORD
	PUSHJ	P,SAVE1##	;SAVE P1
	MOVE	P1,TKBCDB##(W)	;ADDRS OF CDB

	PUSH	P,T3		;SAVE T3
	PUSHJ	P,WRDCNT##	;CALL ROUTINE IN COMMON
	POP	P,T3		;RESTORE T3
	TLNN	T3,(CI.RLD)	;LENGTH = REQUEST?
	JRST	CPOPJ1##	;OK - GIVE GOOD RETURN
	MOVE	T2,TKBICP##(W)	;ICPC PNTR
	HLRZ	T2,1(T2)	;LH TERMINATION WORD
	SKIPGE	CHB22B##(P1)	;SKIP IF DF10
	LSH	T2,-4		;DF10C HAS 14 BIT ADDRS

	SKIPN	(T2)		;ARE WE AT END OF LIST
	POPJ	P,		;YES - SHORT RECORDS OK
	SOJA	T1,CPOPJ1##	;NO - LENGTH IS ONE LESS
	END