Google
 

Trailing-Edge - PDP-10 Archives - BB-M780B-SM - monitor-sources/phym78.mac
There are 27 other files named phym78.mac in the archive. Click here to see a list.
; UPD ID= 40, SNARK:<5.1.MONITOR>PHYM78.MAC.3,   3-Sep-82 15:47:00 by COBB
;TCO 5.1.1056 - Add code to set device online after power change of TM78.
; UPD ID= 95, FARK:<5-WORKING-SOURCES.MONITOR>PHYM78.MAC.2,  18-Aug-82 22:21:03 by WACHS
;[2648] - Fix problems in error recovery
; UPD ID= 592, SNARK:<5.MONITOR>PHYM78.MAC.36,  11-Aug-82 09:20:42 by WACHS
;TCO 5.1780 - Set up Q2 after extended status read interrupt
; UPD ID= 591, SNARK:<5.MONITOR>PHYM78.MAC.35,  29-Jun-82 04:25:25 by WACHS
;TC0 5.1779 - Clear TU7ECD, TU7SNS before starting IO
;TCO 5.1778 - Inhibit error repositioning on last error retry
; UPD ID= 501, SNARK:<5.MONITOR>PHYM78.MAC.34,   5-Mar-82 06:24:45 by WACHS
;TCO 5,1747 - Set up Q1 on interrupt from sense after read of 1st record
;TCO 5,1748 - Worry about RAEs if TM is powered off
; UPD ID= 488, SNARK:<5.MONITOR>PHYM78.MAC.33,  26-Feb-82 11:09:27 by WACHS
;TCO 5.1740 - Check for HOLD in TM status register
; UPD ID= 446, SNARK:<5.MONITOR>PHYM78.MAC.32,  29-Jan-82 05:15:56 by WACHS
;TCO 5.1710 - Set up UDBSLV
; UPD ID= 432, SNARK:<5.MONITOR>PHYM78.MAC.31,  22-Jan-82 08:34:50 by WACHS
;TCO 5.1696 Limit the number of async interrupts to a maximum of 8
; UPD ID= 266, SNARK:<5.MONITOR>PHYM78.MAC.30,  16-Oct-81 11:06:41 by WACHS
;TCO 5.1586 - Increase the retry counter to greater than the microcode's
; UPD ID= 208, SNARK:<5.MONITOR>PHYM78.MAC.29,  23-Sep-81 05:19:24 by WACHS
; UPD ID= 199, SNARK:<5.MONITOR>PHYM78.MAC.28,  21-Sep-81 06:45:53 by WACHS
;TCO 5.1517 Generate a PSI interrupt on REWIND, even if tape is at BOT
; UPD ID= 81, SNARK:<5.MONITOR>PHYM78.MAC.27,  27-Jul-81 09:17:38 by WACHS
;TCO 5.1435 Don't try to read status after TU fault b, MB fault
; UPD ID= 36, SNARK:<5.MONITOR>PHYM78.MAC.26,  16-Jul-81 09:39:10 by WACHS
; UPD ID= 35, SNARK:<5.MONITOR>PHYM78.MAC.25,  16-Jul-81 06:18:04 by WACHS
;TCO 5.1416 Fix bit to check for dual-ported drives
; UPD ID= 2302, SNARK:<5.MONITOR>PHYM78.MAC.24,   7-Jul-81 10:58:24 by WACHS
;TCO 5.1395 Save, restore CDBICR over call to read extended status
; UPD ID= 2041, SNARK:<5.MONITOR>PHYM78.MAC.23,  20-May-81 06:22:32 by WACHS
;TCO 5.1336 Add bits to ICDTBL for entry 22
; UPD ID= 2020, SNARK:<5.MONITOR>PHYM78.MAC.22,  19-May-81 03:43:46 by WACHS
;TCO 5.1333 More checking on done interrupts to make sure we did something
; UPD ID= 1820, SNARK:<5.MONITOR>PHYM78.MAC.21,  17-Apr-81 09:49:55 by WACHS
;TCO 5.1288 Maintain statistics by mode (PE, GCR)
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1980 BY DIGITAL EQUIPMENT CORPORATION.

	SEARCH	PROLOG,PHYPAR,SERCOD	;SYSTEM PARAMETERS
	TTITLE	(PHYM78,,< - DEVICE DEPENDENT CODE FOR TM78/TU78 MAGTAPES >)
	SUBTTL	T. WACHS 22-MAY-80

	SUBTTL	PARAMETERS

	;DRIVE REGISTERS USED IN DATAO'S

	.DOCR==0B5		;DRIVE CONTROL REGISTER
	.DOICD==1B5		;INTERRUPT CODE (DATA XFER)
	   DO.ICD==77		;INTERRUPT CODE
	   DI.FCD==176000	;FAILURE CODE
	.DOFMT==2B5		;RECORD COUNT/FORMAT
	   DO.SER==100000	;SUPPRESS ERROR REPOSITIONING
	   DO.RC1==4		;RECORD COUNT RIGHTMOST BIT
	.DOER==3B5		;ERROR REGISTER
	.DOAS==4B5		;ATTENTION SUMMARY
	.DOBC==5B5		;BYTE COUNT
	.DODT==6B5		;DRIVE TYPE
	.DOSR==7B5		;STATUS REGISTER
	   DI.RDY==100000	;READY
	   DI.PRS==40000	;DRIVE PRESENT
	   DI.PE==4000		;PHASE ENCODED
	   DI.BOT==2000		;AT BOT
	   DI.FPT==400		;FILE PROTECTED
	   DI.AVL==200		;AVAILABLE (TO THIS MASSBUS)
	   DI.MNT==40		;IN MAINTENANCE MODE
	.DOSN==10B5		;SERIAL NUMBER
	.DODG==11B5		;DIAGNOSTIC
	.DODG2==12B5		;DIAGNOSTIC
	.DOICN==13B5		;INTERRUPT CODE (NON DATA-XFER)
	   DI.DRV==1400		;DRIVE NUMBER
	.DOND0==14B5		;NON DATA-XFER COMMAND, UNIT 0
	   DO.NDC==177400	;COUNT FIELD
	   DO.NDF==77		;FUNCTION CODE
	   NDCSHF==^D8		;SHIFT VALUE FOR COUNT
	.DOND1==15B5		;COMMAND, UNIT 1
	.DOND2==16B5		;COMMAND, UNIT 2
	.DOND3==17B5		;COMMAND, UNIT 3
	.DOIA==20B5		;INTERNAL ADDRESS
	.DOTMS==21B5		;TM STATUS
	   DI.TMR==1B20		;TM READY
	   DO.TMC==1B21		;TM CLEAR
	   DO.HLA==1B26		;HOLD ACKNOWLEDGED
	   DO.HLD==1B27		;HOLD


DO.ERD==177777			;BITS IN DATAO (MASSBUS IS 16 BITS)
	;DRIVE FUNCTIONS
	DF.NOP==3		;NO-OP
	DF.UNL==5		;UNLOAD
	DF.REW==7		;REWIND
	DF.SNS==11		;SENSE
	DF.DSE==13		;DATA SECURITY ERASE
	DF.WTM==15		;WRITE TAPE MARK (PE)
	DF.SPF==21		;SPACE FORWARD RECORD
	DF.SPR==23		;SPACE REVERSE RECORD
	DF.SFF==25		;SPACE FORWARD FILE
	DF.SRF==27		;SPACE REVERSE FILE
	DF.SFE==31		;SPACE FORWARD RECORD OR FILE
	DF.SRE==33		;SPACE REVERSE RECORD OR FILE
	DF.ERG==35		;ERASE 3 INCHES OF TAPE (PE)
	DF.CLF==41		;CLOSE FILE (PE) - 2 EOFS, BACKSP 1
	DF.LET==45		;SKIP TO LOGICAL EOT

	DF.WRT==61		;WRITE (PE)
	DF.RED==71		;READ
	DF.RRV==77		;READ REVERSE
	DF.XSN==73		;EXTENDED SENSE
	SUBTTL	DEVICE DEPENDENT TABLE DEFS
;****************************
;UDB EXTENSIONS
	TU7HDN==UDBDDM		;HARDWARE-DETERMINED DENSITY
				; NOTE THAT MAGTAP USES THIS WORD
	TU7SNS==TU7HDN+1	;NON-0 IF DOING A SENSE OPERATION
	TU7ECD==TU7SNS+1	;ERROR BITS FROM TABLE IF AN ERROR ON LAST IO
	TU7ESD==TU7ECD+1	;SAVED ERROR BITS WHILE DOING A SENSE
	TU7RRO==TU7ESD+1	;NON-0 IF IN REREAD OPPOSITE ERROR RECIVERY
	LU.TM8==TU7RRO+1	;LENGTH OF TM78 UDB

;****************************
;KDB DEVICE DEPENDENT PORTION
	TM8ADR==KDBDDP+4	;MASSBUS ADDRESS OF TM78
	SAVUDB==TM8ADR+1	;CURRENT UDB (0 IF NONE)
	SAVFNC==SAVUDB+1	;CURRENT FUNCTION/FLAGS
	SAVLSI==SAVFNC+1	;LAST INTERRUPT CODE 
	TM8XCW==SAVLSI+1	;CCW FOR READING EXTENDED SENSE INFO
	TM8SCW==TM8XCW+1	;SAVED CCW WHILE READING EXTENDED SENSE
	TM8ACT==TM8SCW+1	;COUNT OF ASYNCHRONOUS INTERRUPTS
	TM8CNI==TM8ACT+1	;CONI OF RH GOES HERE
	TM8CS1==TM8CNI+1	;DATAI RH CONTROL REGISTER
	TM8DBF==TM8CS1+1	;DATAI RH DATA REGISTER
	TM8REG==TM8DBF+1	;DRIVE REGISTERS GO HERE
	 DR.CR==0		;DRIVE CONTROL REGISTER
	 DR.ICD==1		;INTERRUPT CODE (DATA XFER)
	 DR.FMT==2		;RECORD COUNT/FORMAT
	 DR.ER==3		;ERROR REGISTER
	 DR.AS==4		;ATTENTION SUMMARY
	 DR.BC==5		;BYTE COUNT
	 DR.DT==6		;DRIVE TYPE
	 DR.SR==7		;STATUS REGISTER
	 DR.SN==10		;SERIAL NUMBER
	 DR.DG==11		;DIAGNOSTIC
	 DR.DG2==12		;DIAGNOSTIC
	 DR.ICN==13		;INTERRUPT CODE (NON DATA-XFER)
	 DR.ND0==14		;NON DATA-XFER COMMAND, UNIT 0
	 DR.ND1==15		;COMMAND, UNIT 1
	 DR.ND2==16		;COMMAND, UNIT 2
	 DR.ND3==17		;COMMAND, UNIT 3
	 DR.IA==20		;INTERNAL ADDRESS
	 DR.TMS==21		;TM STATUS
	TM8REV==TM8REG+22	;ROM REV LEVELS
	TM8XSN==TM8REV+2	;EXTENDED SENSE INFORMATION
	TM8ELN==TM8XSN+17-TM8REG ;LENGTH OF ERROR REGION
	LK.TM8==TM8XSN+17	;LENGTH OF KDB

	TM8SLC==4		;MAX NO OF DRIVES ON A TM78
	TM8AMX==10		;MAX NO OF ASYNC INTERRUPTS BEFORE STOPPING TM
RTYOP==^D55			;MAX NO OF RETRIES (IF NOT ERR CODE 22)
				;THIS MUST BE GTR THAN 50 (THE MICROCODE'S VALUE)
				; TO PREVENT OVERWRITING HARD ERROR RECORDS
ERSTRY==400			;BIT TO TELL PHYH2 ABOUT ALREADY-SET IOLIST
	SUBTTL	DISPATCH FOR TM78

TM8DSP::JRST	TM8INI		;0 - INITIALIZATION
;**;[2648] REPLACED 1 LINE AT TM8DSP+1L	TW	18-AUG-82
	JRST	TM8SI0		;[2648]1 - START I/O
	JRST	TM8INT		;2 - HANDLE INTERRUPT (DATA OPERATION)
	JRST	TM8ERR		;3 - ERROR RECOVERY
	JRST	TM8HNG		;4 - HUNG DEVICE
	RET			;5 - NOT USED
	RET			;6 - NOT USED
;**;[2648] REPLACED 1 LINE AT TM8DSP+7L	TW	18-AUG-82
	JRST	TM8SI0		;[2648]7 - START POSITION OPERATION
	JRST	TM8ATN		;10 - ATTENTION INTERRUPT 
	JRST	TM8PRQ		;11 - SKIP IF POSITION REQUIRED
	RET			;12 - STACK SECOND COMMAND, FAIL FOR TM78
	JRST	TM8LGL		;13 - CHECK LEGALITY OF A UNIT
	RET			;14 - CHECK FOR HALTED CONTROLLER

TM8HNG:	MOVX	T1,IS.NRT!IS.ERR!IS.DVE	;SET FATAL BITS
	IORM	T1,IRBSTS(P4)	;AND REFRESH IT
	HRRZ	T2,CDBICP(P1)
	SKIPE	T1,TM8SCW(P2)	;IS THERE A SAVED CCW (USING A FAKE FOR EXTENDED STATUS)?
	MOVEM	T1,(T2)		;YES, PUT BACK THE REAL CCW
	SETZM	TM8SCW(P2)	;NO SAVED CCW NOW
	SETZM	TU7SNS(P3)	;MAKE SURE THESE FLAGS ARE CLEAR
	SETZM	TU7RRO(P3)
	RET

TM8LGL:	CAILE Q2,3		;ONLY 4 UNITS ARE LEGAL
	JRST RFALSE		;BUT PHYSIO THINKS 8 ARE OK
	JRST EXTUDB		;GO SEE WHAT PHYSIO THINKS

;HERE TO DETERMINE IF THIS REQUEST SHOULD GO ON PWQ OR TWQ
TM8PRQ:	LDB	T1,IRYFCN	;GET FUNCTION
	SKIPL	FNCTBL(T1)	;DATA OPERATION?
	RETSKP			;NO - POSITION ALWAYS REQUIRED
	HRRZ	T2,UDBPWQ(P3)	;YES - ANY PENDING POSITION OPERATIONS?
	JUMPE	T2,R		;NONE - APPEND TO TWQ
	CAIN	T2,(P4)		;AT HEAD OF PWQ?
	RET			;YES - NEXT TRANSFER
	RETSKP			;APPEND TO PWQ
;ROUTINE TO RESET THE TM78 AND WAIT FOR DONE
;RETURNS +1 (ALWAYS) WITH T4 NON-0 IF WE WON, =0 IF WE LOST

TM8ZAP:	MOVE	T2,[.DOTMS!DO.TMC] ;DO AN INIT OF THE TM78
	CALL	WTREG3
	MOVEI	T4,4000		;HOW LONG TO WAIT
TM8ZA1:	MOVSI	T2,(.DOTMS)	;READ TM78 STATUS
	PUSHJ	P,RDREG3
	TRNN	T1,DI.TMR	;TM READY?
	SOJG	T4,TM8ZA1	;NO, TRY AGAIN
	RET			;RETURN
	SUBTTL	START I/O ROUTINE
;C(P4)=IORB C(P1)=CDB C(P2)=KDB C(P3)=UDB
;IF IN ERR RECOVERY, GET FN FROM RH(UDBERR)
;RET MEANS RE-CALL IN 1 MIN TO TRY AGAIN
;PUTS TM78 FN IN Q1, AND DATAO IN T2
;RETSKP (CHSTRT) MEANS OK, IT'S STARTED

;**;[2648] ADDED 2 LINES BEFORE TM8SIO	TW	18-AUG-82
TM8SI0:	SETZM	TU7ECD(P3)	;[2648]MAKE SURE FLAGS ARE ZERO AT START
	SETZM	TU7SNS(P3)	;[2648]

TM8SIO:	MOVX	T2,.DOTMS	;READ STATUS REGISTER
	CALL	RDREG
	JUMPE	T1,CLRCHL	;IF POWERED DOWN, RESET RH INTERRUPT ENABLE
	TRNE	T1,DI.TMR	;TM READY?
	TRNE	T1,DO.HLD	;HOLD OFF?
	RET			;NO, "PROBLEM ON DEVICE"
				;START OF TCO 5.1.1056
	MOVX	T2,US.OFS	;GET THE ONLINE/OFFLINE BIT
	ANDCAM	T2,UDBSTS(P3)	;MAKE SURE DEVICE IS NOT MARKED OFFLINE.
				;END OF TCO 5.1.1056
	SKIPN	Q1,UDBERR(P3)	;YES. GET FUNCTION IF ERROR RECOVERY
	LOAD	Q1,ISFCN,(P4)	;NO, GET FN FROM IORB
	SKIPE	Q1,FNCTBL(Q1)	;VALID FN?
	SKIPGE	IRBSTS(P4)	;MAKE SURE PAGEM NOT SET
	JRST	BADSIO		;IF SET REFUSE IT
	LOAD	T1,IRBDN,(P4)	;DENSITY
	CAIG	T1,MAXDEN
	SKIPGE	T1,DENTBL(T1)	;LEGAL?
	JRST	ILLFNC
	TXNE	Q1,TB.WRT	;WRITE?
	TRO	Q1,(T1)		;YES, SET GCR/PE IN FUNCTION
	LOAD	T1,IRBPAR,(P4)	;GET PARITY
	JUMPE	T1,TM8SI1	;GO IF ODD PARITY
ILLFNC:	MOVX	T1,IS.ERR!IS.NRT!IS.DVE
	IORM	T1,IRBSTS(P4)	;BAD PARITY/DENSITY - HARD ERROR
	RET
TM8SI1:	SKIPGE	TM8ACT(P2)	;HOLD SET?
	CALL	CLRHLD		;YES, CLEAR IT
	SETZM	TM8ACT(P2)	;INDICATE NO ASYNC INTERRUPTS
	JUMPL	Q1,TM8SI4	;GO IF A DATA OP
	SKIPN	UDBERR(P3)	;NON-DATA. IN ERROR RECOVERY?
	SKIPA	T2,IRBCNT(P4)	;NO, GET RECORD COUNT FROM IORB
	MOVEI	T2,1		;YES, ONLY DO 1 RECORD
	LSH	T2,NDCSHF	;PUT COUNT WHERE THE HDWRE WANTS IT
	ANDI	T2,DO.NDC	;8 BITS-WORTH
	TRO	T2,(Q1)		;PUT FUNCTION INTO COMMAND
	CAME	Q1,REWFNC	;REWIND?
	JRST	TM8SI2		;NO
	SETZM	UDBPS2(P3)	;YES, SET AT 0TH REC, 0TH FILE
	SETZM	UDBPS1(P3)
	JRST	TM8SI2		;AND KEEP ON

;HERE TO DO A SENSE ON A GIVEN DRIVE
SENSE:	MOVEM	Q1,TU7SNS(P3)	;LET EVERYONE KNOW WHAT WE'RE DOING
	MOVEI	T2,DF.SNS	;FUNCTION = SENSE
TM8SI2:	HLL	T2,UDBSLV(P3)	;POINT AT RIGHT REGISTER FOR THIS DRIVE
	MOVX	T1,US.OFS
	CAMN	Q1,UNLFNC	;UNLOAD?
	IORM	T1,UDBSTS(P3)	;YES, SET THE DRIVE OFF-LINE
	MOVEM	Q1,SAVFNC(P2)	;SAVE WHAT WE'RE DOING
	SETOM	Q1		;ONLY 1 COMMAND
	JRST	TM8SI5		;GO DO IT
;HERE TO START A DATA OPERATION
TM8SI4:	LOAD	T4,IRBDM,(P4)	;MODE
	CAIG	T4,MAXMOD	;LEGAL?
	SKIPGE	T4,MODTBL(T4)
	JRST	ILLFNC		;NO, RETURN AN ERROR
	MOVEI	T2,DO.RC1(T4)	;YES, SET 1 RECORD + FORMAT
	TRO	T2,@UDBSLV(P3)	;SET UNIT
	MOVE	T1,IRBSTS(P4)
;**;[2648] ADDED 3 LINES AT TM8SI4+7L	TW	18-AUG-82
	SKIPE	T3,UDBERR(P3)	;[2648]IN ERROR RECOVERY?
	MOVE	T3,UDBERC(P3)	;[2648]YES, GET RETRY COUNT
	CAIE	T3,RTYOP	;[2648]INHIBIT ERROR RETRY IF LAST RETRY
	TXNE	T1,IS.IER	;INHIBITING ERROR RETRY?
	TRO	T2,DO.SER	;YES, TELL THE HARDWARE
	HRLI	T2,(.DOFMT)	;WRITE TO FORMAT REGISTER
	CALL	WTREG		;DO IT
	MOVE	T2,IRBCNT(P4)	;GET WORDCOUNT
	HLRZS	T4		;FRAMES PER WORD
	IMULI	T2,(T4)		;FRAME COUNT
	ANDI	T2,DO.ERD	;ENSURE ONLY 16 BITS-WORTH
	HRLI	T2,(.DOBC)	;WRITE BYTE COUNT REGISTER
	MOVEM	Q1,SAVFNC(P2)	;SAVE FUNCTION WE'RE DOING
	ANDI	Q1,77
TM8SI5:	HRRZM	P3,SAVUDB(P2)	;SAVE WHAT SLAVE WE'RE DOING IT TO
	JRST	CHSTRT
BADSIO:	BUG(PM8SIO)
	MOVX	T1,IS.ERR!IS.NRT!IS.DVE	;MARK AN ERROR OCCURED
	IORM	T1,IRBSTS(P4)	;IN IORB
	RET
	SUBTTL	INTERRUPT PROCESSING
;COMES HERE ON AN ATA INTERRUPT (INCLUDING SPACING OPS)
;C(P1)=CDB C(P2)=KDB
;WILL SET C(P4)= 0 IF NONE
;SETS C(P3)=UDB
;ALWAYS RET (NEVER SKP RET'S)
;IF ERR, IS.ERR AND EITHER <IS.DVE OR IS.DTE> WILL BE SET
;IF IS.ERR NOT SET, WE ARE FINISHED WITH THIS IORB
TM8ATN:	SAVEQ			;SAVE SOME REGS
	MOVE	Q2,TM8ADR(P2)	;GET UNIT NUMBER
	MOVX	T2,.DOICN	;READ NON-DATA INTERRUPT CODE
	CALL	RDREG3
	LDB	P3,[POINT 2,T1,27] ;DRIVE NUMBER
	ADDI	P3,KDBUDB(P2)	;+ START OF DRIVES
	SKIPN	P3,(P3)		;POINT P3 AT UDB
	JRST	NOUDB		;IT'S A NEW ONE ON ME!
TM8AT1:	CALL	ANLYZE		;FIGURE OUT WHAT HAPPENED
	  JRST	ATDONE		;RETURN, WILL GET ANOTHER INTERRUPT
	MOVX	T1,US.BOT+US.PSI
	CAMN	Q1,REWFNC	;WAS FUNCTION A REWIND?
	IORM	T1,UDBSTS(P3)	;YES, SET BOT, FOR POSSIBLE PSI
	CALL	ATDONE		;CLEAR THE ATTENTION BIT NOW
	SKIPN	TU7SNS(P3)	;DOING A SENSE?
	JRST	TM8AT2		;NO
	SKIPE	TU7ECD(P3)	;YES, IF NOT SENSE AFTER READ OF 1ST RECORD
	JUMPE	Q3,RSKP		;GET TO TM8ERR IF SENSE AFTER RH20 ERROR
	MOVE	Q1,TU7SNS(P3)	;SENSE AFTER 1ST RECORD. RESET Q1
	JRST	TM8IN2		;KEEP ON GOING (ITS "REALLY" A DATA INTERRUPT)
TM8AT2:	TXNN	Q1,TB.DAT	;NO. DATA OP?
	RET			;NO. WE'RE DONE
TM8ATX:	MOVX	T1,IS.ERR!IS.DVE;DATA OP, ATTEN INTERRUPT - ERROR
	IORM	T1,IRBSTS(P4)
	RET			;TELL UPPER LEVEL WE HAVE A PROBLEM

ATDONE:	MOVE	Q1,TM8ADR(P2)	;RESTORE Q1 (ANLYZE WIPES IT)
	MOVEI	T2,1		;POSITION A BIT
	LSH	T2,(Q1)		;TO CLEAR THE RIGHT ATTENTION BIT
	HRLI	T2,(.DOAS)
	CALLRET	WTREG3		;CLEAR THE ATTEN AND RETURN TO PHYH2
;HERE WHEN WE GET AN ON-LINE INTERRUPT FROM AN UNKNOWN SLAVE
NOUDB:	LDB	P3,[POINT 2,T1,27] ;GET UNIT
	ANDI	T1,DO.ICD	;GET INTERRUPT CODE
	CAIE	T1,ICDND1	;IS IT ONE FOR WHICH THE DRIVE ADDRESS ISNT VALID?
	CAIN	T1,ICDND2
	SKIPA	P3,SAVUDB(P2)	;YES, HAVE TO GET THE DRIVE A DIFFERENT WAY
	JRST	NOUDB1		;NO, THIS REALLY IS A NEW DRIVE
	JUMPN	P3,TM8AT1	;GO IF WE WERE WORKING ON A DRIVE
	MOVE	T1,KDBIUN(P2)	;NOT WORKING ON A DRIVE. FIND ONE
	SKIPE	P3,(T1)		;FIND THE FIRST (LOWEST NUMBER) DRIVE ON THE TM
	JRST	TM8AT1		;GO BLAME THE ERROR ON THAT
	AOBJN	T1,.-2		;THIS DRIVE DOESN'T EXIST, TRY NEXT
	RET			;NO DRIVES AT ALL! FORGET IT
NOUDB1:	CALL	ATDONE		;CLEAR THIS ATTENTION
	MOVEI	T2,DR.ND0(P3)
	ROT	T2,-6		;DO A SENSE ON THE DRIVE
	HRRI	T2,DF.SNS
	CALL	WTREG3		; SINCE WE CAN'T READ STATUS WITHOUT IT
	MOVEI	T4,400000	;WAIT FOR THE ATTENTION AFTER THE SENSE FINISHES
NOUDB2:	MOVX	T2,.DOAS
	CALL	RDREG3
	TRNN	T1,377		;ATTEN?
	SOJG	T4,NOUDB2	;NO, WAIT A BIT
	MOVE	Q1,P3		;YES, SET Q1=UNIT NO
	CALL	INIUNI		;BUILD THE UDB
	AOS	MTAJB0		;TELL WORLD TO LOOK FOR A NEW UNIT
	SETZ	P4,		;SO PHYSIO WONT GET UPSET
	JRST	ATDONE		;CLEAR THE ATTEN AND RETURN, DISMISSING INTERRUPT
;ENTER HERE FROM RH20 COMMAND DONE INTERRUPT
;C(P1)=CDB  C(P2)=KDB
TM8INT:	SAVEQ			;SAVE REGS
	SKIPN	P3,SAVUDB(P2)	;ARE WE DOING SOMETHING?
	JRST	TM8INU		;NO, WE OUGHTN'T BE HERE
	SKIPE	Q1,TU7SNS(P3)	;DOING A SENSE?
	TXNN	Q1,TB.XSN	;YES, AN EXTENDED SENSE?
	JRST	TM8IN1		;NO
	HRRZ	T1,CDBICP(P1)	;YES, PUT BACK THE REAL CCW
	MOVE	T2,TM8SCW(P3)	; (WE OVERWROTE IT TO READ EXTENDED SENSE BYTES)
	MOVEM	T2,(T1)
	SETZM	TM8SCW(P2)	;THE WORLD IS NOW BACK TOGETHER
;**;[2648]ADDED 1 LINE AT TM8INT+10L	TW	18-AUG-82
	MOVE	Q2,TM8ADR(P2)	;[2648]POINT Q2 AT UNIT
	CALL	ANLYZ1		;KEEP ON WITH THE ORIGINAL INTERRUPT
	  JRST	[SETZ P4,	;ASYNC - FORGET IT
		 RET]
	JRST	TM8IN2		;NORMAL RETURN - KEEP ON

;HERE ON A "NORMAL" DONE INTERRUPT (NO EXTENDED SENSE GOING)
TM8IN1:	MOVX	T2,.DOICD	;GET THE INTERRUPT REASON
	MOVE	Q2,TM8ADR(P2)	;WHAT UNIT TO GET IT FOR
	CALL	RDREG3
	CALL	ANLYZE		;FIGURE OUT WHAT HAPPENED
	  JRST	[SETZ P4,	;ASYNC OR ANOTHER COMING
		 RET]
	TRNE	Q3,(IS.ERR)	;IF THE TM78 SAW AN ERROR
	JRST	TM8IN2		; DON'T WORRY ABOUT WHETHER THE RH20 SAW ONE TOO
	CALL	CKERR		;CHECK FOR RH20 ERRORS
	  JRST	TM8RDH		;CHAN ERROR. READ REGS
TM8IN2:	SKIPGE	P5,TU7HDN(P3)	;GET DENSITY
	LOAD	P5,IRBDN,(P4)	;HARDWARE DOESN'T KNOW, GET IT FROM IORB
	CAIN	P5,.SJD16	;1600 BPI (PE MODE)?
	SKIPA	P5,P3		;YES, SET TO ACCUMULATE PE FRAMES
	MOVEI	P5,1(P3)	;NO, SET TO ACCUMULATE GCR FRAMES
	TXNN	Q1,TB.RD	;READ?
	JRST	TM8IN4		;NO
	SKIPN	TU7SNS(P3)	;YES, ALREADY DONE A SENSE?
	TRNE	Q3,(IS.ERR)	;NO, ERROR?
	TDZA	T2,T2		;NO
	MOVE	T2,UDBPS2(P3)	;GOOD READ, NO SENSE JUST DONE.  GET POSITION
	SKIPN	UDBPS1(P3)	;AT FILE 0, RECORD 1?
	SOJE	T2,[SETZ P4,	;YES. DO A SENSE TO DETERMINE DENSITY
		    JRST SENSE]	;AND TELL PHYSIO ANOTHER INTERRUPT IS COMING
	MOVX	T2,.DOBC	;NOT AFTER 1ST RECORD. READ BYTE COUNT
	CALL	RDREG3
	TRNN	Q3,(IS.ERR)	;IF RECORD IS NOT IN ERROR,
	ADDM	T1,UDBRED(P3)	; ACCUMULATE FRAMES READ
	ADDM	T1,UDBRPE(P5)	;ACCUMULATE FRAMES READ IN PE/GCR
	LOAD	T3,IRBDM,(P4)
	HLRZ	T3,MODTBL(T3)	;COMPUTE WORDS READ
	SOJE	T3,TM8IN3	;SAVE TIME IF BYTES=FRAMES
	IDIVI	T1,1(T3)
	JUMPE	T2,TM8IN3	;GO IF AN INTEGRAL NUMBER OF BYTES
	ADDI	T1,1
TM8IN3:	MOVEM	T1,IRBCNT(P4)	;SAVE WORDCOUNT
TM8IN4:	TXNN	Q1,TB.WRT	;WRITE?
	JRST	DTDONE		;NO
	LOAD	T3,IRBDM,(P4)	;YES, ACCUMULATE BYTES WRITTEN
	HLRZ	T3,MODTBL(T3)
	IMUL	T3,IRBCNT(P4)
	ADDM	T3,UDBWRT(P3)
	ADDM	T3,UDBWPE(P5)	;ACCUMULATE BYTES WRITTEN IN PE OR GCR
DTDONE:	SETZM	TU7ECD(P3)	;CLEAN UP ANY TEMPS
	SETZM	TU7SNS(P3)
	TRNN	Q3,(IS.ERR)	;ERROR?
	RETSKP			;NO, TELL PHYH2/PHYSIO ALL IS GOOD
	MOVEM	Q3,TU7ECD(P3)	;ERROR - MAKE SURE TM8ERR KNOWS ABOUT IT
	RET			;AND SIGNIFY BY NON-SKIP


;HERE ON DONE INTERRUPT, NO UDB IS CURRENT
TM8INU:	BUG(TM8NUD)
	JRST	TM8ATX
;SUBROUTINE TO FIGURE OUT WHAT HAPPENED 
;ENTER T1=INTERRUPT CODE REGISTER
;EXIT Q1=FUNCTION, Q3=INTERRUPT TABLE CONTENTS
;NON-SKIP IF ANOTHER INTERRUPT IS COMING, OR IT REQUIRES NO ACTION
;SKIP (WITH P4=IORB) IF IT IS "REAL"
ANLYZE:	MOVE	Q1,SAVFNC(P2)	;FUNCTION WE DID
	SETZ	P4,		;IN CASE WE NON-SKIP RETURN
	SKIPN	TU7SNS(P3)	;DOING A SENSE?
	JRST	ANLYZ4		;NO
	TRNE	T1,76		;IS IT A DONE?
	RET			;NO, IGNORE IT
	MOVE	Q1,TU7SNS(P3)	;YES, GET UPDATED BITS
	PUSH	P,T1		;SAVE INTERRUPT CODE
	TXNN	Q1,TB.RRG	;SENSE SO WE CAN READ REGS 7-10?
	JRST	ANLYZ2		;NO
	CALL	RDREG2		;YES, READ THEM NOW
	POP	P,T1		;RESORE INTERRUPT CODE
	MOVE	T2,TU7ECD(P3)	;EXTRA INTERRUPT FLAGS
	TLNN	T2,-1		;RH20 ERROR?
	JUMPN	T2,[MOVEI P4,1	;YES, SET LH(TU7ECD) NON-0
		    HRLM P4,TU7ECD(P3) ;SO TM8ERR WILL KNOW WHERE WE ARE
		    CALLRET SETIRB] ;DISMISS INTERRUPT, COME BACK AT TM8ERR
ANLYZ1:	MOVE	Q3,TU7ESD(P3)	;GET UPDATED ERROR BITS
	SKIPGE	CDBXFR(P1)	;DOING A DATA XFER?
	JRST	ANLYZ6		;NO. CANT READ THE ERROR LOG NOW
	TXNE	Q3,IC.XSN	;NEED AN EXTENDED SENSE?
	TXOE	Q1,TB.XSN	;YES, HAVE WE JUST DONE IT?
	JRST	ANLYZ6		;DONT NEED IT OR JUST DID IT - KEEP ON
	JRST	ANLY12		;GO DO AN EXTENDED SENSE

;HERE FOR A SENSE WHEN DRIVE COMES ON-LINE OR AFTER READING 1ST RECORD
ANLYZ2:	MOVX	T2,.DOSR	;READ THE STATUS REGISTER
	CALL	RDREG3
	JUMPL	Q1,ANLYZ3	;GO IF A DATA OPERATION
	MOVX	T2,US.WLK!US.BOT ;ON-LINE SENSE - CLEAR/SET WRITE LOCK, BOT
	ANDCAM	T2,UDBSTS(P3)
	TRNN	T1,DI.FPT
	TXZ	T2,US.WLK	;NOT WRITE-LOCKED
	TRNN	T1,DI.BOT
	TXZ	T2,US.BOT	;NOT AT BOT
	IORM	T2,UDBSTS(P3)	;SET STATUS
	POP	P,(P)		;MAKE THE STACK RIGHT
	SETZM	TU7SNS(P3)	;DONE WITH THE SENSE
	SETZM	SAVFNC(P2)	;INDICATE WE AREN'T USING DRIVE
	TXNN	T2,US.BOT	;AT BOT?
	RET			;NO
	SETZM	UDBPS1(P3)	;YES, CLEAR COUNTERS
	SETZM	UDBPS2(P3)	; OF RECORD, FILE
	SETOM	TU7HDN(P3)	;INDICATE UNKNOWN DENSITY
	RET			;NON-SKIP RETURN (TOSS THE INTERRUPT)
;HERE AFTER READING 1ST RECORD. GET DENSITY FROM THE HARDWARE
ANLYZ3:	CALL	SETIRB		;POINT AT IORB
	MOVEI	T2,.SJD16	;ASSUME 1600
	TRNN	T1,DI.PE
	MOVEI	T2,.SJD62	;NOPE, ITS 6250
	MOVEM	T2,TU7HDN(P3)	;SAVE DENSITY IN UDB
	POP	P,T1		;MAKE STACK RIGHT/RESTORE INTERRUPT CODE
	TXZ	Q1,TB.DAT	;SET Q1 SO WE WON'T INCREMENT UDBPS2
				;FALL INTO ANLYZ4

;HERE ON REGULAR INTERRUPT OR SENSE AFTER READING 1ST RECORD
ANLYZ4:	MOVEM 	T1,SAVLSI(P2)	;SAVE LAST INTERRUPT CODE
	ANDI	T1,DO.ICD	;6 BITS OF INTERRUPT CODE
	CAILE	T1,MAXICD	;LEGAL?
	MOVEI	T1,0		;NO
	SKIPN	Q3,TU7RRO(P3)	;IN RETRY OPPOSITE?
	JRST	ANLYZ5		;NO NEED TO DO ANYTHING NOW
	SETZM	TU7RRO(P3)	;NOW NO LONGER IN OPPOSITE MODE
	HRRZ	P4,UDBTWQ(P3)	;GET IORB ADDRESS
	JUMPE	P4,ANLYZ5	;FORGET IT IF NO IORB (!)
	MOVE	T2,IRBCNT(P4)	;GET WORDCOUNT OF RECORD
	SKIPN	T3,UDBERR(P3)	;GET FUNCTION
	LOAD	T3,ISFCN,(P4)
	SKIPL	FNCTBL(T3)	;IS IT A DATA OPERATION?
	JRST	ANLYZ5		;NO (!)
	PUSH	P,T1		;SAVE INTERRUPT CODE
	CALL	REVCCW		;YES, RE-REVERSE THE IO LIST
	HLLM	Q3,(Q3)		;RESTORE LH OR CHANGED IOWD TO ITS ORIGINAL VALUE
	POP	P,T1
ANLYZ5:	SKIPL	Q3,ICDTBL(T1)	;GET ERROR BITS ASSOCIATED WITH THIS INTERRUPT
	JRST	ANLYZ6		;NOT AN ERROR
	SKIPE	UDBERR(P3)	;ERROR. FIRST TIME?
	TXNN	Q3,IC.PAD	;NOT 1ST. DON'T SENSE IF TM78 WILL REPOSITON
	JRST	TM8RDR		;ERROR - READ REGISTERS
ANLYZ6:	TXNN	Q3,IC.RRG	;NON-ERROR INTERRUPT?
	SKIPN	UDBERR(P3)	;YES, IN ERROR RECOVERY?
	CAIA			;ERROR OR NOT IN ERROR RECOVERY
	CALL	RDREG4		;GOOD READ IN ERROR RECIVERY - READ FINAL REGS
	TXNN	Q3,IC.ASY	;ASYNC?
	AOS	(P)		;NO, SET FOR SKIP-RETURN
	TXNE	Q3,IC.DSP	;DISPATCH ADDRESS?
	JRST	(Q3)		;YES, GO TO SUBROUTINE
	SKIPGE	UDBSTS(P3)	;OFF-LINE?
	JRST	[CAME Q1,UNLFNC ;YES, IS IT AN UNLOAD?
		 RET		;NO, FORGET THE INTERRUPT
		 JRST .+1]	;YES, REPORT COMPLETION TO PHYSIO
				;FALL INTO HERE FROM PREVIOUS PAGE
ANLYZ7:	CAMN	P3,SAVUDB(P2)	;NO. HERE FOR THE "RIGHT" UNIT?
	SETZM	SAVUDB(P2)	;YES, CLEAR THE SAVED UDB
	MOVX	T2,US.BOT	;CLEAR BOT, PICK UP DRIVE STATUS
	TXNE	Q3,(IS.BOT)	;DID WE HIT BOT?
	IORB	T2,UDBSTS(P3)	;YES, TELL THE WORLD
	TXNN	Q3,(IS.BOT)	;IF NOT AT BOT
	ANDCAB	T2,UDBSTS(P3)	;TELL THE WORLD WE AREN'T
	TXNE	T2,US.REW	;WAS IT REWINDING?
	JRST	ANLY10		;YES, TELL WORLD WE'RE DONE
	JUMPE	Q1,ANLY11	;NO, GO AWAY IF WE DIDN'T TELL IT TO DO ANYTHING
	HRRZ	T1,UDBTWQ(P3)	;GET TOP ENTRY IN TRANSFER QUEUE
	ADD	T1,UDBPWQ(P3)	; + TOP ENTRY IN POSITION QUEUE
	TRNN	T1,-1		;ANYTHING THERE?
	JRST	ANLY11		;NO, FORGET THIS INTERRUPT
	TXNN	Q3,IC.BST	;SET A BIT IN IORB?
	TDZA	T1,T1		;NO
	HRLZ	T1,Q3		;YES, GET THE BIT(S) TO SET
	CALL	SETIRB		;POINT P4 AT IORB
	MOVX	T2,IS.DVE!IS.DTE;CLEAR ERROR BITS
	ANDCAM	T2,IRBSTS(P4)
	IORM	T1,IRBSTS(P4)	;AND SET BIT(S) FROM THIS INTERRUPT
	TXNN	Q1,TB.SPC	;SPACING OPERATION?
	JRST	ANLYZ8		;NO, COUNT 1 RECORD
	SKIPE	UDBERR(P3)	;IN ERROR RECOVERY?
	JRST	[MOVEI T1,1	;YES, 1 RECORD
		 JRST ANLYZ9]
	HLLZ	T2,UDBSLV(P3)	;NO, READ CURRENT RECORD COUNT
	CALL	RDREG3
	LSH	T1,-NDCSHF	;RIGHT-JUSTIFY IT
	EXCH	T1,IRBCNT(P4)	;TELL WORLD HOW MANY WE DIDNT DO
	SUB	T1,IRBCNT(P4)	;COMPUTE AMOUNT WE DID DO
	JRST	ANLYZ9		;GO UPDATE POSITON
ANLYZ8:	TXNN	Q3,IC.SNM!IC.PAD;ANY MOTION?
	TXNN	Q1,TB.DAT	;YES, DATA OP?
	TDZA	T1,T1		;NO MOTION, DONT UPDATE POSITION
	MOVEI	T1,1		;WE MOVED 1 RECORD
	SKIPE	TU7RRO(P3)	;IN RETRY OPPOSITE?
	TXC	Q1,TB.REV	;YES, GET ORIGINAL DIRECTION
ANLYZ9:	TXNE	Q1,TB.REV	;REVERSE?
	MOVNS	T1		;YES
	ADDM	T1,UDBPS2(P3)	;UPDATE RECORD POSITION
	SETZM	SAVFNC(P2)	;INDICATE WE AREN'T DOING ANYTHING
	TRNN	Q3,(IS.TPM)	;TAPE MARK?
	RET			;NO, RETURN
	SETZM	UDBPS2(P3)	;YES, AT 0TH RECORD
	TXNE	Q1,TB.REV	;UPDATE FILE COUNTER
	SOSA	UDBPS1(P3)
	AOS	UDBPS1(P3)
	RET			;AND RETURN

;HERE ON AN INTERRUPT WHEN DRIVE IS MARKED AS REWINDING
ANLY10:	CALL	PHYRWD		;TELL REST OF WORLD WE FINISHED THE REWIND
	SETOM	TU7HDN(P3)	;INDICATE UNKNOWN DENSITY
ANLY11:	SOS	(P)		;NON-SKIP RETURN (FORGET IT)
	SETZ	P4,		;PHYRWD WIPES OUT P4
	RET			;GO AWAY

;HERE TO DO AN EXTENDED SENSE
ANLY12:	MOVEM	Q1,TU7SNS(P3)	;SAVE UPDATED BITS
	MOVEI	T2,TM8XCW(P2)	;SORRY ABOUT THAT, BUT I CAN'T CONVINCE
	MAP	T2,(T2)		;PHYH2 TO DO THE RIGHT THING
	TLZ	T2,777760	;MAKE ICWA=JUMP KDB
	TLO	T2,200000
	HRRZ	T1,CDBICP(P1)	;ICWA
	EXCH	T2,(T1)		;STORE JUMP, PICK UP WHAT WAS THERE
	MOVEM	T2,TM8SCW(P2)	;SAVE REAL ICWA
	MOVEI	T2,TM8XSN(P2)	;POINT AT EXTENDED SENSE BLOCK
	MAP	T2,(T2)		;GET THE REAL LOC
	TLZ	T2,777760
	TLO	T2,(6B2!17B13)	;MUNGE UP AN IOWD TO READ EXTENDED SENSE
	MOVEM	T2,TM8XCW(P2)	;SAVE IN KDB
	MOVX	T2,.DOFMT	;TELL THE HDWRE WHAT DRIVE
	HRR	T2,UDBSLV(P3)
	TRO	T2,DO.RC1	;ONLY 1 RECORD
	MOVEI	Q1,DF.XSN!ERSTRY;FUNCTION IS EXTENDED SENSE, CCW ALREADY SET
	SOS	(P)		;GIVE NON-SKIP (ANOTHER INTERRUPT COMING)
	PUSH	P,CDBICR(P1)	;SAVE INITIAL CONTROL REGISTER
	CALL	TM8SI5		;CRANK UP THE EXTENDED SENSE
	  JFCL
	POP	P,CDBICR(P1)	;RESTORE WHAT WE WERE DOING BEFORE THE SENSE
	RETSKP			;AND RETURN
;HERE ON A REWIND STARTED INTERRUPT
INTRWP:	MOVX	T1,US.REW	;TELL THE WORLD
	IORM	T1,UDBSTS(P3)	;THAT THE DRIVE IS REWINDING
	SETZB	Q1,SAVFNC(P2)	;INDICATE WE AREN'T DOING ANYTHING TO DRIVE
	CALLRET	SETIRB		;SET UP P4 AND RETURN


;HERE WHEN A DRIVE COMES ON-LINE
INTONL:	CALL	PHYONL		;TELL THE WORLD THE DRIVE IS BACK
	CALL	ATDONE		;CLEAR THE ATTENTION BIT
	MOVEI	Q1,DF.SNS	;START A SENSE TO SEE IF WRITE-LOCKED
	SETZ	P4,		;TELL PHYSIO TO FORGET THE INTERRUPT
	SOS	(P)
	CALLRET	SENSE		;START THE SENSE AND RETURN

;HERE WHEN A DRIVE IS (OR GOES) OFF-LINE
INTOFL:	CALL	PHYOFL		;TELL THE WORLD
	HRRI	Q3,(IS.ERR!IS.DVE) ;LIGHT SOME ERRORS
	JRST	ANLYZ7		;AND RETURN

;HERE ON A TU FAULT/TM FAULT INTERRUPT
CLRTM:	CALL	TM8ZAP		;RESET THE TM78
	MOVE	T1,SAVLSI(P2)	;GET INTERRUPT CODE
	BUG(TM8AEI,<<T1,ICODE>>);LET THE WORLD KNOW
	SETZ	P4,		;TELL PHYSIO THIS ISNT THE LAST INTERRUPT
	SKIPN	P3,SAVUDB(P2)	;WERE WE WORKING ON A DRIVE?
	JRST	CLRTM1		;NO, NOTHING TO RESTART
	MOVE	Q1,UDBSTS(P3)	;YES, GET STATUS
	TXNN	Q1,US.ACT	;IS IT GOING?
	JRST	CLRTM1		;NO, DON'T TRY TO RESTART
	CALL	SETIRB		;YES, SET UP P4 POINTING AT IORB
	TXNN	Q1,US.POS	;DOING A DATA OPERATION?
	JRST	TM8SIO		;YES, GO RETRY THE OPERATION
	MOVE	Q3,NRTERV	;POSITION - CALL IT A HARD DEVICE ERROR
	RETSKP

;HERE IF NOTHING IS HAPPENING
CLRTM1:	AOS	T1,TM8ACT(P2)	;BUMP ASYNC INTERRUPT COUNT
	CAIG	T1,TM8AMX	;TOO MANY?
	RET			;NO
	CALL	SETHLD		;YES, SET HOLD (STOP MICROCODE) TO PREVENT
	 JFCL			; TM78 FROM CLOGGING ERROR FILE
	SETOM	TM8ACT(P2)	;INDICATE THE TM IS STOPPED
	RET			;AND RETURN, IGNORING INTERRUPT
;HERE ON A REREAD OPPOSITE INTERRUPT
INTRRO:	CALL	SETIRB		;POINT P4 AT IORB
	MOVX	T2,.DOBC	;READ BYTE COUNT THE TM78 THINKS IS THE LENGTH
	CALL	RDREG3		; (MIGHT HAVE CHANGED SINCE LAST RETRY)
	JUMPN	T1,INTRR2	;DID THE TM78 RETURN A BYTE COUNT OF 0?
INTRR1:	MOVE	Q3,NRTERD	;YES, HERE IS WHERE WE GIVE UP
	JRST	TM8RDR		;READ REGISTERS AND CALL IT A DAY
INTRR2:	LOAD	T3,IRBDM,(P4)	;NO, A REAL BYTE COUNT
	HLRZ	T3,MODTBL(T3)	;CONVERT TO WORDS
	IDIVI	T1,(T3)
	JUMPN	T2,INTRR1	;CANT RETRY IF NON-INTEGRAL NO OF WORDS
	MOVEM	T1,IRBCNT(P4)	;SAVE CORRECTED BYTE COUNT FOR RETRY
	MOVE	T2,T1		;WORDCOUNT WHERE REVCCW WANTS IT
	CALL	REVCCW		;SET UP TO READ REVERSE
	MOVEM	T1,TU7RRO(P3)	;SAVE ORIGINAL IOWD WHICH REVCCW CHANGED
INTRR3:	HRRI	Q3,(IS.ERR!IS.DTE) ;TELL ANLYZE THAT THERE IS AN ERROR
	JRST	ANLYZ7		;AND CARRY ON
;ERROR RETRY ENTRY POINT
;P1=CDB  P2=KDB  P3=UDB  RETURNS Q1=ERROR BLOCK ADDRESS
;NON-SKIP RETURN - ERROR RETRY IN PROGRESS
;SKIP - WE'RE DONE WITH IT (FOR BETTER OR WORSE)
TM8ERR:	SKIPGE	UDBSTS(P3)	;DRIVE NOW OFF-LINE?
	RETSKP			;YES, FORGET ERROR RECOVERY
	MOVE	T1,TU7ECD(P3)	;EXTRA ERROR FLAGS
	TLNN	T1,-1		;AFTER RH20 ERROR?
	JUMPN	T1,R		;YES, RETURN (A SENSE IS CURRENTLY IN PROGRESS)
	SAVEQ
	CALL	SETIRB		;GET OUR IORB
	HRRZ	Q1,UDBERP(P3)	;GET ERROR BLOCK IF PRESENT
	HLLZ	T1,IRBSTS(P4)	;GET IORB STATUS
	LOAD	T2,ISFCN,(P4)	;GET ORIGINAL FUNCT FROM IORB
	MOVE	T4,FNCTBL(T2)	;GET TABLE ENTRY
	TXNE	T4,TB.DAT	;NON-DATA OPERATIONS ARE RECOVERED BY TM78
	TXNE	T1,IS.NRT!IS.IER ;FATAL OR INHIBIT ERR RECOVERY?
	JRST	TM8NRB		;GIVE-UP RETURN
	SKIPN	T1,TU7ECD(P3)	;NO, RETRY THE ERROR. GET FAILURE BITS
	JRST	TM8RCV		;RECOVERED THE ERROR!
	AOS	T3,UDBERC(P3)	;COUNT A FAILED RETRY
	CAILE	T3,RTYOP	;TRIED ENOUGH?
	JRST	TM8NRC		;YES, NON-RECOVERABLE
	SOJN	T3,TM8ER1	;GO IF NOT 1ST RETRY
	PUSH	P,T1		;1ST - SET ERROR BLOCK
	CALL	BEGLOD
	POP	P,T1
	LOAD	T2,ISFCN,(P4)	;GET ORIGINAL FUNCT FROM IORB
TM8ER1:	SKIPE	TU7RRO(P3)	;REREADING IN OPPOSITE DIRECTION?
	TRC	T2,IRFRED!IRFRDR ;YES, REVERSE SENSE OF ORIGINAL READ
	TXON	T1,IC.SNM!IC.PAD ;NEED A REPOSITON?
	MOVEI	T2,IRFBSB	;YES, BACK UP 1 BLOCK
	MOVEM	T2,UDBERR(P3)	;SAVE ERROR FNCN
	MOVEM	T1,TU7ECD(P3)
	CALL	TM8SIO		;GO RETRY
	  JRST	TM8NRC
	RET			;RETRY STARTED, WAIT FOR NEXT INTERRUPT
;HERE ON A RECOVERED ERROR
TM8RCV:	MOVX	T1,IS.ERR	;CLEAR THE ERROR BIT FROM THE IORB
	ANDCAM	T1,IRBSTS(P4)
	TXNE	T4,TB.WRT
	AOSA	UDBSWE(P3)	;COUNT A SOFT ERROR
	AOS	UDBSRE(P3)
	JRST	TM8NRD		;SET END OF ERROR BLOCK AND RETURN

;HERE WHEN THE RETRY FAILED
TM8NRB:	SKIPN	UDBERC(P3)	;HAVE WE DONE ANY RETRIES?
	CALL	BEGLOD		;NO, SET UP 1ST PART OF ERROR BLOCK

TM8NRC:	TXNE	T4,TB.WRT
	AOSA	UDBHWE(P3)	;COUNT A HARD ERROR
	AOS	UDBHRE(P3)
TM8NRD:	CALL	ENDLOD		;SET UP END OF ERROR BLOCK
	SETZM	TU7RRO(P3)	;CLEAN UP FLAGS
	RETSKP			;AND TELL PHYSIO WE'RE DONE
;HERE AFTER AN RH20-DETECTED ERROR, THE TM78 THINKS EVERYTHING IS FINE
TM8RDH:	HRRZM	P,TU7ECD(P3)	;SET LH(TU7ECD) NON-0
	MOVX	T1,IS.ERR	;INDICATE AN ERROR
	IORM	T1,IRBSTS(P4)
				;FALL INTO TM8RDR

;ROUTINE TO READ ALL TM78 REGISTERS INTO TM8REG IN THE KDB
TM8RDR:	CALL	RDREGS		;READ DRIVE REGISTERS (EXCEPT 7-10)
	TXO	Q1,TB.RRG	;INDICATE WHY WE'RE DOING THE SENSE
	MOVEM	Q3,TU7ESD(P3)	;SAVE ERROR BITS FOR WHEN SENSE FINISHES
	SOS	(P)		;SENSE GIVES A SKIP-RETURN
	CALLRET	SENSE		;DO A SENSE SO WE CAN READ REGS 7 - 10


;ROUTINE TO READ REGISTERS ON ERROR
RDREGS:	CALL	ERRCNI		;GET CONI AND DATAI
	MOVEM	T1,TM8CNI(P2)	;SAVE IN KDB
	MOVEM	T2,TM8CS1(P2)
	MOVEM	T3,TM8DBF(P2)
	MOVEI	T4,TM8REG(P2)	;WHERE TO READ
	HRLI	T4,-22		;READ ALL REGISTERS
	SETZ	T2,		; STARTING AT 0
RDREG1:	CALL	RDREG3
	MOVEM	T1,(T4)		;STORE DATA IN UDB
	ADD	T2,[010000,,0]	;SET FOR NEXT REGISTER
	AOBJN	T4,RDREG1
	RET


;HERE AFTER SENSE COMPLETES WHICH WAS DONE TO READ REGS 7-10
RDREG2:	MOVSI	T1,TM8XSN(P2)	;ZERO THE EXTENDED SENSE AREA
	HRRI	T1,TM8XSN+1(P2)	; IN CASE WE DON'T DO AN EXTENDED SENSE
	SETZM	TM8XSN(P2)	; OR THERE IS AN ERROR IN THAT TRANSFER
	BLT	T1,TM8XSN+16(P2)
	MOVEI	T4,TM8REG+7(P2)
	HRLI	T4,-3		;AOBJN WORD FOR REGS TO READ
	MOVSI	T2,070000	;STARTING REGISTER TO READ
	CALLRET	RDREG1		;GO READ 3 REGISTERS

;HERE TO READ REGISTERS AFTER A SUCCESSFUL RETRY
RDREG4:	PUSH	P,TM8REG+7(P2)	;SINCE WE CAN'T READ 7-10 WITHOUT SOME HAIR,
	PUSH	P,TM8REG+10(P2)	; AND THEY WON'T BE CHANGING
	PUSH	P,TM8REG+11(P2)	; SAVE THEM
	CALL	RDREGS		;READ ALL 22 REGISTERS
	POP	P,TM8REG+11(P2)	;RESTORE THE SAVED ONES
	POP	P,TM8REG+10(P2)
	POP	P,TM8REG+7(P2)
	RET			; AND RETURN
;SUBROUTINE TO LOAD THE ERROR BLOCK AT START OF ERROR
;ENTER WITH Q1 POINTING AT ERROR BLOCK
BEGLOD:	JUMPE	Q1,R		;IF NO ERROR BLOCK, PUNT
	MOVE	T1,Q1		;COPY ERROR BLOCK
	MOVE	T2,[-NITAB,,ITAB] ;POINTER TO INFORMATION TABLE
	CALL	SEBCPY		;COPY INFORMATION
	 JFCL
	MOVS	T1,UDBPS1(P3)	;GET FILE 
	HRR	T1,UDBPS2(P3)	;AND RECORD (JUST AFTER ERROR)
	MOVEM	T1,SEBDAT+MB%LOC(Q1) ;AND SAVE AS LOCATION OF ERROR
	MOVSI	T1,TM8REG(P2)	;WHERE TO GET REGS
	HRRI	T1,SEBDAT+MB%REG(Q1) ;WHERE TO STORE THEM
	BLT	T1,SEBDAT+MB%REG+TM8ELN-1(Q1) ;STUFF INTO ERROR BLOCK
	RET


;SUBROUTINE TO LOAD ERROR BLOCK AT END OF ERROR
ENDLOD:	JUMPE	Q1,R		;IF NO ERROR BLOCK, CANT SAVE DATA
	MOVE	T3,[-22,,TM8REG] ;WHERE TO START
	ADDI	T3,(P2)		;RELOCATE INTO THIS KDB
	MOVEI	T2,SEBDAT+MB%REG(Q1) ;REGISTER DATA GOES HERE
ENDLO1:	MOVE	T1,(T3)		;GET REGISTER
	HRLM	T1,(T2)		;PUT IT
	ADDI	T2,1
	AOBJN	T3,ENDLO1	;DONE?
	MOVE	T1,TM8CNI(P2)	;GET CONI
	MOVEM	T1,SEBDAT+MB%CIF(Q1) ;SAVE
	MOVE	T1,TM8CS1(P2)	;GET TCR
	MOVEM	T1,SEBDAT+MB%D1F(Q1) ;SAVE
	MOVE	T1,TM8DBF(P2)	;GET BAR
	MOVEM	T1,SEBDAT+MB%D2F(Q1) ;SAVE
	RET


;TABLE OF ITEMS TO COPY INTO ERROR BLOCK

ITAB:	SEBPTR	MB%CS0,SBTWD,CDBCS0(P1)	;CHANNEL STATUS 0
	SEBPTR	MB%CS1,SBTWD,CDBCS1(P1)	;CHANNEL STATUS 1
	SEBPTR	MB%CS2,SBTWD,CDBCS2(P1)	;CHANNEL STATUS 2
	SEBPTR	MB%CC1,SBTWD,CDBCC1(P1)	;CCW 1
	SEBPTR	MB%CC2,SBTWD,CDBCC2(P1)	;CCW 2
	SEBPTR	MB%ICR,SBTWD,CDBICR(P1)	;INITIAL CONTROL REGISTER
	SEBPTR	MB%CNI,SBTWD,TM8CNI(P2)	;CONI INITIAL
	SEBPTR	MB%D1I,SBTWD,TM8CS1(P2)	;TCR
	SEBPTR	MB%D2I,SBTWD,TM8DBF(P2)	;BAR/DBF

NITAB==.-ITAB
	SUBTTL	TM78 INITIALIZING ROUTINE
;THIS ROUTINE IS CALLED ONCE PER TM78 DRIVE ON THE SYSTEM
;SET UP UDB'S - 1 PER DRIVE ON THE TM78
;INPUT  C(P1)=CDB  C(Q2)=UNIT NR; OUTPUT P2,P3
TM8INI:	SAVEQ			;SAVE REGISTERS
	CALL	TM8ZAP		;RESET CONTROLLER
	MOVX	T1,LK.TM8	;LENGTH OF KDB
	CALL	PHYALC		;RESERVE SPACE
	RET			;RETURN IF NO SPACE FOUND
	MOVEM	T1,P2		;SAVE ADDRESS IN PROPER AC
	MOVE	P3,T1		;COPY KDB
	MOVEI	T1,.BTKDB	;MARK AS KDB
	DPB	T1,USYBKT	; ...
	MOVX	T1,.UTTM7	;YES - SET UP UNIT TYPE IN KDB
	STOR	T1,USTYP,(P2)	;...
UNINI:	MOVSI	Q1,-TM8SLC	;SET UP AOBJN INDEX LH
	HRRI	Q1,KDBUDB(P2)	;MAKE RH POINT TO UDB ENTRIES IN KDB
	MOVEM	Q1,KDBIUN(P2)	;INITIAL POINTER
	MOVEM	Q1,KDBCUN(P2)	;CURRENT POINTER
	HRRZM	Q2,TM8ADR(P2)	;SAVE KDB ADDRESS
	MOVEI	T1,TM8DSP	;INSERT DISPATCH VECTOR
	MOVEM	T1,KDBDSP(P2)	; ...
	CALL	SETHLD		;SET HOLD IN TM78
	 JRST	UNINF		;WOULDN'T SET
	MOVEI	Q1,TM8REV(P2)	;POINT AT KDB
	HRLI	Q1,441100	;MAKE A BYTE POINTER
	MOVE	Q3,[.DOIA!3776]	;POINT AT LOC FOR 1ST ROM REV LEVEL
UNINE:	MOVE	T2,Q3
	CALL	WTREG3		;LOC WE WANT TO READ
	MOVSI	T2,(.DOTMS)
	CALL	RDREG3		;READ THE LOCATION
	ANDI	T1,377		;ONLY 8 BITS ARE OF INTEREST
	IDPB	T1,Q1		;SAVE IN ..U?0 UDB
	ADDI	Q3,4000		;STEP TO NEXT REV LEVEL LOC
	TRNN	Q3,40000
	JRST	UNINE		;GO READ IT
	CALL	CLRHLD		;CLEAR HOLD IN TM
UNINF:	MOVSI	Q3,1		;WAIT FOR TM READY TO GO BACK ON
UNING:	MOVX	T2,.DOTMS
	CALL	RDREG3		;BEFORE WE TRY TO TALK TO CONTROLLER AGAIN
	TRNN	T1,DI.TMR
	SOJG	Q3,UNING
	MOVSI	Q1,-TM8SLC
INILP:	HRRZ	T2,Q1		;DRIVE NUMBER
	ADDI	T2,DR.ND0	;REGISTER TO TALK TO FOR THIS DRIVE
	ROT	T2,-6		;WHERE IT WILL DO THE MOST GOOD
	HRRI	T2,DF.SNS	;SET UP A SENSE FOR THIS DRIVE
	CALL	WTREG3
	MOVSI	Q3,1		;SET UP A COUNTER
INIL1:	HRLI	T2,(.DOAS)	;READ ATTENTION SUMMARY
	CALL	RDREG3		;AND LOOK FOR US
	MOVEI	T2,1		;GET INTO RIGHT POSITION
	LSH	T2,0(Q2)
	TRNN	T1,0(T2)	;CHECK FOR THIS BIT
	JRST	INIL3		;NO WAIT SOME MORE
	MOVX	T2,.DOICN	;READ NON-DATA STATUS
	CALL	RDREG3
	LDB	T2,[POINT 3,T1,27]	;GET DRIVE NUMBER
	CAIN	T2,0(Q1)	;CORRECT DRIVE?
	JRST	INIU1		;YUP SEE WHAT WE GOT BACK
	CALL	CLRATN
INIL3:	SOJG	Q3,INIL1	;GO TRY AGAIN
	BUG(TM8SNS)
	JRST	NODRV		;FORGET THIS DRIVE

INIU1:	CALL	INIUNI		;INITIALIZE A SINGLE UNIT
NODRV:	AOBJN	Q1,INILP	;TRY NEXT SLAVE
TOORET:	CALL	CLRATN
	MOVE	T1,P2		;TELL RETURN TO PUT KDB INTO CDB
	RET

;SUBROUTINE TO SET HOLD IN TM78
;NON-SKIP RETURN IF HOLD WOULDN'T SET
;SKIP RETURN NORMALLY
SETHLD:	MOVE	T2,[.DOIA!3776]	;POINT INTERNAL ADDR AT A READ-ONLY LOCATION
	CALL	WTREG3		;IN CASE TM78 DECIDES TO WRITE WHEN HOLD SETS
	MOVE	T2,[.DOTMS!DO.HLD]
	CALL	WTREG3		;SET HOLD SO WE CAN READ REV LEVELS
	MOVEI	Q3,40000	;HOW LONG TO WAIT
SETHL1:	MOVSI	T2,(.DOTMS)	;READ STATUS
	CALL	RDREG3
	TRNN	T1,DO.HLA	;HOLD ACKNOWLEDGED?
	SOJG	Q3,SETHL1
	JUMPE	Q3,R		;LOSE IF IT STILL DIDNT SET
	RETSKP			;HOLD IS SET - SKIP RETURN

;SUBROUTINE TO CLEAR HOLD IN TM78
;ALWAYS RETURNS TO CALL+1
CLRHLD:	MOVSI	T2,(.DOTMS)
	CALL	WTREG3		;CLEAR HOLD
	MOVE	T2,[.DOTMS!DO.TMC]
	CALLRET	WTREG3		;CLEAR POSSIBLE ERROR AND RETURN
;THIS ROUTINE IS CALLED TO INITIALIZE A SPECIFIC SLAVE
;INPUT C(P1)=CDB  C(Q1)=UNIT C(P2)KDB  NR; OUTPUT P3
INIUNI:	SAVEQ
	MOVX	T2,.DOSR	;READ THE STATUS REGISTER
	CALL	RDREG3
	TXNN	T1,DI.AVL+DI.MNT ;AVAILABLE OR MAINTEANCE MODE?
	JRST	CLRATN		;NO, DRIVE DOESN'T EXIST
	HRLOI	T3,-MTAN-1	;YES. DRIVE IS THERE. FIND SLOT TO SAVE IT
INIUN1:	AOBJP	T3, [BUG(TM8N2S)
		JRST TOORET]	;DON'T INITIALIZE ANY MORE SLAVES
	SKIPE	MTCUTB(T3)	;CHECK TO SEE IF UNIT FREE
	JRST	INIUN1		;NOPE TRY NEXT ONE
	MOVEM	T3,MTINDX	;SAVE CURRENT LOGICAL INDEX
	MOVE	T3,[TM8DSP,,LU.TM8]	;YES, SET UP ADDRESS,,LENGTH
	ADDI	P2,(Q1)		;POINT TO PROPER KDB ENTRY
	CALL	PHYUDB		;AND ASK FOR UDB ALLOCATION
	  JRST	CLRATN		;RETURN IF NO SPACE FOUND
	HRRZM	P3,KDBUDB(P2)	;SAVE LINK
	SUBI	P2,(Q1)		;FUDGE IT BACK
	HRRZM	P2,UDBKDB(P3)	;SAVE BKWDS LINK
	MOVE	T3,MTINDX	;GET CURRENT LOGICAL INDEX
	HRLZM	P1,MTCUTB(T3)	;SAVE LINK TO CDB IN LOGICAL TABLE
	HRRM	P3,MTCUTB(T3)	;SAVE LINK TO UDB
	MOVX	T2,.DOSR	;GET DRIVE STATUS AGAIN
	CALL	RDREG3
	MOVX	T3,US.TAP	;INDICATE A TAPE TYPE DEVICE
	TXNN	T1,DI.RDY	;ON LINE?
	TXO	T3,US.OFS	;NO, SET OFF LINE BIT
	TXNE	T1,DI.FPT	;WRITE LOCKED?
	TXO	T3,US.WLK	;YES
	HLLM	T3,UDBSTS(P3)	;SAVE UDB STATUS
	MOVX	T3,.UTT78	;UNIT TYPE
	STOR	T3,USTYP,(P3)	;SAVE IT
	MOVX	T1,UC.160!UC.625!UC.CD!UC.IC!UC.HD	;SET CHARACTERISTICS
	MOVEM	T1,UDBCHR(P3)
	MOVX	T2,.DOSN	;NOW SERIAL NR
	CALL	RDREG3
	CALL	PHCVBO		;CONVERT TO OCTAL
	MOVEM	T1,UDBDSN(P3)	;STORE IT
	MOVSI	T1,DR.ND0(Q1)	;SET UP UDBSLV = REG TO WRITE,,NUMBER
	LSH	T1,^D12		;PUT REGISTER WHERE IT WILL DO THE MOST GOOD
	HRRI	T1,(Q1)
	MOVEM	T1,UDBSLV(P3)	;SET UP SLAVE ADDRESS
	AOS	JB0FLG		;THIS WILL REQUEST JOB0 INCASE CALLER SETS MTAJB0

CLRATN:	MOVEI	T2,1		;CLEAR DRIVE ATTENTION
	LSH	T2,0(Q2)
	HRLI	T2,(.DOAS)	;ATTENTION SUMMARY
	CALLRET	WTREG3
;TABLES TO CONTROL IO 
TB.DAT==1B0
TB.WRT==1B1
TB.REV==1B2
TB.SPC==1B3
TB.RD==1B4
TB.ERA==1B5
TB.WTM==1B6
TB.REW==1B7
TB.RRG==1B8	;NOT IN TABLE, LIGHTS ON SENSE FROM RDREG
TB.XSN==1B9	;NOT IN TABLE, LIGHTS AFTER SENSE IF WE DO EXTENDED SENSE

FNCTBL:	0				;0 - ILLEGAL
	TB.DAT!TB.RD!DF.RED!1B17	;1 - READ FORWARD
	0				;2 - ILLEGAL (READ FMT)
	TB.WRT!TB.DAT!DF.WRT!3B17	;3 - WRITE
	0				;4 -ILLEGAL (WRITE FMT)
	0				;5 - ILLEGAL (SEEK)
	TB.SPC!DF.SPF!6B17		;6 - SKIP RECORD
	TB.SPC!TB.REV!DF.SPR!7B17	;7 - BACKSPACE RECORD
	TB.WRT!TB.WTM!DF.WTM!10B17	;10 - WRITE TAPE MARK
	TB.WRT!TB.ERA!DF.ERG!11B17	;11 - ERASE
REWFNC:	TB.REW!TB.REV!DF.REW!12B17	;12 - REWIND
UNLFNC:	DF.UNL!13B17			;13 - REW, UNLOAD
	TB.DAT!TB.RD!TB.REV!DF.RRV!14B17 ;14 - READ REVERSE
	0				;15-ILLEGAL (RECOVERY READ)
	0				;16 - ILLEGAL
	0				;17 - ILLEGAL

	WT.GCR==2			;TURN WRITE PE INTO WRITE GCR

;FRAMES/WORD,,MODE BITS
MODTBL:	-1			;0 - ILLEGAL
	5,,30000		;1 - CORE DUMP
	-1			;2 - SIXBIT
	-1			;3 - 7 BIT (ASCII)
	1,,20000		;4 - INDUSTRY COMPAT
	1,,40000		;5 - HIGH DENSITY
MAXMOD==.-MODTBL-1


;DENSITY CODE TABLE
DENTBL:	-1			;0 - ILLEGAL
	-1			;1 - 200 BPI
	-1			;2 - 556 BPI
	-1			;3 - 800 BPI
	0			;4 - 1600 BPI
	WT.GCR			;5 - 6250 BPI
MAXDEN==.-DENTBL-1
IC.RRG==1B0			;READ REGISTERS
IC.BST==1B1			;SET A BIT IN TKBSTS
IC.DSP==1B2			;DISPATCH TO AN ADDRESS
IC.ASY==1B3			;ASYNCH EVENT (RETURN 0 TO TAPSER)
IC.XSN==1B4			;DO AN EXTENDED SENSE TO GET MORE INFO
IC.SNM==1B5			;NO TAPE MOTION
IC.PAD==1B6			;REPOSITION ALREADY DONE (SER=0)


ICDTBL:	IC.BST!(IS.NRT!IS.ERR)	;0 - UNDEFINED
	0			;1 - DONE
	IC.BST!(IS.TPM)		;2 - UNEXPECTED TAPE MARK
	IC.BST!(IS.TPM!IS.BOT)	;3 - UNEXPECTED BOT
	IC.BST!(IS.EOT)		;4 - END OF TAPE
	IC.BST!(IS.TPM)		;5 - UNEXPECTED LOGICAL EOT
	IC.BST!(IS.NRT)		;6 - NO OP COMPLETED
	IC.DSP!INTRWP		;7 - REWIND IN PROGRESS
	IC.BST!IC.SNM!(IS.WLK!IS.ERR!IS.NRT) ;10 - WRITE TO A WRITE-LOCKED TAPE
	IC.DSP!INTOFL!IC.BST	;11 - NOT READY
	IC.DSP!INTOFL!IC.BST	;12 - DRIVE NOT AVAILABLE (ON OTHER PORT)
	IC.DSP!INTOFL!IC.BST	;13 - OFF LINE
	IC.DSP!INTOFL!IC.BST	;14 - NON-EXISTENT DRIVE
	IC.BST!IC.RRG!(IS.DVE!IS.ERR!IS.NRT) ;15 - NOT CAPABLE
	IC.BST!IC.RRG!(IS.ERR!IS.NRT) ;16 - UNDEFINED
	IC.ASY!IC.DSP!INTONL	;17 - DRIVE HAS COME ON LINE
	IC.BST!IC.RRG!(IS.ERR!IS.NRT!IS.RTL) ;20 - LONG RECORD
	0			;21 - SHORT RECORD
	IC.BST!IC.RRG!IC.XSN!IC.PAD!(IS.ERR!IS.DTE)	;22 - RETRY THE INITIAL OPERATION
	IC.DSP!INTRRO!IC.PAD!IC.BST	;23 - REREAD OPPOSITE
NRTERD:	IC.BST!IC.RRG!IC.XSN!(IS.NRT!IS.DTE) ;24 - UNREADABLE
	IC.BST!IC.RRG!IC.XSN!(IS.ERR!IS.NRT) ;25 - ERROR, SER IS SET
	IC.BST!IC.RRG!IC.XSN!(IS.ERR!IS.NRT) ;26 - ERROR AFTER EOT, SER IS SET
	IC.BST!IC.RRG!IC.XSN!(IS.ERR!IS.NRT!IS.DVE) ;27 - BAD TAPE
NRTERV:	IC.BST!IC.RRG!IC.XSN!(IS.ERR!IS.DVE)	;30 - TM FAULT A
	IC.BST!IC.RRG!IC.XSN!(IS.ERR!IS.DVE)	;31 - TU FAULT A
	IC.ASY!IC.DSP!CLRTM			;32 - TM FAULT B
ICDND1==.-ICDTBL-1
	IC.ASY!IC.DSP!CLRTM!IC.RRG!IC.XSN	;33 - TU FAULT B
	IC.ASY!IC.DSP!CLRTM			;34 - MASSBUS FAULT
ICDND2==.-ICDTBL-1
MAXICD==.-ICDTBL-1
REVERR==23
	END