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