Trailing-Edge
-
PDP-10 Archives
-
BB-M780B-SM
-
monitor-sources/phyx2.mac
There are 47 other files named phyx2.mac in the archive. Click here to see a list.
; UPD ID= 444, SNARK:<5.MONITOR>PHYX2.MAC.13, 27-Jan-82 07:05:44 by WACHS
;TCO 5.1704 - set .UTT73 in UDB if drive is a TU73
; UPD ID= 260, SNARK:<5.MONITOR>PHYX2.MAC.12, 14-Oct-81 12:02:22 by WACHS
;TCO 5.1575 - check MTCUTB before storing in it
; UPD ID= 1904, SNARK:<5.MONITOR>PHYX2.MAC.11, 29-Apr-81 08:29:41 by WACHS
; UPD ID= 1901, SNARK:<5.MONITOR>PHYX2.MAC.10, 29-Apr-81 07:58:46 by WACHS
; UPD ID= 1872, SNARK:<5.MONITOR>PHYX2.MAC.9, 23-Apr-81 08:45:08 by UHLER
;TCO 5.1294 - Make the DX2FGS timer be 6000 to avoid problems on systems that
;share tape subsystems.
; UPD ID= 1860, SNARK:<5.MONITOR>PHYX2.MAC.8, 21-Apr-81 13:50:57 by SCHMITT
;TCO 5.1292 - Reset overdue timer before starting I/O when retrying
; UPD ID= 1823, SNARK:<5.MONITOR>PHYX2.MAC.7, 17-Apr-81 09:53:59 by WACHS
;TCO 5.1288 Maintain statistics by recording mode
; UPD ID= 1212, SNARK:<5.MONITOR>PHYX2.MAC.6, 31-Oct-80 07:08:45 by UHLER
;TCO 5.1184 - DON'T READ REGISTER 30 UNLESS THE DX20 IS ALREADY HALTED
; UPD ID= 738, SNARK:<5.MONITOR>PHYX2.MAC.4, 7-Jul-80 00:47:32 by DBELL
;TCO 5.1096 - ADD DX2CCK ROUTINE TO CHECK FOR HALTED MICROCODE
; UPD ID= 528, SNARK:<5.MONITOR>PHYX2.MAC.3, 19-May-80 16:46:09 by DBELL
;TCO 5.1042 - READ ASYCHRONOUS STATUS REGISTER TWICE IF NECESSARY
; UPD ID= 367, SNARK:<4.1.MONITOR>PHYX2.MAC.24, 26-Mar-80 11:08:31 by DBELL
;TCO 4.1.1119 - MAKE CHANGES NECESSARY FOR RP20 DISKS
;<4.MONITOR>PHYX2.MAC.23, 30-Oct-79 14:50:10, EDIT BY DBELL
;FIX 4.2551 BY USING RDREG INSTEAD OF RDREG3 IN ROUTINE HLTCHK
;<4.MONITOR>PHYX2.MAC.22, 25-Oct-79 19:35:43, EDIT BY DBELL
;TCO 4.2551 - CHECK IF MICROCODE IS HALTED IN DX2CON, GIVE ERROR IF SO
;<4.MONITOR>PHYX2.MAC.21, 19-Sep-79 15:18:20, EDIT BY DBELL
;TCO 4.2476 - ADD DISPATCH AND ROUTINE TO MAKE SET ONLINE WORK IN GENERAL
;<4.MONITOR>PHYX2.MAC.20, 18-Sep-79 17:22:02, EDIT BY DBELL
;FIX 4.2457 SOME BY CLEARING ATTENTION IN ASYNST
;<4.MONITOR>PHYX2.MAC.19, 12-Sep-79 10:40:07, EDIT BY DBELL
;FIX DX2DNF BUGCHK
;<4.MONITOR>PHYX2.MAC.18, 11-Sep-79 17:42:13, EDIT BY DBELL
;TCO 4.2457 - MAKE MULTIPLE TXO2'S OFF ONE DX20 (AND TXO3 OPTION) WORK
;<OSMAN.MON>PHYX2.MAC.1, 10-Sep-79 16:01:58, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>PHYX2.MAC.16, 24-Aug-79 16:46:44, EDIT BY DBELL
;TCO 4.2421 - REMOVE USES OF US.OFS, PHYONL, PHYOFL SINCE UNRELIABLE
;<4.MONITOR>PHYX2.MAC.15, 24-Jul-79 14:13:07, EDIT BY DBELL
;TCO 4.2339 - PREVENT RMR ERRORS WHEN TWO ASYCHRONOUS EVENTS HAPPEN
;<4.MONITOR>PHYX2.MAC.14, 6-Mar-79 09:37:09, Edit by KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<2BOSACK>PHYX2.MAC.7, 19-Feb-79 23:55:55, EDIT BY BOSACK
;<2BOSACK>PHYX2.MAC.6, 19-Feb-79 21:03:44, EDIT BY BOSACK
;<2BOSACK>PHYX2.MAC.5, 19-Feb-79 20:59:57, EDIT BY BOSACK
;ADD LOGIC TO DETERMINE HARDWARE SELECTED DENSITY ON FIRST OP FROM BOT
;<2BOSACK>PHYX2.MAC.4, 19-Feb-79 19:38:12, EDIT BY BOSACK
;<2BOSACK>PHYX2.MAC.3, 19-Feb-79 19:33:51, EDIT BY BOSACK
;<2BOSACK>PHYX2.MAC.2, 19-Feb-79 19:30:44, EDIT BY BOSACK
;<4.MONITOR>PHYX2.MAC.12, 3-Feb-79 00:20:54, Edit by MCLEAN
;<4.MONITOR>PHYX2.MAC.11, 3-Feb-79 00:19:51, Edit by MCLEAN
;<4.MONITOR>PHYX2.MAC.10, 31-Jan-79 01:09:26, Edit by MCLEAN
;MORE .DGPDL FIXES
;<4.MONITOR>PHYX2.MAC.9, 23-Jan-79 18:33:57, Edit by MCLEAN
;MORE DIAG JSYS
;<4.MONITOR>PHYX2.MAC.8, 21-Jan-79 17:54:18, Edit by MCLEAN
;INSERT .DGPDL CODE
;<4.MONITOR>PHYX2.MAC.7, 30-Aug-78 09:31:02, EDIT BY FORTMILLER
;TCO 4.1997 Set US.REW at interrupt level instead of at Start I/O
; time.
;<4.MONITOR>PHYX2.MAC.6, 8-Aug-78 13:44:10, Edit by MCLEAN
;<4.MONITOR>PHYX2.MAC.5, 5-Aug-78 16:08:24, Edit by MCLEAN
;<4.MONITOR>PHYX2.MAC.4, 4-Aug-78 16:08:05, Edit by FORTMILLER
;Add a BUGCHK - DX2HLT If the DX20 is discovered not running and
; print out the contents of DXGP6 which contains an error code
; Only check for legal data mode in Start I/O if a data type operation
;<3A.MONITOR>PHYX2.MAC.5, 1-Aug-78 14:33:10, Edit by FORTMILLER
;Remove BUGCHK at ENDLOD and fix bug in checking whether a mode
; set needs to be done for a TU71
;<4.MONITOR>PHYX2.MAC.3, 31-Jul-78 21:02:44, Edit by MCLEAN
;ADD ONLINE/OFFLINE INTERRUPT PSI
;<4.MONITOR>PHYX2.MAC.2, 22-Jul-78 22:12:37, Edit by MCLEAN
;<3A.MONITOR>PHYX2.MAC.4, 14-Jul-78 09:13:57, Edit by FORTMILLER
;Information printed from AC T1 during BUGCHK DX2NUE is garbage
;<3A.MONITOR>PHYX2.MAC.3, 13-Jul-78 16:04:35, Edit by FORTMILLER
;Add BUGCHK if SYSERR block at ENDLOD doesn't have any beginning data in it
; On some of the BUGs print out interesting AC information
;<3A-NEW>PHYX2.MAC.2, 1-Jun-78 20:19:03, Edit by FORTMILLER
;<3A-NEW>PHYX2.MAC.1, 30-May-78 10:45:29, Edit by FORTMILLER
;MAKE MANY CHANGES FOR 3A
;<DX20-101B-SOURCES>PHYDX2.MAC.4, 14-Jun-77 08:48:05, Edit by OUYANG
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG,PHYPAR,SERCOD ;SYSTEM PARAMETERS
TTITLE (PHYX2,,< - DEVICE DEPENDENT CODE FOR DX20-A/TU70S MAGTAPES VER 1>)
SUBTTL E. OUYANG/Ed Fortmiller 24 FEB 78
DX2VER==1 ;EDIT VERSION
ENTRY DXADSP ;FOR LIBRARY SEARCH
; For information on how to program the DX20/TU7x, see
; document 105-220-001-00 DX20-v100 Microcode by Steve
; Paavola.
PHYX2: ;BEGINNING ADDRESS OF PHYX2
SUBTTL DEVICE DEPENDANT TABLE DEFS
;DX20 STARTING ADDRESS
STADDR==6 ;DX20 STARTING ADDRESS
STMAX==^D10 ;NUMBER OF TIMES TO RESTART MICROCODE
MAXDRV==^D256 ;TOTAL NUMBER OF DRIVES PER DX20
NUMDRV==^D16 ;MAXIMUM NUMBER OF DRIVES WHICH CAN BE
;USED DUE TO TABLE SPACE LIMITATIONS
;UDB EXTENSIONS
U.HDEN==UDBDDM ;DENSITY (HARDWARE DETERMINED)
;NOTE: DO NOT MOVE WITHOUT CHANGING MAGTAP
U.EPOS==U.HDEN+1 ;ERROR POSITION
U.EBP==U.EPOS+1 ;ERROR BYTE POINTER
E.EBC==U.EBP+1 ;ERROR BYTE COUNTER
U.ETCF==E.EBC+1 ;TAPE CLEANER FLAG
U.ETIE==U.ETCF+1 ;TIE BYTE
LU.DX2==U.ETIE+1 ;LENGTH OF UDB
UDB.NM==1B17 ;BIT SET IN UDBERR TO INDICATE
; A RECOVERABLE NO MOTION ERROR
;KDB DEVICE DEPENDANT PORTION
K.DUDB==KDBDDP ;UDB TABLE (NUMDRV DRIVES LONG)
K.DNUM==K.DUDB+NUMDRV ;NUMBER OF DRIVES IN UDB TABLE
K.DXAD==K.DNUM+1 ;MASSBUS ADDRESS OF DX20
K.STCT==K.DXAD+1 ;NUMBER OF TIMES MICROCODE IS RESTARTED
K.DCNI==K.STCT+1 ;CONI OF RH GOES HERE
K.DCS1==K.DCNI+1 ;DATAI RH CONTROL REGISTER
K.DDBF==K.DCS1+1 ;DATAI RH DATA REGISTER
K.DVER==K.DDBF+1 ;MICROCODE VERSION #
K.DREG==K.DVER+1 ;DRIVE REGISTERS GO HERE
DEFINE SAVREG(REGS),<
IRP REGS,<SAVBIT==SAVBIT!<1_<^D35-REGS>>
REG.'REGS==SAVNUM ;DEFINE OFFSET OF THIS REGISTER
SAVNUM==SAVNUM+1 ;COUNT NUMBER OF REGISTERS
>;END IRP REGS
>;END DEFINE SAVREG
SAVBIT==0 ;INIT TO 0, THIS WILL HAVE A BIT SET
; FOR EACH DX20 MASSBUS REG TO SAVE
; IN THE KDB.
SAVNUM==0 ;INIT TO 0, THIS WILL BE A COUNT OF
; THE NUMBER OF DX20 MASSBUS REGS
; THAT GET SAVED IN THE KDB
SAVREG <0,1,2,3,4,5,6,20,21,22,23,24,26,27,30,31,32,33,34,35,36,37>
LR.DX2==SAVNUM ;NUMBER OF DX20 REGISTERS SAVED IN THE KDB
;FOLLOWING ARE THE 24(OCTAL) WORDS FOR THE EXTENDED STATUS TABLE
K.DEST==K.DREG+^D22 ;EXTENDED STATUS TABLE GOES HERE
LK.DX2==K.DEST+^D20 ;LENGTH OF DX20 KDB
SUBTTL MASSBUS-DX20 REGISTER DEFINITIONS
;MASSBUSS DEVICE REGISTER BIT ASSIGNMENTS (REGISTERS 00-37)
DXCTR==0B5 ;CONTROL REGISTER
DXSTR==1B5 ;STATUS REGISTER
DXERR==2B5 ;ERROR REGISTER
DXMTR==3B5 ;MAINTAINABILITY REGISTER
DXASR==4B5 ;ATTENTION SUMMARY "PSEUDO" REGISTER
DO.FC==5B5 ;FRAME COUNT REGISTER
DXDTR==6B5 ;DRIVE TYPE AND HARDWARE VERSION REGISTER
MBRA07==7B5 ;NOT USED
MBRA10==10B5 ;NOT USED
MBRA11==11B5 ;NOT USED
MBRA12==12B5 ;NOT USED
MBRA13==13B5 ;NOT USED
MBRA14==14B5 ;NOT USED
MBRA15==15B5 ;NOT USED
MBRA16==16B5 ;NOT USED
MBRA17==17B5 ;NOT USED
DXGP0==20B5 ;GENERAL PURPOSE REGISTER 0
DXGP1==21B5 ;GENERAL PURPOSE REGISTER 1
DXGP2==22B5 ;GENERAL PURPOSE REGISTER 2
DXGP3==23B5 ;GENERAL PURPOSE REGISTER 3
DXGP4==24B5 ;GENERAL PURPOSE REGISTER 4
DXGP5==25B5 ;GENERAL PURPOSE REGISTER 5
DXGP6==26B5 ;GENERAL PURPOSE REGISTER 6
DXGP7==27B5 ;GENERAL PURPOSE REGISTER 7
DXDR0==30B5 ;DIAGNOSTICS REGISTER 0
DXDR1==31B5 ;DIAGNOSTICS REGISTER 1
DXDR2==32B5 ;DIAGNOSTICS REGISTER 2
DXDR3==33B5 ;DIAGNOSTICS REGISTER 3
DXDR4==34B5 ;DIAGNOSTICS REGISTER 4
DXDR5==35B5 ;DIAGNOSTICS REGISTER 5
DXDR6==36B5 ;DIAGNOSTICS REGISTER 6
DXDR7==37B5 ;DIAGNOSTICS REGISTER 7
;CONTROL REGISTER DEFINITIONS (DXCTR REG. 0)
GO==1B35 ;GO BIT
DEFSTR(DXFTN,T1,^D35,6) ;DX20 FUNCTON FIELD(INCLUDES GO BIT) AS IN T1
;DX20 FUNCTION CODES(INCLUDING GO BIT)
XF.NOP==1 ;NO OPERATION
XF.UNL==3 ;REWIND AND UNLOAD
XF.REW==7 ;REWIND
XF.CLR==11 ;DRIVE CLEAR
XF.SRL==13 ;SENSE RELEASE
XF.ERA==25 ;ERASE GAP
XF.WTM==27 ;WRITE TAPE MARK
XF.SPF==31 ;FORWARD SPACE RECORD
XF.SPR==33 ;BACK SPACE RECORD
XF.SBF==35 ;FORWARD SPACE BLOCK
XF.SBR==37 ;BACKWARD SPACE BLOCK
XF.TIO==41 ;TEST I/O
XF.DSE==43 ;DATA SECURITY ERASE
XF.SNS==45 ;SENSE
XF.SNR==47 ;SENSE RESERVE
;
;THE FOLLOWING ARE NON IMMEDIATE TYPE OF OPERATIONS
; AND CAUSE A COMMAND DONE INTERRUPT
;
XF.WTF==61 ;WRITE DATA
XF.DIA==63 ;WRITE DIAGNOSTIC
XF.LWR==65 ;LOOP WRITE TO READ
XF.RDF==71 ;READ DATA
XF.RXS==75 ;READ EXTENDED STATUS
XF.RDR==77 ;READ REVERSE
;STATUS REGISTER DEFINITIONS (DXSTR REG. 1)
SR.ATA==1B20 ;ATTENTION ACTIVE (CAUSES ATTN SUMMARY)
SR.CER==1B21 ;COMPOSITE ERROR (MUST CHECK ERROR REG.)
SR.LP==1B22 ;LINK PRESENT
SR.RUN==1B23 ;MICROPROCESSOR RUNNING
;ERROR REGISTER DEFINITIONS (DXERR REG. 2)
DEFSTR(ECC,T1,^D27,^D4) ;STRUCTURE FOR ERROR CLASS CODE
DEFSTR(ESCC,T1,^D23,^D4) ;STRUCTURE FOR ERROR SUB-CLASS CODE
ER.NEW==1B28 ;MICROPROCESSOR DETECTED ERROR
ER.SPT==1B29 ;MICROPROCESSOR STOPED
ER.MPE==1B30 ;MICROBUS PAR. ERROR IN MASSBUSS INTERFACE
ER.DPE==1B31 ;DATA BUFFER PAR. ERROR
ER.CPE==1B32 ;MASSBUS CONTROL BUS PAR. ERROR
ER.RMR==1B33 ;REGISTER MODIFICATION REFUSED
ER.ILR==1B34 ;TRIED TO ACCESS NON-IMPLEMENTED REG.
ER.ILF==1B35 ;TRIED TO ISSUE NON-IMPLEMENTED COMMAND
;*CLASS SUB-CLASS ERROR CODES
; NOTE SUB-CLASS ERROR CODE DEFN.S ARE INDENTED
ER.UDS==1 ;UNUSUAL DEVICE STATUS
SER.FS==0 ;FINAL STATUS SEQUENCE
SER.IS==1 ;INITIAL STATUS SEQUENCE
ER.SR==2 ;SHORT RECORD
ER.LR==3 ;LONG RECORD
ER.DSE==4 ;DRIVE SELECTION ERROR
ER.RER==5 ;RECOVERABLE ERROR(TAPE MOTION STARTED)
SER.DP==0 ;DATA PARITY ERROR
ER.RE1==6 ;RECOVERABLE ERROR(NO TAPE MOTION)
SER.AM==0 ;ADDRESS MISMATCH
SER.B1==1 ;BUS PARITY ERROR FROM DRIVE
SER.B2==2 ;BUS PARITY ERROR FROM INITIAL STATUS
ER.NRE==7 ;NON-RECOVERABLE ERROR
SER.DP==0 ;DATA PATH, MICRO BUS PARITY ERROR
SER.CB==1 ;CHANNEL BUS INTER.,MICRO BUS PARITY ERROR
ER.FTL==^D8 ;FATAL ERROR
SER.DT==0 ;DRIVE TYPE NOT MATCHING BY MICROCODE
SER.PE==1 ;PARITY ERROR DURING CONTROL UNIT INITIAL SEQUENCE
SER.PE==2 ;****SIMILAR AS ABOVE
;MAINTENANCE REGISTER DEFINITIONS (DXMTR REG. 3)
MR.SS==1B31 ;SINGLE STEP MICRO CONTROLLER
MR.WEP==1B32 ;WRITE EVEN PARITY BALU
MR.ST==1B33 ;START/STOP MICRO CONTROLLER
MR.RES==1B34 ;RESET MICRO CONTROLLER
;ATTENTION SUMMARY REGISTER DEFINITIONS (DXASR REG. 4)
AS.7==1B28 ;DRIVE-7 NEEDS ATTENTION
AS.6==1B29 ;DRIVE-6 NEEDS ATTENTION
AS.5==1B30 ;DRIVE-5 NEEDS ATTENTION
AS.4==1B31 ;DRIVE-4 NEEDS ATTENTION
AS.3==1B32 ;DRIVE-3 NEEDS ATTENTION
AT.2==1B33 ;DRIVE-2 NEEDS ATTENTION
AT.1==1B34 ;DRIVE-1 NEEDS ATTENTION
AT.0==1B35 ;DRIVE-0 NEEDS ATTENTION
;BYTE REGISTER DEFINITIONS(DO.FC REG. 5)
; USED INTERCHANGEABLY WITH REG. 25
;STATUS INDEX/ENDING STATUS REGISTER DEFINITION(DXGP0 REG.20)
ES.RES==1B28 ;BIT TO REQUEST FOR EXTENDED STATUS
ES.UEX==1B27 ;UNIT EXCEPTION
ES.UCK==1B26 ;UNIT CHECK
ES.DVE==1B25 ;DEVICE END
ES.CHE==1B24 ;CHANNEL END
ES.BSY==1B23 ;CONTROL UNIT OR DEVICE BUSY
ES.CUE==1B22 ;CONTROL UNIT END
ES.SM==1B21 ;STATUS MODIFIER
ES.ATN==1B20 ;ATTENTION
;DRIVE NUMBER/MODE REGISTER DEFINITION(DXGP1 REG. 21)
DEFSTR(DRVNUM,T1,^D35,^D8) ;STRUCTURE DEFN FOR DRIVE NUMBER
DEFSTR(DRVMOD,T1,^D27,^D4) ;DRIVE MODE
DEFSTR(DATMOD,T1,^D23,^D4) ;STRUCTURE FOR DATA MODE
;DRIVE MODE VALUES
DRV.NM==0 ;NO MODE SET TO BE ISSUED
DRV.O2==1 ;7 TRACK, 200 BPI, ODD PARITY
DRV.O5==2 ;7 TRACK, 556 BPI, ODD PARITY
DRV.O8==3 ;7 TRACK, 800 BPI, ODD PARITY
DRV.E2==5 ;7 TRACK, 200 BPI, EVEN PARITY
DRV.E5==6 ;7 TRACK, 556 BPI, EVEN PARITY
DRV.E8==7 ;7 TRACK, 800 BPI, EVEN PARITY
DRV.NR==13 ;9 TRACK, 800 BPI
DRV.PE==14 ;9 TRACK, 1600 BPI
DRV.GC==15 ;9 TRACK, 6250 BPI.
DRV.IL==77 ;ILLEGAL CODE
;DATA MODE VALUES
DAT.IL==0 ;ILLEGAL CODE
DAT.CD==1 ;CORE DUMP FORMAT(9-TRACK)
DAT.IC==2 ;INDUSTRY COMPATIBLE, 4 8-BIT BYTES/WRD
DAT.SB==3 ;6 6-BIT BYTES/WRD
DAT.AS==4 ;7-BIT ASCII MODE
DAT.HD==5 ;HI DENSITY
;EXTENDED STATUS TABLE SIZE REGISTER DEFINITION (DXGP2 REG. 22)
DEFSTR(ESTSZ,T1,^D35,^D8) ;STRUCTURE FOR EXTENDED STATUS TABLE SIZE
;TRACK IN ERROR, FLAGS REGISTER DEFINITIONS (DXGP3 REG. 23)
TE.TIE==1B27 ;=1, IF TIE ERROR RECOVERY ATTEMPTED
TE.SOP==1B26 ;=1, IF SENSE OPERATION REQUIRED
TE.SAS==1B25 ;=1, IF SUPPRESS AUTOMATIC SENSE ON UNIT CHECK.
;ASYNCHRONOUS STATUS REGISTER DEFINITIONS (DXGP4 REG. 24)
;BYTE COUNT REGISTER DEFINITIONS (DXGP5 REG. 25)
DXGP==177777B35 ;MASK FOR 16 DATA BITS IN REGISTER
;EXTENDED STATUS REGISTER 0 DEFINITIONS(DXGP6 REG. 26)
DXGP==177777B35 ;MASK FOR 16 DATA BITS IN REGISTER
;EXTENDED STATUS REGISTER 1 DEFINITIONS (DXGP7 REG. 27)
DXGP==177777B35 ;MASK FOR 16 DATA BITS IN REGISTER
;DIAGNOSTIC REGISTER 0 DEFINITION (DXDR0 REG. 30)
IR==177777B35 ;MASK FOR IR REG.
;DIAGNOSTIC REGISTER 1 DEFINITION (DXDR1 REG. 31)
D1.IRE==1B20 ;ENABLE IR LOAD FROM MICRO-STORE
D1.MSE==1B21 ;ENABLE MICRO-STORE LOAD FROM IR
D1.PCE==1B22 ;ALLOW LOAD/WRITE OF THE PC
D1.PCI==1B23 ;ALLOW AUTO-INCREMENT OF PC
D1.PC==7777B35 ;MASK FOR 12 BITS IN PC
DS.BOT==1B35 ;BOT SEEN
DS.EOT==1B34 ;EOT SEEN
DS.TM==1B33 ;TAPE MARK SEEN
DS.WLK==1B32 ;WRITE LOCKED
DS.OFL==1B31 ;DRIVE IS OFFLINE
DS.NMV==1B30 ;TAPE DIDN'T MOVE
DS.DC==1B29 ;DATA CHECK IN SENSE BYTES
DS.RTY==1B28 ;RETRIABLE ERROR
DS.ERR==1B27 ;ERROR
;BIT DEFINITIONS FOR SENSE BYTES 0-3
S0.CR==1B2 ;COMMAND REJECT
S0.IR==1B3 ;INTERVENTION REQUIRED
S0.BOC==1B4 ;BUS OUT CHECK
S0.EC==1B5 ;EQUIPMENT CHECK
S0.DC==1B6 ;DATA CHECK
S0.OR==1B7 ;OVERRUN
S0.WCZ==1B8 ;WORD COUNT ZERO
S0.DCC==1B9 ;CONVERTER CHECK
S1.NSE==1B10 ;NOISE
S1.TUA==1B11 ;TU STATUS A
S1.TUB==1B12 ;TU STATUS B
S1.7TK==1B13 ;7 TRACK FEATURE
S1.BOT==1B14 ;BOT - LOAD POINT
S1.WS==1B15 ;WRITE STATUS
S1.FP==1B16 ;WRITE PROTECTED
S1.NC==1B17 ;NOT CAPABLE
S2.TIE==377B27 ;TRACK IN ERROR REGISTER
S3.VRC==1B28 ;R/W VRC
S3.MTE==1B29 ;MTE/LRC
S3.SKW==1B30 ;SKEW ERROR
S3.CRC==1B31 ;CRC ERROR
S3.ENV==1B32 ;VRC ERROR
S3.D16==1B33 ;1600 BPI
S3.BKW==1B34 ;BACKWARD STATUS
S3.CPC==1B35 ;C COMPARE
;BIT DEFINITIONS FOR SENSE BYTE 6
S6.7TK==1B20 ;7 TRACK DRIVE
S6.DD==1B22 ;DUAL DENSITY TAPE UNIT
; TU IS CAPABLE OF BOTH 1600 AND 6250
S6.TMI==17B27 ;MODEL ID FIELD
S6M.70==1 ;TU70 (ONLY WHEN ONLINE)
S6M.71==1 ;TU71 (ONLY WHEN ONLINE)
S6M.72==14 ;TU72
S6M.73==15 ;TU73 (200 IPS GCR DRIVE)
SUBTTL DX20 ERROR RECOVERY DEFS
;RETRY COUNTS:
CLNREC==5 ;SP REVERSE THIS NR RECORDS TO HIT CLEANER
RTYOP==4 ;RETRY OPERATION THIS MANY TIMES BEFORE TAPE CLEAN SEQUENCE
RTYCLN==^D10 ;RETRY CLEAN SEQUENCE THIS MANY TIMES ON READ
; BEFORE GIVING UP
; THE TOTAL NR OF RD RETRIES = RTYOP*(RTYCLN+1)
RTYWRT==^D14 ;# WRITE RETRIES MAXIMUM BEFORE ABORT
RTY.DN==16 ;CODE SIGNAL END OF RETRY
RTY.CP==17 ;CODE TO CHECK POSITION
;ERROR WORDS
; E.EBC ;ERR BYTE COUNTER (USED IF WE HIT BOT
;DURING TAPE CLEAN SEQUENCE)
; U.EBP ;ERR BYTE POINTER
; U.ETCF ;-1= IN TAPE CLN SEQUENCE, 0= NOT
; UDBERR(RH) ;CURRENT FUNCTION (1 - 17)
;ON RETRY OF ORIGINAL OPERATION, THIS LOC
;MUST BE SET TO THE ORIGINAL OPERATION
; UDBERC ;RETRY COUNT
;CONVERTED TO # RETRIES DONE AT END
; U.EPOS ;WE SHOULD BE HERE WHEN WE'RE
;READY TO RETRY OPERATION
SUBTTL ROUTINE TO MANIPULATE DX20 REGISTERS
;MACROS TO READ AND WRITE A DX20 REGISTER
; ASSUME: P1/ CDB POINTER
; Q2/ UNIT NUMBER OF THE DX20
; T1,T4 ARE PRESERVED
DEFINE RDRG (REG),<
MOVSI T2,(REG)
CALL RDREG3
>;END DEFINE RDRG
DEFINE WTRG (REG,DATA),<
MOVEI T2,DATA ;DATA LESS OR EQUAL TO 16 BITS
TLO T2,(REG)
CALL WTREG3
>;END DEFINE WTRG
;MACRO TO READ AND WRITE DX20 REGISTERS
; ASSUME: P1/ CDB POINTER
; P3/ UDB POINTER
; T1,T4 ARE PRESERVED
DEFINE REDRG (REG),<
MOVSI T2,(REG)
CALL RDREG
>;END DEFINE REDRG
DEFINE WRTRG (REG,DATA),<
MOVEI T2,DATA ;;DATA LESS OR EQUAL TO 16 BITS
TLO T2,(REG)
CALL WTREG
>;END DEFINE WRTRG
;STDX - STARTS THE MICROCODE IN THE DX20
; T1/ STARTING ADDRESS OF THE CRAM
; P1/ CDB, Q2/ UNIT NUMBER OF THE DX20
; CALL STDX
; RETURN+1: ALWAYS
; T1 IS NOT PRESERVED
STDX: PUSH P,T1 ;SAVE T1
MOVX T2,DXMTR!MR.RES ;ISSUE A RESET TO
CALL WTREG3 ; THE DX20. (ALSO STOP IT)
POP P,T2 ;GET BACK THE STARTING ADDR
ANDI T2,D1.PC ;STRIP
TXO T2,DXDR1!D1.PCE!D1.PCI!D1.IRE ;LOAD STARTING
CALL WTREG3 ; ADDRESS IN THE DX20
MOVX T2,DXMTR!MR.ST ;START THE
CALLRET WTREG3 ; DX20 MICROPROCESSOR
;GTVER - GETS THE VERSION NUMBER OF THE MICROCODE FROM
; LOCATION 0 OF THE CRAM IN THE DX20
; P1/CDB, Q2/ UNIT NUMBER OF THE DX20
; CALL GTVER
; RETURN+1: ALWAYS, AND T1/ CONTENTS OF LOC. 0 OF CRAM
GTVER: MOVX T2,DXMTR!MR.RES ;STOP THE
CALL WTREG3 ; DX20 MICROPROCESSOR
MOVX T2,DXDR1!D1.PCE!D1.IRE ;SET THE
CALL WTREG3 ; PC TO 0
MOVX T2,DXDR0 ;READ THE IR
CALLRET RDREG3 ; REGISTER INTO T1
;GTSNS - READS IN SENSE BYTES 0-3 INTO T1
; T4/ DRIVE NUMBER
; P1/ CDB, Q2/ UNIT NUMBER OF DX20
; CALL GTSNS
; RETURN+1: FAIL
; RETURN+2: GOOD RETURN
; T1/ SENSE BYTES 0 - 3 (0) 2-9 (1) 10-17 (2) 20-27 (3) 28-35
GTSNS: CALL HLTCHK ;SEE IF MICROCODE IS STILL RUNNING
RET ;NO, FAIL
MOVE T2,T4 ;GET THE DRIVE NUMBER
TXO T2,DXGP1 ;SET THE DRIVE
CALL WTREG3 ; NUMBER INTO THE DX20
REPEAT 0,< ;IF ITS DESIRED TO DO A NOP TO
; GET THE SENSE BYTE DELETE THE
; REPEAT 0 AND THE MOVX FOLLOWING IT
MOVX T2,DXGP3!TE.SOP ;SET FORCE SENSE BIT
CALL WTREG3 ; LOAD INTO THE FLAGS REG
MOVX T2,DXCTR!XF.NOP ;DO A
>;END REPEAT 0
MOVX T2,<DXCTR!XF.SNS> ;DO A SENSE OPERATION
CALL WTREG3 ; NOP OPERATION
MOVEI T4,1 ;GET MASK BIT
LSH T4,(Q2) ;ATTENTION MASK FOR THIS DX20
PUSH P,P4 ;USE P4 AS COUNTER
MOVEI P4,6000 ;LOOP COUNT=6000
; (THIS MUST BE THIS LARGE AS THE
; FIRST TIME THRU TAKES A LONG TIME)
GTSN1: RDRG DXASR ;READ ATTENTION SUMMARY REG. IN T1
TDNE T1,T4 ;SKIP IF ATTENTION BIT NOT SET
JRST GTSN2 ;JUMP, GET ATTENTION SET
SOJG P4,GTSN1 ;TRY AGAIN
POP P,P4 ;FAIL, THEN RESTORE P4
BUG(DX2FGS) ;PUT OUT BUGCHK
RET ;JUST RETURN
GTSN2: POP P,P4 ;SUCCEED, RESTORE P4
WTRG DXASR,(T4) ;CLEAR ATTENTION BIT FOR THIS DX20
CALLRET RDSNS ;GET 4 SENSE BYTES IN T1
;GETEXS - READ IN 4 BYTES OF EXTENDED STATUS
; T1/ INDEX FOR EXTENDED STATUS
; P1/ CDB, Q2/ UNIT NUMBER OF DX20
; CALL GETEXS
; RETURN+1: FAIL RETURN
; RETURN+2: SUCEED
; T1/ T1 HAS THE 4 BYTES (1) 2-9 (2) 10-17 (3) 20-27 (4) 28 - 35
GETEXS: MOVE T2,T1 ;GET INDEX FROM T1
TXO T2,<DXGP0!ES.RES> ;SET BIT TO REQUEST
CALL WTREG3 ; TO REQUEST SENSE BYTES
RDSNS: MOVX T4,100 ;NUMBER OF TIMES TO WAIT
; FOR ES.RES TO CLEAR BEFORE GIVING UP
RDSNS1: RDRG DXGP0 ;READ BACK REG. 20
TXNN T1,ES.RES ;REQUEST SENSE BYTE BIT CLEARED?
JRST RDSNS2 ;GO READ REG 26 AND 27
SOJG T4,RDSNS1 ;NO, TRY AGAIN
BUG(DX2FUS)
RET ;FAIL, NONSKIP RETURN
RDSNS2: RDRG DXGP6 ;READ IN REG 26
HRL T4,T1 ;PUT REG. 26 IN LEFT HALF
RDRG DXGP7 ;READ IN REG 27
HRR T4,T1 ;PUT REG. 27 IN RIGHT HALF
MOVE T1,T4 ;PUT IN T1
RETSKP ;SKIP RETURN
;HLTCHK - SEES IF THE MICROCODE IS STILL RUNNING IN THE DX20
; P1/ CDB
; P2/ KDB
; P3/ UDB
;RETURNS:
; +1: MICROCODE HALTED, BUGINF PRINTED IF FIRST TIME NOTICED
; +2: MICROCODE IS RUNNING FINE
;
;PRESERVES T4.
HLTCHK: MOVX T2,DXSTR ;READ THE DX20 STATUS REGISTER
CALL RDREG ; TO SEE IF THE DX20 IS RUNNING
MOVX T2,KS.HLT ;GET HALTED FLAG READY
TXNN T1,SR.RUN ;IS IT RUNNING?
JRST DX2STP ;NO IT QUIT ON US
ANDCAM T2,KDBSTS(P2) ;NOT HALTED, REMEMBER THAT
RETSKP ;GOOD RETURN
DX2STP: TDNE T2,KDBSTS(P2) ;ALREADY KNEW THAT IT WAS STOPPED?
RET ;YES, JUST RETURN
IORM T2,KDBSTS(P2) ;NOW WE KNOW
PUSH P,T4 ;SAVE T4
PUSH P,T1 ;SAVE STATUS
MOVX T2,DXERR ;NOW WANT ERROR REGISTER
CALL RDREG ;READ IT
HRLZ T4,T1 ;SAVE ERROR REGISTER
MOVX T2,DXGP6 ;FINALLY GET POSSIBLE ERROR REASON
CALL RDREG ;READ IT
HRR T4,T1 ;SAVE IT
CALL FNDCKU ;SET UP CHANNEL AND CONTROLLER NUMBERS
POP P,T3 ;RESTORE STATUS REGISTER
BUG(DX2HLT,<<T1,CHAN>,<T2,DX20>,<T3,REG1>,<T4,2AND26>>) ;COMPLAIN
POP P,T4 ;RESTORE AC
RET ;ERROR RETURN
;ASYNST - TAKES CARE OF ANY ASYNCHRONOUS STATUS PRESENTED TO DX20,
; WHICH IS CAUSED BY THE COMPLETION OF A REWIND
; OR AN UNIT BECOMES ON-LINE.
; P1/CDB, P2/KDB
; CALL ASYNST
; RETURN+1: ALWAYS
ASYNST: PUSH P,Q2 ;SAVE DRIVE STATUS
MOVE Q2,K.DXAD(P2) ;GET UNIT NUMBER OF DX20
ASYNS1: RDRG DXGP4 ;GET ASYNST STATUS
JUMPE T1,Q2RET ;NONE, SO RETURN
MOVX T2,DXGP4 ;SET UP IN CASE NEED TO READ REGISTER AGAIN
TXNN T1,ES.UEX!ES.UCK!ES.DVE!ES.CHE!ES.BSY!ES.CUE!ES.SM!ES.ATN ;FLAGS?
CALL RDREG3 ;NO, READ AGAIN SINCE DX20 WASN'T DONE YET
PUSH P,P3 ;PRESERVE P3
PUSH P,P4 ; AND P4
MOVX T2,DXGP4 ;ZERO THE ASYNC STATUS
CALL WTREG3 ; REGISTER
LOAD T4,DRVNUM ;GET DRIVE NUMBER IN T4
CALL DRVSRC ;FIND THE UDB WITH THIS DRIVE NUMBER
JRST [ BUG(DX2DNF,<<T4,DRIVE>>) ;CAN'T FIND IT
MOVX T2,1 ;GET BIT READY
LSH T2,(Q2) ;MASK TO CLEAR OUR ATTENTION BIT
TXO T2,DXASR ;CLEAR THE ATTENTION
CALL WTREG3 ; BIT FOR THIS DX20
POP P,P4 ;RESTORE AC'S
POP P,P3 ;THAT WERE PUSHED
JRST ASYNS1] ;AND LOOK FOR MORE STATUS
CALL GTSNS ;CLEAR ATTN BIT AND GET SENSE BYTES IN T1
MOVX T1,S1.FP ;FAIL, MAKEUP SOME SENSE BYTES
MOVX T2,<US.BOT!US.WLK> ;GET MASK
ANDCAM T2,UDBSTS(P3) ;CLEAR THESE BITS FIRST
TXNN T1,S1.BOT ;UNIT AT BOT?
TXZ T2,US.BOT ;NO, CLEAR BOT BIT
TXNN T1,S1.FP ;FILE-PROTECTED AS IN SENSE BYTE
TXZ T2,US.WLK ;NO, CLEAR US.WLK IN MASK
IORM T2,UDBSTS(P3) ;MARK INTO UDB
MOVSI T2,(US.REW) ;SAY NO LONGER REWINDING
ANDCAM T2,UDBSTS(P3) ;SO CLEAR THE BIT
MOVSI T2,(US.PSI) ;SET POSSIBLE PSI
IORM T2,UDBSTS(P3) ; FOR REWIND DONE
MOVX T2,DXGP4 ;GET ASYCHRONOUS STATUS
CALL RDREG3 ; ...
JUMPN T1,[IOPIOF ;SEE IF ANY THERE
CALL SCHSEK ;YES, ONLY DO SEEKS
IOPION ;INTERRUPTS OK NOW
POP P,P4 ;RESTORE ACS
POP P,P3
JRST ASYNS1] ;LOOP TO SEE IF ANY MORE STATUS
CALL PHYRWD ;LAST ONE, START IO
POP P,P4 ;RESTORE AC'S
POP P,P3
Q2RET: POP P,Q2 ;RESTORE Q2
RET ; AND RETURN TO CALLER
;HARCHK - CHECKS FOR ERRORS AND PUTS THE DRIVE STATUS IN Q2
; P1/CDB, P2/KDB, P3/UDB, Q1/FTN CODE, P4/IORB
; CALL HARCHK
; RETURN+1: SOME HARD ERROR FOUND
; RETURN+2: GOOD RETURN WITH DRIVE STATUS IN Q2
HARCHK: MOVX T1,<IS.DVE!IS.DTE> ;CLEAR DEVICE AND DATA
ANDCAM T1,IRBSTS(P4) ; IN IRBSTS
MOVX T1,US.WLK ;SEE IF THE UNIT IS
TDNE T1,UDBSTS(P3) ; WRITE LOCKED?
MOVX Q2,DS.WLK ;YES, LIGHT A BIT
TXNE Q1,TB.TM ;WRITE TM OPERATION
TXO Q2,DS.TM ;YES, SET WHERE IT WILL BE SEEN
REDRG DXSTR ;READ IN THE DX20 STATUS REGISTER
TXNN T1,SR.CER ;ANY ERROR TO INVESTIGATE?
RETSKP ;NO ERRORS
REDRG DXERR ;READ THE DX20 ERROR REGISTER
TXNE T1,<ER.SPT!ER.MPE> ;IS THE DX20 HALTED?
JRST HARCH1 ;YES, GO START IT
TXNE T1,<ER.ILF!ER.ILR!ER.RMR!ER.CPE> ;ILLEGAL FUNCTION, ILLEGAL REG, REG MOD REFUSED,
; OR CONTROL BUS PARITY ERROR?
JRST HARCH2 ;YES, FATAL ERROR
LOAD T2,ECC ;GET THE ERROR CLASS CODE
JUMPLE T2,ECCERR ;0 ERROR CLASS CODE IS A FATAL ERROR
CAILE T2,ECCSZ ;LEGAL CODE?
JRST ECCERR ;NO, FATAL ERROR
JRST @ECCTBL-1(T2) ;DISPATCH TO ERROR CLASS CODE
;HERE IF DX20 IS HALTED
;
HARCH1: REDRG DXGP6 ;READ IN AS THIS MIGHT CONTAIN AN ERROR CODE
BUG (DX2DIE,<<T1,D>>)
MOVEI T1,STADDR ;DX20 STARTING ADDRESS
CALL STDX ;START THE DX20 RUNNING AGAIN
HARCH2: CALL RDALL ;READ ALL DX20 REGISTERS AND EXTENDED STATUS
HERR: MOVX T3,<IS.DVE!IS.ERR!IS.NRT> ;FLAG A FATAL
IORM T3,IRBSTS(P4) ; ERROR IN THE IORB
MOVX T3,US.REW ;CLEAR REWINDING
ANDCAM T3,UDBSTS(P3) ; IN THE UDB
MOVX T1,US.WLK ;IF WRITE LOCKED IS
TDNE T1,UDBSTS(P3) ; SET IN THE UDB, SET
IORM T1,IRBSTS(P4) ; WRITE LOCKED IN THE IORB
TXO Q2,DS.ERR ;FLAG AN ERROR OCCURRED
RET ;NONSKIP RETURN INDICATES FATAL ERROR
;ERROR CLASS CODE DISPATCH TABLE
;
ECCTBL: ECC1 ;(1) UNUSUAL DEVICE STATUS (EXAMINE ENDING STATUS REG)
CLRERR ;(2) SHORT RECORD (NOT AN ERROR)
CLRERR ;(3) LONG RECORD (FATAL)
; (ERROR BITS WILL BE SET BY CKERR)
FTLERR ;(4) DRIVE SELECTION ERROR (FATAL)
CLRERR ;(5) TAPE MOTION (RECOVERABLE)
NOTMOV ;(6) NO TAPE MOTION (RECOVERABLE)
FTLERR ;(7) PARITY ERROR (FATAL)
FTLERR ;(8) FATAL ERROR
ECCSZ==.-ECCTBL ;LENGTH OF TABLE
;RDALL - READS ALL THE DX20 REGISTERS AND
; THE EXTENDED STATUS INTO THE KDB
; P1/CDB, P2/KDB, P3/UDB
; CALL RDALL
; RETURN+1: ALWAYS
;
RDALL: CALL DX2RDR ;READ DX20 REGISTERS
MOVX T2,DXERR ;ZERO THE DX20
CALL WTREG ; ERROR REGISTER
CALLRET DX2REX ;READ THE EXTENDED STATUS
;HERE IF ERROR CLASS 1
;
ECC1: REDRG DXGP0 ;READ THE ENDING STATUS
TXNN T1,ES.UEX ;UNIT EXCEPTION?
JRST ECC1A ;NO
TXNE Q1,TB.RD!TB.SPC ;READ OR SPACE OPERATION?
TXO Q2,DS.TM ;YES, THEN LIGHT TAPE MARK BIT
TXNE Q1,TB.WRT ;WRITE OPERATION?
TXO Q2,DS.EOT ;YES, THEN LIGHT EOT BIT
ECC1A: TXNN T1,ES.UCK ;UNIT CHECK IN ENDING STATUS?
JRST CLRERR ;CLEAR ERROR REGISTER AND
; SKIP RETURN
PUSH P,T1 ;SAVE ENDING STATUS ACROSS SUBROUTINE CALL
CALL RDALL ;READ ALL DX20 REGISTERS AND EXTENDED STATUS
POP P,T1 ;RESTORE ENDING STATUS
MOVE T2,K.DEST(P2) ;GET SENSE BYTES 0 - 3
TXNE T2,S0.EC ;EQUIPMENT CHECK?
JRST HERR ;YES, FATAL ERROR
TXNE T2,S0.BOC ;BUS OUT CHECK?
JRST ERRBOC ;YES, ANALYZE IT FURTHER
TXNE T2,S0.IR ;INTERVENTION REQUIRED?
JRST ERRIRQ ;YES, ANALYZE IT FURTHER
ECC1B: TXNE T2,<S0.CR!S1.NC> ;COMMAND REJECT OR NOT CAPABLE?
JRST HERR ;YES, FATAL ERROR
TXNE T2,S0.OR ;OPERATION REJECTED?
JRST ERROVR ;YES, ANALYZE IT FURTHER
TXNE T2,S1.BOT ;AT BOT?
JRST ERRBOT ;YES
TXNE T2,S0.DC ;DATA CHECK
JRST ERRDC ;YES, ANALYZE IT FURTHER
JRST HERR ;FATAL ERROR
;HERE IF AT BOT
;
ERRBOT: TXO Q2,DS.BOT ;YES, FLAG AT BOT
RETSKP ;SKIP RETURN
;HERE IF BUS OUT CHECK
;
ERRBOC: TXNN T1,ES.DVE ;DEVICE END?
JRST NOTMOV ;NO, REISSUE COMMAND
TXNN Q1,TB.WRT ;WRITE TYPE OPERATION?
JRST NOTMOV ;NO, REISSUE COMMAND
JRST RTYERR ;YES, RETRIABLE ERROR
;HERE IF INTERVENTION REQUIRED
;
ERRIRQ: TXNN T1,ES.DVE ;DEVICE END?
JRST HERR ;NO, HARD ERROR
TXNN Q1,<TB.UNL!TB.REW> ;REWIND OR UNLOAD COMMAND?
JRST ECC1B ;NO, LOOK AT SOME MORE SENSE BYTES
JRST RSKP ;YES, JUST CONTINUE
;HERE IF OVERRUN
;
ERROVR: TXNN Q1,TB.DOP ;DATA OPERATION?
JRST NOTMOV ;NO, TAPE HASN'T MOVED
JRST RTYERR ;YES, RETRIABLE ERROR
;HERE IF DATA CHECK
;
ERRDC: TXO Q2,<DS.DC!DS.RTY!DS.ERR> ;FLAG DATA CHECK
MOVX T1,<IS.DTE!IS.ERR> ;FLAG DATA ERROR
IORB T1,IRBSTS(P4) ; IN THE IORB
TXNN Q1,TB.RD ;READ OPERATION?
RETSKP ;SKIP RETURN
LDB T1,[POINTR K.DEST(P2),S2.TIE] ;GET THE TIE BYTE
HRROM T1,U.ETIE(P3) ;REMEMBER TIE INFO
RETSKP ;GIVE SKIP RETURN
ECCERR: BUG(DX2IEC,<<T1,D>>)
JRST HARCH2
;HERE IF TAPE HASN'T MOVED
;
NOTMOV: JRST HERR ;CALL IT HARD FOR NOW
MOVX T1,UDB.NM ;SET FLAG IN
IORM T1,UDBERR(P3) ; UDB TO INDICATE TAPE HASN'T MOVED
TXO Q2,<DS.NMV!DS.ERR> ;FLAG NOT MOVED AND ERROR
MOVX T1,<IS.ERR!IS.DVE> ;DEVICE ERROR
IORM T1,IRBSTS(P4) ;SET IN THE IORB
JRST CLRERR ;CLEAR ERROR, AND SKIP RETURN
RTYERR: TXO Q2,<DS.RTY!DS.ERR> ;FLAG RETRIABLE AND ERROR
MOVX T1,<IS.DVE!IS.DTE!IS.ERR> ;FLAG AN
IORM T1,IRBSTS(P4) ; ERROR IN THE IORB
RETSKP ;SKIP RETURN
FTLERR: CALL RDALL ;READ ALL REGISTERS
CALLRET HERR ;FLAG AS HARD ERROR
CLRERR: MOVX T2,DXERR ;ZERO THE
CALL WTREG ; ERROR REGISTER
RETSKP ;SKIP RETURN
;DX2RDR - READS DX20 REGISTERS 0-6,20-24,26-37 INTO K.DREG IN THE KDB
; ALSO, K.DCNI, K.DCS1, AND K.DDBF INTO KDB
; P1/CDB, P2/KDB, P3/UDB
; CALL DX2RDR
; RETURN+1: ALWAYS
DX2RDR: SAVEQ ;SAVE ALL Q REGISTERS
PUSH P,P2 ;REMEMBER CURRENT KDB POINTER
SETZB T4,Q1 ;ZERO COUNTER,AC TO TEST AFTER SHIFT
MOVX Q2,SAVBIT ;A BIT FOR EACH REGISTER TO SAVE
DX2RD1: LSHC Q1,1 ;SHIFT IN A BIT FROM Q2
JUMPE Q1,DX2RD2 ;JUMP IF THIS REG IS NOT TO BE SAVED
HLLZ T2,T4 ;GET REGISTER TO READ
CAMN T2,[DXDR0] ;ABOUT TO READ REGISTER 30?
TDZA T1,T1 ;YES, READ IT
CALL RDREG ;READ A DX20 REGISTER
MOVEM T1,K.DREG(P2) ;SAVE REGISTER IN THE KDB
ADDI P2,1 ;UPDATE KDB POINTER FOR NEXT TIME
SETZ Q1, ;ZERO TEST AC
DX2RD2: ADD T4,[BYTE (6) 1 (36-6) 1] ;UPDATE REGISTER NUMBER
JUMPN Q2,DX2RD1 ;DONE SAVING ALL REGISTERS?
POP P,P2 ;RESTORE KDB POINTER
CALL ERRCNI ;GET CONI AND DATAI
MOVEM T1,K.DCNI(P2) ;SAVE IN KDB
MOVEM T2,K.DCS1(P2) ; ...
MOVEM T3,K.DDBF(P2) ; ...
DMOVE T1,K.DREG+REG.0(P2) ;GET CONTROL AND STATUS REGISTERS
TXNN T1,GO ;IS GO STILL UP?
TXNE T2,SR.RUN ;NO, IS THE MICROPROCESSOR STILL RUNNING
RET ;YES, CAN'T READ REGISTER 30 THEN
MOVX T2,DXDR1 ;SETUP TO READ THE PC REGISTER
CALL RDREG ;READ IT
TXZ T1,D1.IRE ;TURN OFF IR ENABLE
MOVX T2,DXDR1 ;SET TO WRITE PC REGISTER
IOR T2,T1 ;WITH ALL THE BITS BUT IR ENABLE
CALL WTREG ;WRITE IT BACK
MOVX T2,DXDR0 ;SETUP TO READ THE IR
CALL RDREG ;READ IT NOW
MOVEM T1,K.DREG+REG.30(P2) ;STORE IT WHERE IT BELONGS
RET
;DX2REX - READS IN THE EXTENDED STATUS TABLE INTO THE KDB
; P1/CDB, P2/KDB, P3/UDB
; CALL DX2REX
; RETURN+1:ALWAYS
DX2REX: PUSH P,Q1 ;WILL USE Q1 & Q2
PUSH P,Q2 ;SO, SAVE THEM
MOVE Q2,K.DXAD(P2) ;GET UNIT # FOR THIS DX20
MOVSI Q1,-LK.DX2+K.DEST ;Q1 AS COUNTER AND INDEX
DX2RE1: HRRZ T1,Q1 ;GET INDEX FOR EXTENDED STATUS
CALL GETEXS ;READ IN THE SENSE BYTES
JRST DX2RE2 ;FAIL
ADD Q1,P2 ;ADD BASE ADDR. OF KDB
MOVEM T1,K.DEST(Q1) ;STORE SENSE BYTES IN KDB
SUB Q1,P2 ;RESTORE Q1
AOBJN Q1,DX2RE1 ;LOOP BACK FOR THE NEXT 4 BYTES
DX2RE2: POP P,Q2 ;RESTORE Q1&Q2
POP P,Q1 ;
RET ;RETURN
;DRVSRC - FIND THE UDB GIVEN THE DRIVE NUMBER OF A DRIVE.
;GIVEN THE 8-BIT DRIVE NUMBER, THIS ROUTINE RETURNS THE UDB FOR
;THAT DRIVE. INDEXING INTO K.DUDB WILL NOT WORK SINCE A TABLE
;256 ENTRIES LONG WOULD BE NEEDED.
; T4/ DRIVE NUMBER, P2/ KDB
;RETURNS:
; +1: NO UDB FOUND WITH THIS DRIVE NUMBER
; +2: P3/ ADDRESS OF THE FOUND UDB
;DESTROYS T1.
DRVSRC: MOVSI T1,-NUMDRV ;BUILD AOBJN POINTER
ADDI T1,K.DUDB(P2) ;POINT TO UDB TABLE
SKIPE P3,(T1) ;ANY UDB THERE?
CAME T4,UDBSLV(P3) ;YES, IS IT THIS UNIT?
AOBJN T1,.-2 ;NO, LOOK MORE
JUMPL T1,RSKP ;GOOD RETURN IF FOUND IT
RET ;ERROR RETURN
;GTRDEN - DETERMINE DENSITY OF TAPE AND STORE IN UDB
;CALLED AFTER DATA-TRANSFER AND SKIP-RECORD OPERATIONS
; P1/CDB, P2/KDB, P3/UDB
; CALL GTRDEN
; RETURNS +1: ALWAYS, DENSITY STORED IN U.HDEN
GTRDEN: PUSH P,Q2 ;SAVE Q2
MOVE Q2,K.DXAD(P2) ;GET DX20 UNIT# FOR GTSNS
HRRZ T4,UDBSLV(P3) ;GET SLAVE# FOR GTSNS
LOAD T1,USTYP,(P3) ;GET UNIT TYPE
JRST @GTRDND-.UTT70(T1) ;DISPATCH TO DRIVE-SPECIFIC CODE
GTRDND: IFIW!GRD70 ;TU70
IFIW!GRD71 ;TU71
IFIW!GRD72 ;TU72
IFIW!GRD73 ;TU73
GRD70: CALL GTSNS ;GET SENSE BYTES IN T1
JRST GTRDEX ;ERROR
MOVEI T2,.SJDN8 ;ASSUME 800 BPI
JRST GTRDE1
GRD72:
GRD73: CALL GTSNS ;GET SENSE BYTES
JRST GTRDEX ;ERROR
MOVEI T2,.SJD62 ;ASSUME 6250 BPI
GTRDE1: TXNE T1,S3.D16 ;1600-BPI FLAG SET?
MOVEI T2,.SJD16 ;YES, SAY 1600
MOVEM T2,U.HDEN(P3) ;STORE IN UDB
GRD71:
GTRDEX: POP P,Q2 ;RESTORE Q2
RET
SUBTTL DISPATCH FOR DX20
DXADSP::JRST DX2INI ;0 - INITIALIZATION
JRST DX2SIO ;1 - START I/O
JRST DX2INT ;2 - HANDLE INTERRUPT (DATA OPERATION OR SPACE)
JRST DX2ERR ;3 - ERROR RECOVERY
JRST DX2HNG ;4 - HUNG DEVICE
RET ;5 - NOT USED
RET ;6 - NOT USED
JRST DX2SIO ;7 - START POSITION OPERATION
JRST DX2ATN ;10 - ATTENTION INTERRUPT (CALLED AS MANY
; TIMES AS THERE ARE DX20 DRAS BITS UP)
JRST DX2PRQ ;11 - SKIP IF POSITION REQUIRED
RET ;12 - STACK SECOND COMMAND, FAIL FOR DX20
JRST DX2EXT ;13 - CHECK LEGALITY AND EXISTANCE OF A UNIT
JRST DX2CCK ;14 - CHECK FOR HALTED MICROCODE
DX2HNG: MOVX T1,<IS.DVE!IS.ERR!IS.NRT> ;SET FATAL BITS
IORM T1,IRBSTS(P4) ;AND REFRESH IT
RET
;HERE TO DETERMINE IF THIS REQUEST SHOULD GO ON PWQ OR TWQ
DX2PRQ: LDB T1,IRYFCN ;GET FUNCTION
MOVE T1,DX2FTB(T1) ;GET TABLE ENTRY
TXNN T1,TB.DOP ;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
;HERE TO SEE IF A PARTICULAR UNIT EXISTS ON THIS DX20.
; Q2/ UNIT TO CHECK
;RETURNS:
; +1: T1/ 0 UNIT IS ILLEGAL
; T1/ -1 NONEXISTANT UNIT
; +2: UNIT EXISTS
DX2EXT: SKIPL T4,Q2 ;MOVE TO RIGHT AC AND CHECK LEGALITY
CAIL T4,MAXDRV
JRST RFALSE ;UNIT NUMBER IS ILLEGAL
CALL DRVSRC ;SEE IF THIS UNIT IS EXISTANT
JRST RTRUE ;NO
RETSKP ;YES, SKIP RETURN
SUBTTL DX20 INITIALIZING ROUTINE
;DX2INI - INITIALIZATION ROUTINE
;THIS ROUTINE IS CALLED ONCE PER DX20 DRIVE ON THE SYSTEM
;AND BUILDS A KDB FOR THE DX20 AND A UDB FOR EACH TAPE DRIVE
;THAT HAS TUA OR TUB SET IN SENSE BYTE 1. CALL:
; P1/ CDB
; Q2/ DX20 NUMBER
; P5/ UNIT NUMBER TO BE INITIALIZED, OR -1 FOR ALL UNITS
; CALL DX2INI
; RETURN +1: ALWAYS
; T1/KDB
DX2INI: SAVEQ ;SAVE REGISTERS
JUMPL P5,INILB ;CHECK FOR ONLY 1 UNIT
MOVE P2,CDBIUN(P1) ;GET KDB ADDRESS IF IT EXISTS
ADD P2,Q2 ;POINT TO CORRECT UNIT
MOVE P2,0(P2) ;GET ENTRY
SKIPE P3,P2 ;FOUND ONE?
JRST INILA ;ALREADY GOT ONE
INILB: CALL CHKMIC ;CHECK THE MICROCODE IN DX20
JRST [BUG(DX2MCF)
RET]
MOVX T1,LK.DX2 ;LENGTH OF KDB
CALL PHYALC ;RESERVE SPACE
RET ;RETURN IF NO SPACE FOUND
MOVE P2,T1 ;SAVE ADDRESS OF KDB IN PROPER AC
MOVE P3,T1 ;NEED POINTER OF KDB ALSO IN P3
MOVEI T1,.BTKDB ;MARK AS A KDB
DPB T1,USYBKT ;SET .BTKDB IN KDB
CALL GTVER ;PUT MICROCODE VERSION NUMBER IN T2
MOVEM T1,K.DVER(P2) ;SAVE DX20 MICROCODE VERSION IN THE KDB
MOVEI T1,STADDR ;STARTING ADDRESS OF DX20
CALL STDX ;START THE DX20 MICROCODE
MOVX T1,.UTDXA ;SET UP UNIT TYPE IN KDB
STOR T1,USTYP,(P2) ;THIS IS A DX20 CONTROLER
MOVSI T1,-NUMDRV ;SET UP AOBJN INDEX
HRRI T1,K.DUDB(P2) ;MAKE RH POINT TO UDB ENTRIES IN KDB
MOVEM T1,KDBIUN(P2) ;INITIAL POINTER
MOVEM T1,KDBCUN(P2) ;CURRENT POINTER
HRRZM Q2,K.DXAD(P2) ;SAVE KDB ADDRESS
MOVEI T1,DXADSP ;INSERT DISPATCH VECTOR
MOVEM T1,KDBDSP(P2) ; ...
SETZM K.DNUM(P2) ;CLEAR NUMBER OF UDB'S IN EXISTANCE
INILA: SKIPL Q1,P5 ;GET POSSIBLE SPECIFIC SLAVE NUMBER
TLOA Q1,-1 ;WAS ONE, DO ONLY 1 TIME
MOVSI Q1,-MAXDRV ;WANTS ALL DRIVES, SET UP AOBJN INDEX
INILP: HRRZ T4,Q1 ;GET CURRENT SLAVE #
CALL GTSNS ;GET SENSE BYTES(0-3) IN T1
JRST NODRV ;FAIL TO GET SENSE BYTES, TRY NEXT
TXNN T1,S1.TUA+S1.TUB ;IS IT IN EXISTENCE?
JRST NODRV ;NO, JUMP
MOVE Q3,T1 ;SAVE SENSE BYTES 0-3
MOVE T3,K.DNUM(P2) ;GET NUMBER OF DRIVES FOUND SO FAR
CAIL T3,NUMDRV ;ROOM IN K.DUDB TABLE?
JRST TOORET ;NO, GO COMPLAIN
SKIPN T3,MTINDX ;GET AOBJN INDEX TO LOGICAL TABLE
HRLOI T3,-MTAN-1 ;IF 1ST TIME THRU
INILP1: AOBJP T3,TOORET ;LOSE IF TOO MANY DRIVES
SKIPE MTCUTB(T3) ;IS THIS ENTRY ALREADY IN USE?
JRST INILP1 ;YES, TRY NEXT
MOVEM T3,MTINDX ;SAVE CURRENT LOGICAL INDEX
MOVE T3,[DXADSP,,LU.DX2] ;SET UP ADDRESS,,LENGTH
CALL PHYUDB ;AND ASK FOR UDB ALLOCATION
RET ;RETURN IF NO SPACE FOUND
AOS T3,K.DNUM(P2) ;ADVANCE TO NEXT FREE UDB ENTRY
ADDI T3,K.DUDB-1(P2) ;POINT TO THE NEW TABLE ENTRY
HRRZM P3,(T3) ;SAVE LINK
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 T3,US.TAP ;T3 AS MASK FOR UDBSTS, ITS TAPE UNIT
TXNE Q3,S1.FP ;WRITE-PROTECTED?
TXO T3,US.WLK ;YES, MARK IT
HLLM T3,UDBSTS(P3) ;SAVE STATUS IN UDB
SETOM U.HDEN(P3) ;INDICATE UNKNOWN DENSITY
MOVEI T1,1 ;INDEX FOR SENSE BYTES 4 - 7
CALL GETEXS ;READ IN SENSE BYTES 4 - 7 INTO T1
JRST UPERR ;UPDATE FAILED
MOVX T2,.UTT70 ;ASSUME TU70 (800/1600 9 TRK)
TXNE T1,S6.DD ;IS IT 1600/6250?
MOVX T2,.UTT72 ;CALL IT A TU72 (1600/6250 9TRK, 125 IPS)
TXC T1,<S6M.73>B27
TXCN T1,<S6M.73>B27 ;IS IT A TU73?
MOVX T2,.UTT73 ;CALL IT A TU73 (1600/6250 9 TRK, 200 IPS)
TXNE T1,S6.7TK ;IS IT A 7 TRK DRIVE?
MOVX T2,.UTT71 ;CALL IT A TU71 (200/556/800 7TRK)
STOR T2,USTYP,(P3) ;PUT UNIT TYPE IN UDB
MOVE T1,[ UC.800!UC.160!UC.CD!UC.AA!UC.IC!UC.HD ;TU70
UC.200!UC.556!UC.800!UC.6B!UC.7TK ;TU71
UC.160!UC.625!UC.CD!UC.AA!UC.IC!UC.HD ;TU72
UC.160!UC.625!UC.CD!UC.AA!UC.IC!UC.HD ]-.UTT70(T2) ;TU73
MOVEM T1,UDBCHR(P3) ;STORE DENSITYS DRIVE IS CAPABLE OF
; IN THE UDB
MOVEI T1,3 ;INDEX=3 FOR SENSE BYTES
CALL GETEXS ;READ IN SENSE BYTES 12 - 15
JRST UPERR ;JUMP, ERROR
ANDI T1,377 ;TAKE BYTE 15 ONLY
MOVE Q3,T1 ;TUCK IT AWAY FOR AWHILE
MOVEI T1,4 ;INDEX=4 FOR SENSE BYTES
CALL GETEXS ;READ IN SENSE BYTES 16 - 19
JRST UPERR ;ERROR, JUMP
LSH T1,-^D26 ;BYTE 16 AS LOW ORDER BYTE
LSH Q3,^D8 ;MAKE BYTE 15 HIGH ORDER BYTE
IOR T1,Q3 ;CONCATENATE INTO T1, AS SERIAL NUMBER
JUMPN T1,GOTSER ;0 IF TU70, OR TU71
HRRZ T1,Q1 ;GET PHYSICAL UNIT NUMBER ON THIS DX20
HRRZ T2,Q2 ;GET DX20 NUMBER ON THIS CHANNEL
IMULI T2,^D100 ;MAKE KONTROLLER IN THE 100s
ADD T1,T2 ;INCLUDE KONTROLLER NUMBER
HRRZ T2,CDBADR(P1) ;GET THE RH20 CONTROLLER NUMBER
IMULI T2,^D1000 ;MAKE RH20 CONTROLLER NUMBER IN 1000s
ADD T1,T2 ;PRESTO RH20#,DX20#,TAPE#
GOTSER: MOVEM T1,UDBDSN(P3) ;STORE SERIAL NUMBER FOR THE TAPE UNIT
HRRZM Q1,UDBSLV(P3) ;SET UP SLAVE ADDRESS
NODRV: MOVX T2,DXERR ;CLEAR THE DX20
CALL WTREG3 ; ERROR REGISTER
AOBJN Q1,INILP ;TRY NEXT SLAVE
MOVE T1,P2 ;TELL RETURN TO PUT KDB INTO CDB
RET
TOORET: BUG(DX2N2S) ;COMPLAIN ABOUT EXCESS OF DRIVES
MOVE T1,P2 ;TELL RETURN TO PUT KDB INTO CDB
RET
UPERR: BUG(DX2UPE)
RET ;RETURN
;DX2CCK - CALLED ONCE A MINUTE FROM PHYCHK TO SEE IF THE DX20
;HAS HALTED, AND IF SO TO TRY AND RESTART IT.
;ARGUMENTS:
; P1/ CDB
; P2/ KDB
; P3/ UDB (ANY ONE WILL DO)
;RETURNS:
; +1: ALWAYS
;TRASHES Q2
DX2CCK: MOVE Q2,K.DXAD(P2) ;GET CONTROLLER NUMBER
CALL HLTCHK ;IS MICROCODE STILL HAPPY?
CALL CHKMIC ;OR IS IT REAL SICK?
RET ;YES, NOTHING TO DO
AOS T1,K.STCT(P2) ;INCREMENT RESTART COUNTER
CAILE T1,STMAX ;TOO MANY UPS AND DOWNS?
RET ;YES, LET DX20 REST IN PEACE THEN
MOVEI T1,STADDR ;GET START ADDRESS
CALL STDX ;RESTART THE MICROCODE
MOVX T1,KS.HLT ;GET HALT FLAG
ANDCAM T1,KDBSTS(P2) ;SAY MICROCODE IS RUNNING AGAIN
RET ;AND RETURN
;CHKMIC - CHECKS THE MICROCODE IN DX20, TO SEE IF IT IS THE RIGHT ONE
; BY LOOKING INTO CRAM LOCATIONS 7 - 11
; P1/CDB, Q2/DX20 UNIT NUMBER
; CALL CHKMIC
; RETURN+1: ERROR RETURN
; RETURN+2: GOOD RETURN
CHKMIC: MOVX T2,DXMTR!MR.RES ;RESET THE
CALL WTREG3 ; DX20
MOVX T2,DXDR1!D1.IRE!D1.PCE!D1.PCI!7 ;SETUP PC AND
CALL WTREG3 ; FLAGS INTO THE PC REG
RDRG DXDR0 ;READ IR REG. SO TO GET C(LOC 7) OF CRAM
PUSH P,T1 ;SAVE IT
RDRG DXDTR ;GET DRIVE TYPE REG.
POP P,T2 ;RESTORE LOCATION 7 OF CRAM
CAME T1,T2 ;DRIVE TYPE MATCH?
RET ;NO, ERROR RETURN
RDRG DXDR7 ;CHECK ANY PARITY ERROR
TXNE T1,1B22 ;IRPER=1B22
RET ;ERROR
RDRG DXDR0 ;GET LOC.10
CAIE T1,100 ;IS LOCATION 10 = 100?
RET ;NO, ERROR
RDRG DXDR7 ;CHECK IR PARITY ERROR
TXNE T1,1B22 ;IRPER=1B22
RET ;ERROR RETURN
RDRG DXDR0 ;GET LOC.11
CAIE T1,042562 ;042562 IS THE MAGIC NUMBER
RET ;ERROR
RDRG DXDR7 ;CHECK IR PARITY ERROR
TXNE T1,1B22 ;IRPER=1B22
RET ;ERROR
RETSKP ;GOOD RETURN
SUBTTL START I/O ROUTINE
;DX2SIO - ROUTINE TO START I/O
; P1/CDB, P2/KDB, P3/UDB, P4/IORB
;IF IN ERROR RECOVERY, GET FUNCTION FROM RH(UDBERR)
; CALL DX2SIO
; RETURN +1: ERROR - COULDN'T START I/O
; RETURN +2: SUCCESS THROUGH CHSTRT
DX2SIO: HRRZ Q1,UDBERR(P3) ;GET FUNCTION IF ERROR RECOVERY
SKIPN Q1 ;IN ERROR RECOVERY?
LOAD Q1,ISFCN,(P4) ;NO, GET FN FROM IORB
SKIPG Q1,DX2FTB(Q1) ;VALID FN?
JRST BADSIO ;REFUSE TO START IT
SKIPGE IRBSTS(P4) ;MAKE SURE PAGEM NOT SET
JRST BADSIO ;IS SET REFUSE IT
CALL DX2CON ;CONNECT TO DRIVE (AND CLEAR ERRORS)
RET ;ERROR
MOVX T2,DO.FC ;IN CASE WE DON'T WANT TO LOAD FC
TXNE Q1,TB.NFC ;DO WE LOAD FC WITH SOMETHING SPECIAL?
JRST NOFC ;NO- LOAD 0
TXNN Q1,TB.DOP ;DATA OPERATION?
JRST DX2NDO ;NO, T2=-#RECORDS ON SPACE
MOVN T2,IRBCNT(P4) ;BYTE COUNT FROM IORB
LOAD T1,IRBDM,(P4) ;GET DATA MODE
CAIE T1,.SJDMH ;IS IT HIGH DENSITY MODE?
JRST DX2SI1 ;NO, JUMP
IDIVI T2,2 ;EVEN BYTE(36-BIT) COUNT?
JUMPN T3,BADSI1 ;ODD IS BAD FOR HI-DEN. MOD
DX2SI1: HLRZ T1,Q3 ;GET MULTIPLIER
JUMPE T1,DX2DO ;SAVE TIME IF FRAMES=BYTES
IMUL T2,T1 ;CALCULATE # FRAMES
JRST DX2DO ;WE'RE A DATA OPERATION
BADSIO: BUG(DX2IFS,<<Q1,D>>)
BADSI1: MOVX T1,<IS.ERR!IS.DVE!IS.NRT> ;MARK AN ERROR OCCURED
IORM T1,IRBSTS(P4) ;IN IORB
RET
DX2NDO: SKIPE UDBERR(P3) ;IN ERROR RECOVERY?
SKIPA T2,[-1] ;YES, SPACE 1 RECORD
MOVN T2,IRBCNT(P4) ;NO, DO # RECORDS FROM IORB
DX2DO: ANDI T2,177777 ;16 BITS OF FRM COUNT
HRLI T2,(DO.FC) ;DO FRM COUNT TO FRM COUNT REGISTER
NOFC: ANDI Q1,77 ;6 BITS OF DX20 FN
HRRZM P3,KDBACT(P2) ;SAVE CURRENT UDB IN KDB
JRST CHSTRT ;NOW START THINGS MOVING
;DX2CON - LOAD DRIVE NUMBER, DATA MODE AND DRIVE NUMBER INTO
; THE DX20. IF DOING ERROR RECOVERY AND THERE IS A TRACK-IN-ERROR
; BYTE (U.ETIE IS NEGATIVE) LOAD IT INTO THE DX20 AFTER
; LOADING THE DRIVE REGISTER.
; P1/CDB, P2/KDB, P3/UDB, & P4/IORB, AND Q1/ FUNCTION TABLE ENTRY
; CALL DX2CON
; RETURN+1: ERROR
; RETURN+2: GOOD RETURN
; Q3/NUMBER OF FRAMES PER BYTE
DX2CON: CALL HLTCHK ;MAKE SURE MICROCODE IS GOING
JRST BADSI1 ;NO, ABORT THE I/O
HRRZ T1,UDBSLV(P3) ;GET THE SLAVE NUMBER INTO T1
; THIS AC WILL BE USED ALSO TO PUT
; THE DRIVE MODE AND DATA MODE INTO
LOAD T4,USTYP,(P3) ;GET THE DRIVE TYPE
SUBI T4,.UTT70 ;MAKE 0 FOR TU70, 1 FOR TU71, 2 FOR TU72
; AND 3 FOR TU73
MOVE Q2,T4 ;NEED ANOTHER COPY LATER
MOVE Q3,UDBSTS(P3) ;GET THE STATUS FROM THE UDB
MOVX T2,TB.RD!TB.WRT ;IF A TU71 THEN WE NEED TO DO A MODE
; SET FOR EACH READ OR WRITE OPERATION
CAIN Q2,.UTT71-.UTT70 ;IS IT A TU71 (7 TRACK)
JRST DX2CO2 ;YES
TXNN Q3,US.BOT ;AT BOT?
JRST NOMOD ;NO, MODE SET NOT REQUIRED THEN
MOVX T2,TB.WRT ;ONLY DO MODE SET ON TU70, TU72, TU73
; IF A WRITE OPERATION OFF OF BOT
DX2CO2: TDNN Q1,T2 ;NEED TO DO A MODE SET?
JRST NOMOD ;NO
LSH T4,1 ;MUL BY 2 FOR TABLE OF DENSITYS
; THERE ARE 2 ENTRYS FOR EACH DRIVE
; TYPE. (ODD AND EVEN PARITY)
LOAD T3,IRBPAR,(P4) ;GET 1 BIT OF PARITY INFORMATION
ADD T4,T3 ;POINT TO THE ODD OR EVEN ENTRY
LOAD T2,IRBDN,(P4) ;GET THE DENSITY REQUESTED
CAILE T2,MAXDN ;DO WE ALLOW IT?
JRST BADSI1 ;NO, ILLEGAL DENSITY
LDB T3,DENPNT(T4) ;GET ENTRY FROM THE DENSITY TABLE
; (T2 IS USED AS AN INDEX IN THE
; BYTE POINTER IN DENTAB)
CAIN T3,DRV.IL ;ILLEGAL DENSITY FOR THIS DRIVE TYPE?
JRST BADSI1 ;YES
STOR T3,DRVMOD ;PUT DRIVE MODE IN T1
NOMOD: TXNN Q1,TB.RD!TB.WRD ;READ OR WRITE DATA OPERATION?
JRST NODMOD ;NOT A DATA TYPE OPERATION SO
; DON'T CHECK IF DATA MODE IS LEGAL
LOAD T2,IRBDM,(P4) ;GET THE DATA MODE REQUESTED
CAILE T2,MAXFN ;DO WE ALLOW IT?
JRST BADSI1 ;NO
SKIPG Q3,@FMTTAB(Q2) ;GET A COPY OF THE DX20 CODE FOR THIS
; TYPE OF DRIVE AND MODE REQUESTED
; (T2 IS USED AS AN INDEX IN FMTTAB)
;NEGATIVE INDICATES THE DATA MODE IS
; ILLEGAL FOR THIS TYPE OF DRIVE
JRST BADSI1 ;ILLEGAL DATA MODE
STOR Q3,DATMOD ;STORE DATA MODE IN T1
NODMOD: WRTRG DXGP1,(T1) ;TELL DX20 - DATA MODE, DRIVE MODE, DRIVE NUMBER
SKIPL T2,U.ETIE(P3) ;TRACK IN ERROR?
RETSKP ;GIVE WIN RETURN
TXO T2,TE.TIE ;YES, REQUEST TIE RECOVERY
HRLI T2,(DXGP3) ;REGISTER 23
CALL WTREG ;TELL DX20 TIE RECOVERY
SETZM U.ETIE(P3) ;CLEAR
RETSKP ;SKIP RETURN
SUBTTL ENTER HERE FROM RH20 COMMAND DONE INTERRUPT
;DX2INT - COME HERE TO PROCESS A DONE INTERRUPT.
; P1/CDB, P2/KDB
; IF KDBACT IS -1 IN THE LH THEN THERE WAS AN ATTENTION
; INTERRUPT PRECEDING THE DONE INTERRUPT AND A CHECK MUST
; BE MADE FOR ERRORS. THIS ALLOWS FASTER PROCESSING OF THE
; DONE INTERRUPT (NORMAL CASE) BUT DEPENDS UPON THE DX20
; GIVING AN ATTENTION INTERRUPT IF THERE IS AN ERROR
; CONDITION. THIS ROUTINE IS ONLY ENTERED FOR DATA TYPE
; OPERATIONS.
; CALL DX2INT
; RETURN+1: ERROR
; P3/UDB P4/IORB
; RETURN+2: NO ERROR
; P3/UDB P4/IORB
DX2INT: PUSH P,Q2 ;
PUSH P,Q1 ;WILL USE Q1 & Q2
SKIPN P3,KDBACT(P2) ;UDB SAVED ON THIS DX20?
JRST DX2INU ;NO, ERROR
SETZM KDBACT(P2) ;CLEAR THE CURRENT UDB
CALL SETIRB ;GET IORB POINTER INTO P4
HRRZ T4,UDBERR(P3) ;GET FTN CODE IF ERROR RECOVERY
SKIPN T4 ;IN ERROR RECOVERY?
LOAD T4,ISFCN,(P4) ;NO, GET FTN CODE FROM IORB
MOVE Q1,DX2FTB(T4) ;GET FTN TABLE ENTRY IN Q1
SETZ Q2, ;CLEAR FLAG WORD
TLZN P3,-1 ;WAS THERE AN ATTENTION INTERRUPT?
JRST DXENTY ;NO
CALL HARCHK ;GO CHECK IF ANY FATAL ERROR
; AND SETUP DRIVE STATUS IN Q2
JRST INTRET ;ERROR, JUST RETURN
TXNE Q2,DS.NMV ;TAPE MOVED?
JRST INTRET ;NO, RECOVERABLE ERROR
DXENTY: TXNE Q1,TB.REV ;ARE WE BACKWARDS?
SOSA UDBPS2(P3) ;YES, THEN SUBTRACT 1 RECORD
AOS UDBPS2(P3) ;NO, ADD 1
JUMPE Q2,CKCON1 ;QUICK PATH? (BIT 14 NOT SET IN STATUS REG)
TXNN Q2,DS.TM ;IS IT TAPE MARK?
JRST NOTM ;NOT TM
TXNE Q1,TB.REV ;ARE WE REVERSE
SOSA UDBPS1(P3) ;YES, BACK UP 1 FILE
AOS UDBPS1(P3) ;NO, FORWARD 1 FILE
NOTM: TXNE Q2,DS.BOT ;AT BOT?
CALL ATBOT ;YES, ZERO COUNTERS
NOBOT: TXNE Q2,DS.RTY ;RETRIABLE ERROR?
JRST INTRET ;YES, ERROR BITS SET IN IORB
CKCONI: TXNN Q1,TB.DOP ;DATA OPERATION?
JRST NOTWRT ;NO, DON'T CHECK CHANNEL
CKCON1: CALL CKERR ;SEE IF ANY CHANNEL ERRORS
SKIPA ;YES
JRST NODERS ;NO CHANNEL ERRORS
MOVX T3,<IS.ERR!IS.DTE> ;YES, ERROR- DO RETRY
IORM T3,IRBSTS(P4) ;SET IORB ERR (DATA ERR)
CALL RDALL ;GET ALL REGISTERS INTO THE KDB
JRST INTRET ;JUST RETURN
; DON'T BOTHER SETTING UP STATUS BITS
;HERE WHEN DONE INTERRUPT AND NO SAVED UDB
DX2INU: BUG(DX2NUD)
JRST INTRX ;GO CHECK ERROR AND ASYNCHR. STATUS
NODERS: TXNN Q1,TB.RD ;ARE WE READING?
JRST SPENTY ;NO, DON'T TELL ABT FRM COUNT
MOVX T1,US.BOT ;WERE WE AT BOT?
TDNE T1,UDBSTS(P3) ; ???
CALL GTRDEN ;YES - TRY TO FIGURE OUT DENSITY
MOVX T2,DO.FC ;GET FRM COUNT
CALL RDREG ;
ADDM T1,UDBRED(P3) ;ACCUMULATE FRAMES READ
AOS UDBRCT(P3) ;UPDATE READ COUNT
SKIPG T2,U.HDEN(P3) ;HARDWARE KNOW WHAT THE DENSITY IS?
LOAD T2,IRBDN,(P4) ;NO, GET THE SOFTWARE DENSITY
ADDM T1,@RSTATF-1(T2) ;ACCUMULATE FRAMES READ BY DENSITY
CALL CHKMOD ;GET AND CHECK DATA MODE
CAIN T2,.SJDMH ;HI-DENSITY MODE?
LSH T1,1 ;MUL BY 2 SINCE WHEN CALCULATING
; NUMBER OF BYTES READ WE FIGURE FOR 2 WORDS
JUMPE T3,NODIV ;SAVE TIME IF FRAMES=BYTES
IDIV T1,T3 ;CALCULATE # BYTES
SKIPE T2 ;REMAINDER?
ADDI T1,1 ;YES, ANOTHER BYTE
NODIV: MOVEM T1,IRBCNT(P4) ;TELL HOW MANY FRAMES ON READ
SPENTY: TXNN Q1,TB.WRD ;WRITE DATA?
JRST NOTWRT ;NO
CALL CHKMOD ;GET AND CHECK DATA MODE
MOVE T1,IRBCNT(P4) ;GET NUMBER OF FRAMES
CAIN T2,.SJDMH ;HI-DENSITY MODE
LSH T1,-1 ;
IMUL T1,T3 ;MAKE FRAMES
ADDM T1,UDBWRT(P3) ;ACCUMULATE FRAMES WRITTEN
LOAD T2,IRBDN,(P4) ;GET DENSITY
ADDM T1,@WSTATF-1(T2) ;ACCUMULATE FRAMES WRITTEN BY DENSITY
AOS UDBWCT(P3) ;UPDATE WRITE COUNT
NOTWRT: MOVX T2,<IS.BOT!IS.EOT!IS.TPM!IS.WLK> ;ZERO BITS
ANDCAM T2,IRBSTS(P4) ;DO IT TO IT
MOVX T3,<US.BOT> ;CLEAR BITS
ANDCAM T3,UDBSTS(P3) ; IN THE UDB
JUMPE Q2,INTRET ;QUICK WAY THROUGH?
TXNN Q2,DS.BOT ;AT BOT?
TXZ T2,IS.BOT ;NO
TXNE Q1,TB.WRT ;ARE WE WRITING?
TXNN Q2,DS.EOT ;AND AT EOT?
TXZ T2,IS.EOT ;NO TO EITHER
TXNN Q2,DS.TM ;TP MK
TXZ T2,IS.TPM ;NO, CLEAR TM FLAG
TXNE Q1,TB.REV ;SPACE REVERSE OR READ REVERSE
TXNN Q2,DS.BOT ;AND AT BOT?
SKIPA ;NO TO EITHER
TXO T2,IS.TPM ;YES TO BOTH,RETURN TAPE MARK
TXNN Q2,DS.WLK ;WRITE LOCKED?
TXZ T2,IS.WLK ;NO
IORM T2,IRBSTS(P4) ;AND SAVE IT (LEAVE ERR SET IF IT WAS SET)
TXNN Q2,DS.BOT ;AT BOT?
TXZ T3,US.BOT ;NO, CLEAR BIT
IORM T3,UDBSTS(P3) ;SAVE IT
INTRET: SKIPN UDBERR(P3) ;IN ERROR RECOVERY?
JRST INTR1 ;NO, JUMP
MOVX T3,<IS.ERR!IS.DTE!IS.DVE> ;YES, IN ERROR RECOVERY
TDNN T3,IRBSTS(P4) ;WAS IN ERROR?
CALL DX2RDR ;NO, COPY REGISTERS FOR ERROR BLOCK LOGGING
INTR1: CALL ASYNST ;GO TO TAKE CARE OF ANY ASYNCHRONOUS
; STATUS AND CLEAR THE ATTENTION BIT
INTR3: TXNE Q2,DS.ERR ;ANY KIND OF ERROR?
JRST INTR4 ;YES, THEN NEVER SKIP RETURN
TXNE Q1,TB.DOP ;DATA OPERATION?
AOS -2(P) ;YES, SKIP RETURN FROM CMD DONE INT
INTR4: POP P,Q1 ;POP STACK
POP P,Q2 ;
RET ;RETURN
;COMES HERE WHEN INTERRUPT AND NO UDB SAVED
INTRX: MOVE Q2,K.DXAD(P2) ;GET UNIT NUMBER OF DX20
RDRG DXSTR ;GET STATUS REGISTER
TXNN T1,SR.CER ;COMPOSITE ERROR BIT SET?
JRST INTRX2 ;NO, GO CHECK ASYNCHR. STATUS
MOVE T4,T1 ;REMEMBER THE STATUS REGISTER
RDRG DXERR ;READ IN ERROR REGISTER
BUG(DX2NUE,<<T4,D>,<T1,D>>)
MOVX T2,DXERR ;CLEAR THE DX20
CALL WTREG3 ; ERROR REGISTER
INTRX2: SETZB Q1,Q2 ;ZERO FUNCTION AND STATUS
JRST INTR1 ;CHECK ASYNST STATUS
;COME HERE TO CHECK IF MODE IS LEGAL
;C(P3) = UDB C(P4) = IORB
; CALL CHKMOD
;RETURN+1: ALWAYS
;C(T2) DATA MODE FROM IORB
;C(T3) NUMBER OF FRAMES PER BYTE
;C(T4) 0 FOR TU70, 1 FOR TU71, 2 FOR TU72
;
CHKMOD: LOAD T4,USTYP,(P3) ;GET TYPE OF DRIVE
SUBI T4,.UTT70 ;MAKE 0, 1, OR 2. (TU70, TU71, TU72)
LOAD T2,IRBDM,(P4) ;GET DATA MODE
CAIG T2,MAXFN ;RANGE CHECK THE FUNCTION
SKIPGE T3,@FMTTAB(T4) ;GET BYTES,,DX20 FUNCTION
JRST CHKMO1 ;ILLEGAL
HLRZS T3 ;RETURN FRAMES PER BYTE IN T3
RET ;RETURN
CHKMO1: BUG(DX2IDM,<<T2,D>>)
SETZ T3, ;ACT LIKE WORDS
RET ;RETURN
SUBTTL ATTENTION INTERRUPT HANDLING
;DX2ATN - COME HERE ON AN ATTENTION INTERRUPT
; THIS ROUTINE IS CALLED FOR ANY NONE DATA OPERATION AND ANY
; DATA OPERATION THAT HAS AN ERROR ASSOCIATED WITH IT.
; P1/CDB, P2/KDB
;IF ERR, IS.ERR AND EITHER <IS.DVE OR IS.DTE> WILL BE SET IN THE IORB
;IF IS.ERR NOT SET, WE ARE FINISHED WITH THIS IORB
; RETURN +1: IF ERROR
; P3/UDB IF ANY
; P4/0 IF DATA TYPE OPERATION
; RETURN +2: IF NO ERROR
; P3/UDB
DX2ATN: PUSH P,Q2 ;SAVE Q2
MOVE Q2,K.DXAD(P2) ;GET OUR MASSBUS ADDRESS
MOVX T2,1 ;
LSH T2,(Q2) ;MASK TO CLEAR OUR ATTENTION BIT
TXO T2,DXASR ;CLEAR THE ATTENTION
CALL WTREG3 ; BIT FOR THIS DX20
PUSH P,Q1
SETZ Q2, ;CLEAR FLAG WORD
HRRZ P3,KDBACT(P2) ;GET ACTIVE UDB (IF ANY)
JUMPE P3,INTRX ;IF NO UDB, JUMP
MOVX T1,US.ACT ;UNIT ACTIVE?
TDNE T1,UDBSTS(P3) ; ??
JRST CKNDOP ;YES
BUG(DX2UNA)
SETZB P3,KDBACT(P2) ;RESET SAVED UDB
JRST INTRX ;CHECK ERROR & ASYN. STATUS
CKNDOP: CALL SETIRB ;GET CURRENT IORB
HRRZ Q1,UDBERR(P3) ;GET FUNCTION CODE
SKIPN Q1 ;IN ERROR RECOVERY?
LOAD Q1,ISFCN,(P4) ;NO, GET IT FROM IORB
MOVE Q1,DX2FTB(Q1) ;GET FUNCTION ENTRY
TXNN Q1,TB.DOP ;DATA OPERATION?
JRST NDOP ;NO
MOVEI P4,0 ;YES, ENSURE RECALL AT INTERRUPT ENTRY
HRROS KDBACT(P2) ;FLAG ATTN INT
JRST INTR4 ;AND EXIT AS SOON AS POSSIBLE
NDOP: SETZM KDBACT(P2) ;CLEAR SAVED UDB
CALL HARCHK ;ANY FATAL ERRORS? (PUT DRIVE STATUS IN Q2,
; DX2FTB ENTRY IN Q1)
JRST INTRET ;YES, FATAL ERROR FOUND & RETURN
TXNE Q1,TB.TM ;WRITE TM OPERATION?
JRST DXENTY ;YES, USE DATA ROUTINES
TXNE Q1,TB.ERA ;ERASE OPERATION?
JRST NOTWRT ;YES, DON'T CHECK TAPE POSITION
TXNE Q1,TB.REW ;REWIND?
JRST REWSTA ;YES, CLEAR REC CNTRS
MOVX T1,US.BOT ;WERE WE AT BOT?
TDNE T1,UDBSTS(P3) ; ???
CALL GTRDEN ;YES - GET HARDWARE DENSITY
MOVX T2,DO.FC
CALL RDREG
MOVN T3,T1 ;NEGATE FRM COUNT
ANDI T3,177777 ;ITS ONLY 16 BIT NEG NR
TXNE Q2,DS.TM ;FILE MARK?
SUBI T3,1 ;SPACING OVER A FILE MARK DOESN'T
; COUNT IN THE REGISTER BUT WE TREAT
; FILE MARKS AS RECORDS
SKIPE T1,UDBERR(P3) ;ARE WE IN ERR RECOVERY?
JRST RTYATN ;YES
EXCH T3,IRBCNT(P4) ;SAVE RESIDUE (# RECORDS NOT SPACED)
SUB T3,IRBCNT(P4) ;CALCULATE # RECORDS MOVED
TXNE Q1,TB.REV ;IN REVERSE DIR?
MOVNS T3 ;YES, NEGATE
ADDM T3,UDBPS2(P3) ;UPDATE REC COUNT
MOVE T3,IRBCNT(P4) ;GET FRM COUNT AGAIN
JUMPE T3,NOCKER ;IF ALL RECORDS SPACED, DON'T CHECK ERR
RES1: TXNN Q2,DS.BOT!DS.EOT!DS.TM ;EARLY TERM OK IF EOT, BOT, OR TM
RESERR: JRST [ MOVX T1,IS.ERR!IS.DVE!IS.NRT ;INDICATE ERRORS
IORM T1,IRBSTS(P4)
JRST SPENTY]
; ...
; ...
;ALL RECORDS SPACED, DON'T BOTHER CHKING ERROR BITS
NOCKER: TXNN Q2,DS.TM ;TAPE MK?
JRST NOSTM ;NO
TXNE Q1,TB.REV ;IN REVERSE DIR?
SOSA UDBPS1(P3) ;YES, THEN -1
AOS UDBPS1(P3) ;NO, THEN +1 FILE
NOSTM: TXNE Q2,DS.BOT ;AT BOT?
REWENT: CALL ATBOT ;CLEAR COUNTERS
JRST SPENTY ;NOW SET STATUS AND RET
REWSTA: MOVX T1,US.REW ;SET REWINDING
IORM T1,UDBSTS(P3) ; IN THE UDB
JRST REWENT ;
;COME HERE AT END OF SPACE DURING RETRY
RTYATN: JUMPN T3,RTYAT2 ;FRAME COUNT 0?
TXNN Q1,TB.REV ;IN REVERSE DIRECTION?
AOSA T1,UDBPS2(P3) ;NO FORWARD THE RECORD COUNTER
SOS T1,UDBPS2(P3) ;YES, BACK IT UP
TXNN Q2,DS.BOT ;AT BOT?
JUMPGE T1,NOCKER ;ONLY JUMP IF RECORD COUNT
; DIDN'T GO NEGATIVE
JRST RESERR ;CONFUSED ERROR RECOVERY
RTYAT2: SKIPE U.ETCF(P3) ;TAPE CLEANER SEQUENCE?
TXNN Q2,DS.BOT ;YES, DID WE BACK INTO BOT?
JRST RESERR ;NOT CLEANER SEQ
JRST REWENT ;UPDATE OUR POSITION
ATBOT: SETZM UDBPS1(P3) ;FILE 0
SETZM UDBPS2(P3) ;RECORD 0
SETOM U.HDEN(P3) ;INDICATE UNKNOWN HARDWARE DENSITY
RET ;RETURN TO CALLER
SUBTTL ERROR RETRY ENTRY POINT
;DX2ERR - HERE TO ATTEMPT ERROR RECOVERY
; P1/CDB, P2/KDB, P3/UDB, Q1/ERROR BLOCK ADDRESS IF ANY
; CALL DX2ERR
; RETURN+1:
; RETURN+2:
DX2ERR: SAVEQ
CALL SETIRB ;GET OUR IORB
HRRZ Q1,UDBERP(P3) ;GET ERROR BLOCK IF PRESENT
HLLZ T1,IRBSTS(P4) ;GET IORB STATUS
HRRZ T4,UDBERR(P3) ;GET FUNCTION IF ERROR RECOVERY
SKIPN T4 ;IN ERROR RECOVERY?
LOAD T4,ISFCN,(P4) ;NO, GET FN FROM IORB
MOVE T4,DX2FTB(T4) ;NOW TABLE ENTRY
TXNN T1,<IS.NRT!IS.IER> ;FATAL OR INHIBIT ERR RECOVERY?
JRST DXERTY ;NO, RETRY THE ERROR
SKIPE U.EBP(P3) ;WAS FATAL ERR DURING RETRY?
JRST ABTNOS ;YES, WE ALREADY HAVE BEGIN DATA
AOS (P) ;SKIP RET FROM BEGLOD - DONE WITH IORB
JRST BEGLOD ;LOAD UP ERR BLK FOR FATAL ERR
;DO RETRY
DXERTY: HLR T4,T4 ;COPY LH OF FNTBL
TRZ T4,777770 ;SAVE ONLY RETRY INDEX IN RH
SKIPE UDBERC(P3) ;1ST TIME FOR HERE?
JRST NOT1ST ;NO
SETZM U.ETCF(P3) ;NOT DOING TAPE CLEAN
SKIPN T1,RTYBPT(T4) ;GET RETRY BYTE POINTER
JRST [ BUG(DX2IDX)
JRST ABTNOS] ;CALL IT FATAL
MOVEM T1,U.EBP(P3) ;SAVE IT
MOVE T1,UDBPS2(P3) ;GET # RECORDS
SUBI T1,1 ;CALCULATE WHERE WE SHOULD BE AFTER REPOS
TXNE T4,TB.REV ;IF IN FORWARD, WE WANT (CUR POSITION-1)
ADDI T1,2 ;IF REVERSE, WE WANT (CUR POSITION+1)
MOVEM T1,U.EPOS(P3) ;WHERE WE SHOULD BE SOMEDAY
MOVEI T1,RTYWRT+1 ;ON WRITE, THIS MANY RETRIES
TXNN T4,TB.WRT ;ARE WE RIGHT (WRITE)?
MOVE T1,[RTYCLN+1,,RTYOP+1] ;NO, THIS IS FOR READ
MOVEM T1,UDBERC(P3) ;THE RETRY COUNTER
CALL BEGLOD ;LOAD UP ERR BLK WITH BEGIN DATA
JRST NXTBYT ;1ST TIME THRU DX2ERR
NOT1ST: MOVE T1,U.EBP(P3) ;GET RETRY BYTE POINTER
ILDB T1,T1 ;LOOK AT NEXT OPERATION
CAIE T1,RTY.DN ;END OF RETRY
JRST CKBOT ;NO
HLLZ T1,IRBSTS(P4) ;GET IORB STATUS
TXNN T1,IS.DTE ;WAS THERE DATA ERR?
JRST RTYNOE ;NO, WE'VE RECOVERED!
MOVE T1,RTYBPT(T4) ;GET BYTE POINTER
MOVEM T1,U.EBP(P3) ;RESET IT
SETZM U.ETCF(P3) ;NOT DOING TAPE CLN SEQUENCE
HRRZ T1,UDBERC(P3) ;GET ABORT COUNTER
SUBI T1,1 ;ANOTHER RETRY - SEE IF WE'VE LOST
HRRM T1,UDBERC(P3) ;SAVE IT
JUMPN T1,NXTBYT ;IF NOT 0, TRY AGAIN
TXNE T4,TB.DOP ;DATA OPERATION?
TXNN T4,TB.RD ;WRITE OR READ?
JRST ABTRTY ;NON DATA OR WRITE - WE'VE FAILED
HLRZ T1,UDBERC(P3) ;GET TAPE CLNR COUNTER
SOJE T1,ABTRTY ;RUN OUT OF RETRIES? - YES
HRLM T1,UDBERC(P3) ;NO, UPDATE CLN COUNTER
MOVX T1,RTYOP+1 ;NOW RESET (RH) COUNTER
HRRM T1,UDBERC(P3) ;FOR NEXT CLEAN RETRY
MOVE T1,RTYBPT+1(T4) ;GET CLEANER SEQ BYTE POINTER
MOVEM T1,U.EBP(P3) ;SAVE FOR USE LATER
SETZM E.EBC(P3) ;RESET COUNT FOR USE IF WE HIT BOT
SETOM U.ETCF(P3) ;WE ARE DOING A CLEAN
JRST NXTBYT ;NOW DO NEXT OPERATION
CKBOT: SKIPN U.ETCF(P3) ;DOING TAPE CLEAN?
JRST NXTBYT ;NO DON'T CHECK BOT
HLLZ T1,IRBSTS(P4) ;GET STATUS
TXNE T1,IS.BOT ;OR DID WE HIT BOT?
SKIPA T1,[CLNREC] ;YES, FIGURE OUT HOW TO FUDGE BYTE POINTER
JRST NXTBYT ;NO, CONTINUE NORM RETRY
LOAD T3,ISFCN,(P4) ;GET ORIGINAL FN
MOVE T3,DX2FTB(T3) ;GET FLAGS
TXNE T3,TB.WRT ;IS IT A WRITE?
JRST NXTBYT ;WRITE RETRY WON'T EVER HIT BOT SO NO FUDGE
TXNN T3,TB.REV ;ADD 1 IF FORWARD
ADDI T1,1 ;DO IT ON FORWARD
SUB T1,E.EBC(P3) ;SUBT # RECORDS SPACED
LSH T1,1 ;TIMES 2 (COMMENTS ASSUME CLNREC=5)
ADDI T1,1 ;ON FORWARD, SKIP (6-CNT)*2+1 BYTES
CAIL T1,1 ;ON REVERSE, SKIP (5-CNT)*2+1 BYTES
CAILE T1,^D9 ;RESULT MUST BE BETWEEN 1 AND 9
JSP CX,CNFERR ;BAD INCR, WE ARE CONFUSED
ADJBP T1,U.EBP(P3) ;ADJUST POINTER
MOVEM T1,U.EBP(P3) ; AND PUT ADJUSTED POINTER BACK
NXTBYT: AOS E.EBC(P3) ;ANOTHER BYTE FOR THE COUNTER
ILDB T3,U.EBP(P3) ;GET NEXT FUNCTION
CAIE T3,RTY.CP ;IS IT CHECK POSITION OPERATION?
JRST NOTCKP ;NO
MOVE T1,UDBPS2(P3) ;YES, GET OUR POSITION
CAMN T1,U.EPOS(P3) ;ARE WE WHERE WE WANT TO BE?
JRST NXTBYT ;YES, ALL OK
JSP CX,CNFERR ;POSITION CONFUSED,SIGNAL ERROR
JRST ABTNOS ;BOMB OUT
NOTCKP: CAIE T3,RTY.DN ;END OF RETRY?
SKIPG T3 ;IS FUNCTION VALID?
JRST [ BUG(DX2IRF)
JRST ABTNOS] ;IMAGINE FATAL
HRRM T3,UDBERR(P3) ;SAVE FUNCTION
CALL SETIO ;SET UP FOR I/O
CALL CDSSIO(T1) ;START IO
JRST ABTNOS ;COULDN'T START UP RETRY OPERATION
RET ;AND WAIT
RTYNOE: TXNE T1,IS.NRT ;HARD ERRS SHOULDN'T EVER GET HERE
BUG(DX2NRT)
MOVX T1,IS.ERR ;WE DID IT! CLEAR ERR BIT
ANDCAM T1,IRBSTS(P4) ;AND SKP RETURN
TXNN T4,TB.WRT ;ARE WE WRTING?
AOSA UDBSRE(P3) ;NO, A SOFT READ ERR
AOS UDBSWE(P3) ;YES, A SOFT WRITE ERR
JRST ABTNOS
;HERE WHEN ERROR RECOVERY GETS CONFUSED(FLAKEY HARDWARE W I L L DO IT)
CNFERR: BUG(DX2RFU)
MOVSI T1,(IS.ERR!IS.NRT) ;INDICATE RATHER HARD ERR
IORM T1,IRBSTS(P4) ; ...
JRST ABTNOS ;AND ABORT
ABTRTY: ;WE RAN OUT OF RETRIES
TXNN T4,TB.WRT ;ARE WE WRTING?
AOSA UDBHRE(P3) ;NO, A HARD READ ERR
AOS UDBHWE(P3) ;YES, A HARD WRITE ERR
ABTNOS: AOS (P) ;SKIP RET FROM ENDLOD
HRRZ Q1,UDBERP(P3) ;GET ERROR BLOCK
SKIPN U.EBP(P3) ;DONE ANY RETRIES?
JRST ENDLOD ;NO, LOAD UP ERR BLK WITH END DATA
TXNN T4,TB.WRT ;YES, IN A WRITE?
JRST RDCNT ;NO
MOVEI T1,RTYWRT+1 ;YES, CALCULATE # RETRIES DONE
SUBM T1,UDBERC(P3) ;RESIDUE
JRST ENDLOD ;NOW LOAD UP ERR BLK
RDCNT: HLRZ T1,UDBERC(P3) ;GET CLN COUNTER
IMULI T1,RTYOP ;CONVRT JUST TO # RETRIES
ADD T1,UDBERC(P3) ;ADD IN REGULAR RETRIES
MOVEI T2,<RTYCLN+2>*RTYOP+1 ;COUNT AT START
SUB T2,T1
HRRZM T2,UDBERC(P3) ;SAVE # RETRIES
JRST ENDLOD ;NOW LOAD UP ERR BLK
;BEGLOD - ROUTINE TO LOAD UP THE ERROR BLOCK AT
; THE START OF THE ERROR
; Q1/ERROR BLOCK ADDRESS
; CALL BEGLOD
; RETURN+1: ALWAYS
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
MOVE T1,[XWD ^D22,DX%MBR] ;COUNT,,OFFSET FOR DX20 MB REGISTER
MOVEM T1,SEBDAT+DX%MBI(Q1) ;STORE IN ERROR BLOCK
MOVE T1,[XWD ^D20,DX%ESR] ;COUNT,,OFFSET FOR EXTENDED STATUS TABLE
MOVEM T1,SEBDAT+DX%ESI(Q1) ;STORE IN ERROR BLOCK
MOVEI T1,SEBDAT+DX%MBR(Q1) ;MOVE REGISTERS TO HERE
MOVEM T1,T2 ;SAVE FOR RH OF BLT
ADDI T2,^D22+^D20-1 ;22 REGISTERS(WORDS)+20 WORD EXTENDED STATUS TABLE
HRLI T1,K.DREG(P2) ;GET REGISTERS FROM HERE
HRLI T2,(BLT T1,) ;SET UP INST FIELD
XCT T2 ;DO IT
RET
;ENDLOD - ROUTINE TO LOAD UP THE ERROR BLOCK AT
; THE END OF THE ERROR
; Q1/ERROR BLOCK ADDRESS IF ANY
; CALL ENDLOD
; RETURN+1: ALWAYS
ENDLOD: SETZM U.EBP(P3) ;ZERO, SO IF ERROR WITH IS.NRT
; SET ERROR DATA IS LOGGED AS
; BEGINNING DATA IN ERROR BLOCK
SETZM U.ETIE(P3) ;MAKE SURE TIE FLAG CLEAR
JUMPE Q1,R ;IF NO ERROR BLOCK, CANT SAVE DATA
MOVE T3,[-^D22,,K.DREG] ;CASE FOR START
ADD T3,P2 ;POINTS TO REGISTER DATA
MOVEI T2,SEBDAT+DX%MBR(Q1) ;REGISTER DATA GOES HERE
ENDLD1: MOVE T1,(T3) ;GET REGISTER
HRLM T1,(T2) ;PUT IT
ADDI T2,1 ;NEXT WD
AOBJN T3,ENDLD1 ;DONE?
MOVE T1,K.DCNI(P2) ;GET CONI
MOVEM T1,SEBDAT+MB%CIF(Q1) ;SAVE
MOVE T1,K.DCS1(P2) ;GET TCR
MOVEM T1,SEBDAT+MB%D1F(Q1) ;SAVE
MOVE T1,K.DDBF(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,K.DCNI(P2) ;CONI INITIAL
SEBPTR MB%D1I,SBTWD,K.DCS1(P2) ;TCR
SEBPTR MB%D2I,SBTWD,K.DDBF(P2) ;BAR/DBF
SEBPTR DX%VER,SBTWD,K.DVER(P2) ;VERSION NUMBR
NITAB==.-ITAB
SUBTTL DX20 FUNCTION TABLE
;EACH ENTRY MUST BE NON-0
;1B0 ;ILLEGAL FUNCTION
TB.WRT==1B1 ;THIS FUNCTION WRITES ON TAPE
TB.REV==1B2 ;THIS OPERATION MOVES TAPEIN REVERSE DIRECTION
TB.DOP==1B3 ;THIS IS A DATA OPERATION
TB.SPC==1B4 ;THIS IS A SPACE OPERATION
TB.RD==1B5 ;THIS IS A READ
TB.ERA==1B6 ;ERASE OPERATION
TB.TM==1B7 ;WRITE TAPE MARK
TB.NFC==1B8 ;DON'T LOAD FRM COUNT WHEN DOING OPERATION
TB.REW==1B9 ;OPERATION IS A REWIND
TB.WRD==1B10 ;THIS FUNCTION WRITES DATA ON TAPE
TB.UNL==1B11 ;UNLOAD COMMAND
;BITS 15,16,17 CONTAIN AN INDEX TO RTYBPT TO TELL US HOW
;TO RETRY AN OPERATION (0 IF NO RETRY)
;BITS 30-35 HAS MAJOR FUNCTION CODE FOR DX20
; BITS 21-26 HAS MINOR FUNCTION CODE FOR DX20
DX2FTB: 1B0 ;0- ILLEGAL
<TB.DOP!TB.RD>!2B17!XF.RDF ;1- READ FORWARD (IRFRED)
1B0 ;2- ILL (RD FMT)
<TB.WRT!TB.WRD!TB.DOP>!1B17!XF.WTF ;3- WRITE FORWARD (IRFWRT)
1B0 ;4- ILL (WRT FMT)
1B0 ;5- ILL (SEEK)
TB.SPC!XF.SPF ;6- SPCE FORWARD(BLOCK)
<TB.REV!TB.SPC>!XF.SPR ;7- SPCE REVERSE(BLOCK)
<TB.WRT!TB.TM>!6B17!XF.WTM ;10- WRITE TM
<TB.WRT!TB.ERA>!XF.ERA ;11- ERASE
<TB.NFC!TB.REW>!XF.REW ;12- REWIND
<TB.NFC!TB.UNL>!XF.UNL ;13- UNLOAD
<TB.REV!TB.DOP!TB.RD>!4B17!XF.RDR ;14- READ REVERSE
1B0 ;15- ILL (RECOVERY RD)
1B0 ;16- ILL
1B0 ;17- ILL
;CONVERT SOFTWARE MODE CODE TO TU70S FMT CODE (1B0 IS ILLEGAL)
;LH IS #FRAMES/BYTE (0 MEANS FRAMES=BYTES), RH IS TX02 FORMAT TYPE
M70FMT: 1B0 ;(0) ILLEGAL
XWD 5,DAT.CD ;(1) DUMP MODE
1B0 ;(2) SIXBIT
DAT.AS ;(3) ANSI ASCII
DAT.IC ;(4) INDUSTRY COMPATIBLE
XWD ^D9,DAT.HD ;(5) HI-DENSITY
MAXFN==.-M70FMT-1
M71FMT: 1B0 ;(0) ILLEGAL
1B0 ;(1) DUMP MODE
DAT.SB ;(2) SIXBIT
1B0 ;(3) ANSI ASCII
1B0 ;(4) INDUSTRY COMPATIBLE
1B0 ;(5) HI-DENSITY
FMTTAB: M70FMT(T2) ;TU70
M71FMT(T2) ;TU71
M70FMT(T2) ;TU72
M70FMT(T2) ;TU73
DEFINE DEN(E9PG,O9PG,E9NP,O9NP,E7NP,O7NP),<
BYTE (6) E9PG,O9PG,E9NP,O9NP,E7NP,O7NP
>;END DEFINE DEN
;TABLE OF DENSITYS FOR EACH TYPE OF DRIVE
;
DENTAB: DEN DRV.IL,DRV.IL,DRV.IL,DRV.IL,DRV.IL,DRV.IL ;(0) DRV.ILEGAL DENSITY
DEN DRV.IL,DRV.IL,DRV.IL,DRV.IL,DRV.E2,DRV.O2 ;(1) 200 BPI
DEN DRV.IL,DRV.IL,DRV.IL,DRV.IL,DRV.E5,DRV.O5 ;(2) 556 BPI
DEN DRV.IL,DRV.IL,DRV.IL,DRV.NR,DRV.E8,DRV.O8 ;(3) 800 BPI
DEN DRV.IL,DRV.PE,DRV.IL,DRV.PE,DRV.IL,DRV.IL ;(4) 1600 BPI
DEN DRV.IL,DRV.GC,DRV.IL,DRV.IL,DRV.IL,DRV.IL ;(5) 6250 BPI
MAXDN==.-DENTAB-1
;TABLE OF POINTERS TO DENTAB
; T2 CONTAINS THE DENSITY FROM THE IORB
;
DENPNT: POINT 6,DENTAB(T2),23 ;TU70 (9TRK 800/1600 ODD PARITY)
POINT 6,DENTAB(T2),17 ;TU70 (9TRK 800/1600 EVEN PARITY)
POINT 6,DENTAB(T2),35 ;TU71 (7TRK 200/556/800 ODD PARITY)
POINT 6,DENTAB(T2),29 ;TU71 (7TRK 200/556/800 EVEN PARITY)
POINT 6,DENTAB(T2),11 ;TU72 (9TRK 1600/6250 ODD PARITY)
POINT 6,DENTAB(T2),5 ;TU72 (9TRK 1600/6250 EVEN PARITY)
POINT 6,DENTAB(T2),11 ;TU73 (9TRK 1600/6250 ODD PARITY)
POINT 6,DENTAB(T2),5 ;TU73 (9TRK 1600/6250 EVEN PARITY)
;TABLE OF FRAMES READ/WRITTEN BY MODE (NRZI, PE, GCR)
RSTATF: UDBRNR(P3) ;(1) 200BPI - NRZI
UDBRNR(P3) ;(2) 556BPI - NRZI
UDBRNR(P3) ;(3) 800BPI - NRZI
UDBRPE(P3) ;(4) 1600BPI - PE
UDBRGC(P3) ;(5) 6250BPI - GCR
WSTATF: UDBWNR(P3) ;200 - NRZI
UDBWNR ;556 - NRZI
UDBWNR ;800- NRZI
UDBWPE(P3) ;1600 - PE
UDBWGC(P3) ;6250 - GCR
;RETRY TABLES TO TELL HOW TO RETRY
RTYBPT: 0 ;ILLEGAL RETRY
POINT 4,TBRWRT ;WRITE RETRY
POINT 4,TBRRF ;READ FORWARD RETRY
POINT 4,TBRRFC ;READ FORWARD TAPE CLEAN
POINT 4,TBRRR ;READ REVERSE RETRY
POINT 4,TBRRRC ;READ REVERSE TAPE CLEAN
POINT 4,TBRWTM ;WRITE TAPE MARK
0 ;ILLEGAL
;THE FOLLOWING MACROS HELP ME GET AROUND SOME SHORTCOMINGS IN MACRO:
;NOTE: THE MACRO'S MUST BE FIXED IN THE UNLIKELY EVENT THAT
;SOMEBODY WANTS TO CHANGE TO A BYTE SIZE WHICH DOESN'T GO
;EVENLY INTO 36(10). RIGHT NOW IT'S 4.
DEFINE FOO (XXA) <
WD==0
BYC==0
ZZ==0 ;FLIP-FLOP
IRP XXA,<
IFE ZZ,<RP==XXA>
IFN ZZ,<FOO1 RP,XXA>
ZZ==ZZ+1
IFE ZZ-2,<ZZ==0>>
IFN BYC,<EXP WD>>
DEFINE FOO1 (A1,A2) <
REPEAT A1,<
WD==WD+<A2>B<4*BYC+3>
BYC==BYC+1
IFGE BYC-^D9, <
EXP WD
WD==0
BYC==0>>>
TBRWRT: BYTE (4) IRFBSB,IRFERG,RTY.CP,IRFWRT,RTY.DN
;WRITE RETRY - SPACE REVERSE, ERASE, CHECK POSITION, WRITE
TBRWTM: BYTE (4) IRFBSB,IRFERG,RTY.CP,IRFWTM,RTY.DN
;WRITE TM RETRY - SPACE REVERSE, ERASE, CHECK POS, WTM, EOR
TBRRF: BYTE (4) IRFBSB,RTY.CP,IRFRED,RTY.DN
;READ FORWARD RETRY - SPACE REVERSE, CHECK POSITION, READ FORWARD
TBRRR: BYTE (4) IRFFSB,RTY.CP,IRFRDR,RTY.DN
;READ REVERSE RETRY - SPACE FORWARD, CHECK POSITION, READ REVERSE
TBRRFC: FOO<CLNREC+1,IRFBSB, CLNREC,IRFFSB, 1,RTY.CP, 1,IRFRED, 1,RTY.DN>
;RD FORWARD TAPE CLEAN: 6 SP REVERSE, 5 SP FORWARD, CHECK POSITION, RD FORWARD
TBRRRC: FOO<CLNREC,IRFBSB, CLNREC+1,IRFFSB, 1,RTY.CP, 1,IRFRDR, 1,RTY.DN>
;RD REVERSE TAPE CLEAN: 5 SP REVERSE, 6 SP FORWARD, CHECK POSITION, RD REVERSE
TNXEND
END