Google
 

Trailing-Edge - PDP-10 Archives - BB-H311D-RM - monitor-sources/phym78.mac
There are 27 other files named phym78.mac in the archive. Click here to see a list.
; UPD ID= 4824, SNARK:<6.MONITOR>PHYM78.MAC.27,  17-Sep-84 10:43:15 by PURRETTA
;Update copyright notice
; UPD ID= 4646, SNARK:<6.MONITOR>PHYM78.MAC.26,   2-Aug-84 11:12:29 by HAUDEL
;TCO 6.2159 - CHANGE THE INTERRUPT DISPATCHING AC, THAT IS SET UP FROM ICDTBL,
;TO BA A LOCAL INDEX AND NOT A GLOBAL ONE. INTRRO NEEDS THIS.
; UPD ID= 4614, SNARK:<6.MONITOR>PHYM78.MAC.25,  27-Jul-84 15:28:13 by HAUDEL
;TCO 6.2145 - PREVENT NOIORB FROM SPURIOUS REW INTERRUPT.
; UPD ID= 4600, SNARK:<6.MONITOR>PHYM78.MAC.24,  27-Jul-84 08:09:26 by HAUDEL
;TCO 6.2127 - ADD DATA ITEMS TO TM8AEI BUGCHK
; UPD ID= 4392, SNARK:<6.MONITOR>PHYM78.MAC.23,  27-Jun-84 12:10:04 by HAUDEL
;TCO 6.2019 - INCREMENT UDBPS2 WHEN WRITING A TM. THIS IS FOR LABELLED TAPES.
; UPD ID= 3659, SNARK:<6.MONITOR>PHYM78.MAC.22,   7-Feb-84 14:55:09 by HAUDEL
;More TCO 6.1818 - ADJUST CODE FOR SECTION 1 OPERATION.
; UPD ID= 3398, SNARK:<6.MONITOR>PHYM78.MAC.21,   3-Jan-84 11:42:26 by HAUDEL
;More TCO 6.1794 - Change REVLEV bugchk to buginf
; UPD ID= 3109, SNARK:<6.MONITOR>PHYM78.MAC.20,   7-Nov-83 21:24:02 by MCLEAN
;ADD PORT RELEASE DISPATCH
; UPD ID= 3020, SNARK:<6.MONITOR>PHYM78.MAC.19,  10-Oct-83 16:21:42 by MURPHY
;Clean up format.
; UPD ID= 3003, SNARK:<6.MONITOR>PHYM78.MAC.18,   5-Oct-83 20:13:19 by MCLEAN
;TCO 6.1818 RE-ADJUST CODE FOR SECTION 1 OPERATION
; UPD ID= 2928, SNARK:<6.MONITOR>PHYM78.MAC.17,  23-Sep-83 11:40:28 by HAUDEL
;TCO 6.1794 - Add REVLEV bugchk and make a 31 class error fatal.
; UPD ID= 2898, SNARK:<6.MONITOR>PHYM78.MAC.16,  16-Sep-83 14:37:50 by HAUDEL
;TCO 6.1757 - Save T4 in BEGLOD before call to SEBCPY
; UPD ID= 2615, SNARK:<6.MONITOR>PHYM78.MAC.15,  21-Jun-83 13:10:49 by HAUDEL
;TCO 6.1697 - Reset SAVFNC in TM8HNG code.
; UPD ID= 2614, SNARK:<6.MONITOR>PHYM78.MAC.14,  21-Jun-83 13:01:47 by HAUDEL
;TCO 6.1696 - Do not set KDBACT on SENSE operation after online interupt
; UPD ID= 2613, SNARK:<6.MONITOR>PHYM78.MAC.13,  21-Jun-83 12:32:25 by HAUDEL
;TCO 6.1695 - Add SOS (P) to Reread Opposite code
; UPD ID= 2579, SNARK:<6.MONITOR>PHYM78.MAC.12,  14-Jun-83 09:53:00 by HAUDEL
;TCO 6.1668 - Add SAVEQ at TM8SI0
; UPD ID= 2416, SNARK:<6.MONITOR>PHYM78.MAC.11,   4-May-83 08:16:44 by HAUDEL
;TCO 6.1640 - Change code after TM8NUD  bugchk
; UPD ID= 1980, SNARK:<6.MONITOR>PHYM78.MAC.10,  11-Mar-83 15:56:19 by HAUDEL
;TCO 6.1539 - Change SAVUDB,KDBACT,SAVFNC so that SENSE works correctly
; UPD ID= 1946, SNARK:<6.MONITOR>PHYM78.MAC.9,   9-Mar-83 10:24:35 by HAUDEL
;TCO 6.1512 - Add code for high density format mode,fix TCO 6.1410
; UPD ID= 1719, SNARK:<6.MONITOR>PHYM78.MAC.8,  28-Jan-83 14:20:04 by DONAHUE
;TCO 6.1431 - Clear the interrupt if no UDB is found
; UPD ID= 1604, SNARK:<6.MONITOR>PHYM78.MAC.7,  29-Dec-82 13:47:38 by DONAHUE
;TCO 6.1410 - Change references to MTINDX to use STKVAR's
; UPD ID= 1115, SNARK:<6.MONITOR>PHYM78.MAC.6,  26-Aug-82 14:07:43 by HAUDEL
;TCO 5.1.1056 - Add code to set device online after TM78 power turned on.
; UPD ID= 1077, SNARK:<6.MONITOR>PHYM78.MAC.5,  11-Aug-82 09:25:27 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
; UPD ID= 965, SNARK:<6.MONITOR>PHYM78.MAC.4,  29-Jun-82 04:34:54 by WACHS

;TC0 5.1779 - Clear TU7ECD, TU7SNS before starting IO
;TCO 5.1778 - Inhibit error repositioning on last error retry
; UPD ID= 904, SNARK:<6.MONITOR>PHYM78.MAC.2,   9-Jun-82 23:25:34 by MURPHY
;TCO 6.1147 - Move bugdefs from BUGS.MAC to here and put them in-line.
; 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  BE  USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT  (C)  DIGITAL  EQUIPMENT  CORPORATION  1980, 1984.
;ALL RIGHTS RESERVED.


	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
	SAVFNC==TU7RRO+1	;CURRENT FUNCTION/FLAGS
	LU.TM8==SAVFNC+1	;LENGTH OF TM78 UDB

;****************************
;KDB DEVICE DEPENDENT PORTION
	TM8ADR==KDBDDP+4	;MASSBUS ADDRESS OF TM78
	SAVUDB==TM8ADR+1	;CURRENT UDB (0 IF NONE)
	SAVLSI==SAVUDB+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
	JRST TM8SI0		;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
	JRST TM8SI0		;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
	JRST R			;15 - PORT RELEASE (UNUSED)

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)
	SETZM  SAVFNC(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

TM8SI0:	SAVEQ
	SETZM TU7ECD(P3)	;MAKE SURE FLAGS ARE ZERO AT START
	SETZM TU7SNS(P3)

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 OFFLINE/ONLINE STATUS BIT
	ANDCAM T2,UDBSTS(P3)	;MAKE SURE DRIVE ISN'T 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(P3)	;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
	HRRZ T2,UDBSLV(P3)	;GET THE UNIT NUMBER
	TRO T2,DO.RC1(T4)	;SET 1 RECORD AND THE FORMAT
	MOVE T1,IRBSTS(P4)
	SKIPE T3,UDBERR(P3)	;IN ERROR RECOVERY?
	MOVE T3,UDBERC(P3)	;YES, GET RETRY COUNT
	CAIE T3,RTYOP		;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
	TRNN T4,40000		;IS MODE HIGH DENSITY?
	JRST TM8SI6		;NO.
	TRNE T2,1		;YES. IS WORD COUNT EVEN?
	JRST BADSIO		;NO.
	LSH T2,-1		;YES. MULTIPLY BY 9/2
TM8SI6:	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(P3)	;SAVE FUNCTION WE'RE DOING
	ANDI Q1,77
	HRRZM P3,SAVUDB(P2)	;SAVE ADDRESS ON DATA TRANSFER OPERATION
TM8SI5:	MOVE T3,SAVFNC(P3)	;GET THE FUNCTION
	ANDI T3,77		;MASK OUT ALL BITS BUT FUNCTION CODE BITS
	CAIE T3,DF.SNS		;IS FUNCTION A SENSE AFTER ONLINE?
	HRRZM P3,KDBACT(P2)	;NO. SAVE WHAT SLAVE WE'RE DOING IT TO
	JRST CHSTRT
BADSIO:	BUG.(CHK,PM8SIO,PHYM78,HARD,<PHYM78 - ILLEGAL FUNCTION AT START IO>,,<

Cause:	This bugchk can be caused by trying to write an odd number of
	words to a TU78 that is set for the high density mode. If
	T2 is odd, this is probably the cause. There is also an undocumented
	cause of this bugchk.

>)
	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,KDBACT(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
	CALLRET ATDONE		;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(P2)	; (WE OVERWROTE IT TO READ EXTENDED SENSE BYTES)
	MOVEM T2,(T1)
	SETZM TM8SCW(P2)	;THE WORLD IS NOW BACK TOGETHER
	MOVE Q2,TM8ADR(P2)	;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
	TRNE Q3,(IS.ERR)	;IF RECORD IS NOT IN ERROR,
	JRST TM8IN5		;ERROR. DO NOT ACCUMULATE
	ADDM T1,UDBRED(P3)	; ACCUMULATE FRAMES READ
	ADDM T1,UDBRPE(P5)	;ACCUMULATE FRAMES READ IN PE/GCR
TM8IN5:	LOAD T4,IRBDM,(P4)
	HLRZ T3,MODTBL(T4)	;COMPUTE WORDS READ
	SOJE T3,TM8IN3		;SAVE TIME IF BYTES=FRAMES
	CAIN T4,IRMHID		;IS MODE HIGH DENSITY?
	LSH T1,1		;YES. THEN MULTIPLY BY 2/9
	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 T4,IRBDM,(P4)	;YES, ACCUMULATE BYTES WRITTEN
	HLRZ T3,MODTBL(T4)
	IMUL T3,IRBCNT(P4)
	CAIN T4,IRMHID		;IS MODE HIGH DENSITY?
	LSH T3,-1		;YES. THEN DIVIDE BY 2
	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)
	SETZM SAVUDB(P2)
	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.(CHK,TM8NUD,PHYM78,HARD,<PHYM78 - CHANNEL DONE INTERRUPT BUT NO UNIT ACTIVE>,,<

Cause:	This BUG is not documented yet.

Action:

>)
	SETZ P4,
	RET			;SIGNIFY ERROR
;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(P3)	;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(P3)	;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
	HRRZ T1,Q3		;MASK OFF JUNK
	HLLM Q3,(T1)		;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
	TXNN Q3,IC.DSP		;DISPATCH ADDRESS?
	IFSKP.
	  HRRZ T4,Q3		;YES. SET UP LOCAL INDEX. (INTRRO NEEDS THIS).
	  JRST (T4)		;GO TO SUBROUTINE.
	ENDIF.
	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,KDBACT(P2)	;NO. HERE FOR THE "RIGHT" UNIT?
	SETZM KDBACT(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
	TXNE Q1,TB.WTM		;IS IT A TAPE MARK OPERATION?
	MOVEI T1,1		;YES. SET TO INCREMENT COUNT SO
				;THAT LABELLED TAPES WORK.
	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(P3)	;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:	HRRZ T1,UDBPWQ(P3)	;GET PWQ ENTRY.
	CAIN T1,0		;IS THERE AN IORB ON THE PWQ?
	JRST INTRW1		;NO. THEN THIS IS A SPURIOUS INTERRUPT.
	MOVX T1,US.REW		;TELL THE WORLD
	IORM T1,UDBSTS(P3)	;THAT THE DRIVE IS REWINDING
	SETZB Q1,SAVFNC(P3)	;INDICATE WE AREN'T DOING ANYTHING TO DRIVE
	CALLRET SETIRB		;SET UP P4 AND RETURN

				;HERE IF THERE IS A REW INTERRUPT
				;BUT THERE IS NO IORB ON THE PWQ.
INTRW1:	SOS (P)			;ADJUST STACK POINTER.
	SETZ P4,		;SET TO DISMISS INTERRUPT
	MOVE T2,CDBADR(P1)	;GET CHANNEL NUMBER
	MOVE T3,TM8ADR(P2)	;GET CONTROLLER NUMBER
	BUG.(INF,TM8REW,PHYM78,HARD,<PHYM78 -SPURIOUS REWIND INTERRUPT>,<<T2,CHANNEL>,<T3,CONTROLLER>>,<

Cause:	The TM78 gave a spurious rewind interrupt.

Action:	None. The TM78 has dismissed the interrupt. If persistent,
	notify field service.

Data:	T2 - CHANNEL NUMBER
	T3 - CONTROLLER NUMBER
>);LET THE WORLD KNOW
	RET			;GO DISMISS INTERRUPT


;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
	MOVE T2,CDBADR(P1)	;GET CHANNEL NUMBER
	MOVE T3,TM8ADR(P2)	;GET CONTROLLER NUMBER
	BUG.(INF,TM8AEI,PHYM78,HARD,<PHYM78 - ASYNCHRONOUS ERROR INTERRUPT>,<<T1,ICODE>,<T2,CHANNEL>,<T3,CONTROLLER>>,<

Cause:	The TM78 gave an asynchronous error interrupt.

Action:	None. The TM78 has been cleared and restarted.

Data:	ICODE/ The interrupt code associated with this interrupt
>);LET THE WORLD KNOW
	SETZ P4,		;TELL PHYSIO THIS ISNT THE LAST INTERRUPT
	SKIPN P3,KDBACT(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
	SOS  (P)		;ADJUST STACT POINTER FOR SKIP RETURN
	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
	PUSH P,T4		;SAVE, BECAUSE SEBCPY USES T4.
	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
	POP P,T4		;RESTORE T4
	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
				;START REVISION LEVEL CHECK.
	SETZM T4		;CLEAR T4 FOR USE AS A FLAG
	MOVEI Q1,TM8REV-1(P2)	;SET UP BYTE POINTER FOR ACTUAL LEVELS
	HRLI Q1,001100
	MOVEI Q3,MINREV-1	;SET UP BYTE POINTER FOR MINIMUM LEVELS NEEDED.
	HRLI Q3,001100
	MOVEI T3,10		;SET UP COUNTER TO CHECK 8. LEVELS.
REVCHK:	ILDB T1,Q1		;GET THE REVSION LEVEL NUMBERS.
	ILDB T2,Q3
	CAMGE T1,T2		;DO THE CHECK.
	AOS T4			;LEVEL DOES NOT MEET MINIMUM. SET FLAG.
	SOJG T3,REVCHK		;CHECK ALL LEVELS.
	JUMPE T4,REVCH1		;LEVELS MEET MINIMUM LEVELS REQUIRED.
	DMOVE T1,TM8REV(P2)	;SET UP FOR BUGCHK. GET ACTUAL LEVELS.
	DMOVE T3,MINREV		;GET MINIMUM LEVELS.
	BUG.(INF,REVLEV,PHYM78,SOFT,<TM78 Microcode is outdated>,<<T1,ACTUAL LEVELS>,<T2,ACTUAL LEVELS>,<T3,MINIMUM LEVELS>,<T4,MINIMUM LEVELS>>,<

Cause:	The TM78 does not have a microcode version that is needed by this
	monitor.

Action:	Have Field Service install the new microcode.

Data:	T1 and T2 have the actual revision levels in the TM78. T3 and T4
	have the levels that are required by this monitor.
>)

REVCH1:	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.(CHK,TM8SNS,PHYM78,HARD,<CAN'T SENSE TU78 STATUS>,,<

Cause:	This BUG is not documented yet.

Action:

>)
	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
	STKVAR <MTINDX>		;INDEX INTO MTCUTB
	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.(INF,TM8N2S,PHYM78,HARD,<PHYM78 - MORE DRIVES THAN TABLE SPACE, EXCESS IGNORED>,,<

Cause:	This BUG is not documented yet.

Action:

>)
		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
	11,,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)

MINREV:	6005,,6004		;MINIMUM TM78 REVISION LEVELS REQUIRED 
	2003,,10003

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.NRT!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

	TNXEND
	END