Trailing-Edge
-
PDP-10 Archives
-
BB-Y393M-SM
-
monitor-sources/phyp4.mac
There are 52 other files named phyp4.mac in the archive. Click here to see a list.
; *** Edit 7375 to PHYP4.MAC by JROSSELL on 3-Oct-86, for SPR #21186
; On an HCE without a HCRC, do a recalibrate if offsetting does not clear the
; error.
; UPD ID= 279, FARK:<4-1-WORKING-SOURCES.MONITOR>PHYP4.MAC.2, 6-Jan-83 14:03:44 by DONAHUE
;Edit 2894 - Change RP4UNF to a Bugchk
;<4-1-FIELD-IMAGE.MONITOR>PHYP4.MAC.2, 25-Feb-82 20:44:51, EDIT BY DONAHUE
;UPDATE COPYRIGHT DATE
; UPD ID= 2, FARK:<4-WORKING-SOURCES.MONITOR>PHYP4.MAC.3, 22-Jul-81 14:47:40 by MOSER
;EDIT 1913 - Set US.PSI in RP4INI so device allocator knows about the new pack.
; UPD ID= 488, FARK:<4-WORKING-SOURCES.MONITOR>PHYP4.MAC.2, 29-Apr-81 14:22:35 by ZIMA
;Edit 1860 - increase retry count before ECC is applied. See 4.2106.
;<4.MONITOR>PHYP4.MAC.10, 3-Jan-80 08:10:13, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.MONITOR>PHYP4.MAC.9, 15-Nov-79 15:24:58, EDIT BY DBELL
;TCO 4.2572 - MAKE PORT CONTENTION WORK PROPERLY AT RP4CN2 AND RP4ATU
;<OSMAN.MON>PHYP4.MAC.1, 10-Sep-79 16:00:38, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>PHYP4.MAC.7, 4-May-79 11:00:12, EDIT BY ENGEL
;USE INTERRUPTS TO FORCE RELEASE OF DUAP-PORT DEVICE (RP4CN2 & RP4ATU)
;<4.MONITOR>PHYP4.MAC.6, 5-Mar-79 15:53:41, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>PHYP4.MAC.5, 4-Dec-78 19:37:55, EDIT BY BOSACK
;TCO 4.2106 - DEFER ECC APPLICATION UNTIL DRIVE HAS SETTLED ON CYL
;<2MCLEAN>PHYP4.MAC.4, 30-Jul-78 15:16:13, Edit by MCLEAN
;<2MCLEAN>PHYP4.MAC.3, 30-Jul-78 14:46:26, Edit by MCLEAN
;<4.MONITOR>PHYP4.MAC.2, 22-Jul-78 22:11:23, Edit by MCLEAN
;<1MCLEAN>PHYP4.MAC.83, 6-May-78 21:45:28, Edit by MCLEAN
;<1MCLEAN>PHYP4.MAC.82, 6-May-78 21:40:57, Edit by MCLEAN
;ADD RP07 CODE
;<1MCLEAN>PHYP4.MAC.81, 6-May-78 21:40:37, Edit by MCLEAN
;<3.SM10-RELEASE-3>PHYP4.MAC.79, 3-Apr-78 18:49:52, Edit by MCLEAN
;FIX ATNXIT NOT TO CLEAR CHANNEL ON TRANSFERING DRIVE
;<3A.MONITOR>PHYP4.MAC.79, 8-Mar-78 23:58:51, Edit by MCLEAN
;CLEAR DRIVE AT ATNXIT
;<2BOSACK>PHYP4.MAC.77, 24-Feb-78 01:25:42, EDIT BY BOSACK
;CHANGE DEVICE/DATA ERROR FLAGGING
;<2BOSACK>PHYP4.MAC.76, 15-Feb-78 02:09:13, EDIT BY BOSACK
;<4.MONITOR>PHYP4.MAC.76, 1-Feb-78 14:52:23, Edit by MCLEAN
;FIX FOR NEW PHYUDB CALLING SEQ
;<2BOSACK>PHYP4.MAC.75, 30-Jan-78 02:37:06, EDIT BY BOSACK
;<2BOSACK>PHYP4.MAC.74, 27-Jan-78 02:14:45, EDIT BY BOSACK
;<2BOSACK>PHYP4.MAC.73, 25-Jan-78 03:46:02, EDIT BY BOSACK
;<2BOSACK>PHYP4.MAC.72, 25-Jan-78 03:40:58, EDIT BY BOSACK
;REORGANIZED DISK PHYSICAL PARAMETER TREATMENT
;CHANGED LATOPT TO USE UDB FOR PHYSICAL PARAMETERS
;MINOR (10USEC ON A 2050) SPEEDUPS
;<2BOSACK>PHYP4.MAC.71, 15-Jan-78 20:50:53, EDIT BY BOSACK
;<2BOSACK>PHYP4.MAC.70, 15-Jan-78 20:47:30, EDIT BY BOSACK
;CHANGES FOR RM03 ECC DIFFERENCES
;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,1980,1981,1982 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG,SERCOD ;SYSTEM PARAMETERS
TTITLE (PHYP4,,< - DEVICE DEPENDENT CODE FOR RP04 DISKS>)
SUBTTL T.HESS, T WACHS/TAH/TW/LB 2 JULY 75
SEARCH PHYPAR ;PARAMETERS
ENTRY RP4DSP ;FOR LIBRARY SEARCH
SUBTTL PARAMETERS
;DRIVE REGISTERS
DO.DRC==(0B5) ;DRIVE CONTROL REGISTER
DO.SR==(1B5) ;STATUS REGISTER
DO.ER==(2B5) ;ERROR REGISTER
DO.AS==(4B5) ;ATTENTION SUMMARY
DO.DA==(5B5) ;DESIRED ADDRESS (TRACK/SECTOR)
DO.DT==(6B5) ;DRIVE TYPE
DO.LA==(7B5) ;LOOK AHEAD
DO.SN==(10B5) ;DRIVE SERIAL NUMBER
DO.OF==(11B5) ;OFFSET REGISTER
DO.DC==(12B5) ;DESIRED CYLINDER
DO.ER3==(15B5) ;ERROR REGISTER # 3
DO.ECP==(16B5) ;ECC POSITION
DO.ECB==(17B5) ;ECC BURST (PATTERN)
;DRIVE FUNCTIONS
DF.UNL==3 ;UNLOAD
DF.SEK==5 ;SEEK
DF.RCL==7 ;RECALIBRATE
DF.CLR==11 ;DRIVE CLEAR
DF.REL==13 ;RELEASE (DUAL PORT)
DF.OFS==15 ;OFFSET POSITION
DF.RTC==17 ;RETURN TO CENTERLINE
DF.PST==21 ;READIN PRESET
DF.ACK==23 ;PACK ACKNOWLEDGE
DF.SRC==31 ;SEARCH
DF.WRT==61 ;WRITE DATA
DF.WTF==63 ;WRITE FORMAT
DF.RED==71 ;READ DATA
DF.RDF==73 ;READ FORMAT
F22==100 ;22-SECTOR MODE (SOFTWARE ONLY)
ERETRY==200 ;ERROR RETRY (ECC FIXED 1ST PART) SOFTWARE ONLY
DXES==200000 ;DISABLE STOP ON ERROR
;BITS IN CONTROL REGISTER
CR.DVA==4000 ;DEVICE AVAILABLE - FOR DUAL PORT
;DRIVE STATUS REGISTER
DS.ATA==1B20 ;ATTENTION
DS.ERR==1B21 ;ERROR
DS.PIP==1B22 ;POSITION IN PROGRESS
DS.MOL==1B23 ;MEDIA ON LINE
DS.WRL==1B24 ;WRITE LOCKED
DS.LST==1B25 ;LAST SECTOR TRANSFERRED
DS.PGM==1B26 ;PROGRAMMABLE (DUAL PORT)
DS.DPR==1B27 ;DRIVE PRESENT
DS.DRY==1B28 ;DRIVE READY
DS.VV==1B29 ;VOLUME VALID
DS.GUD==DS.MOL!DS.DPR!DS.DRY!DS.VV
DS.MSK==DS.GUD!DS.ATA!DS.ERR!DS.PIP!DS.WRL ;MASK OF STATUS BITS TO CONSIDER
;DRIVE ERROR REGISTER
ER.DCK==1B20 ;DRIVE CHECK
ER.UNS==1B21 ;DRIVE UNSAFE
ER.OPI==1B22 ;OPERATION INCOMPLETE
ER.DTE==1B23 ;DRIVE TIMING ERROR
ER.WLE==1B24 ;WRITE LOCK ERROR
ER.IAE==1B25 ;INVALID ADDRESS ERROR
ER.AOE==1B26 ;ADDRESS OVERFLOW ERROR
ER.CRC==1B27 ;HEADER CRC ERROR
ER.HCE==1B28 ;HEADER COMPARE ERROR
ER.ECH==1B29 ;ECC HARD ERROR
ER.WCF==1B30 ;WRITE CLOCK FAILURE
ER.FER==1B31 ;FORMAT ERROR
ER.CPE==1B32 ;CONTROL BUS PARITY ERROR
ER.RMR==1B33 ;REGISTER MODIFICATION REFUSED
ER.ILR==1B34 ;ILLEGAL REGISTER
ER.ILF==1B35 ;ILLEGAL FUNCTION
ER.OFS==ER.DCK!ER.FER!ER.CRC!ER.HCE ;ERRORS ON WHICH TO TRY OFFSET
;OFFSET REGISTER
OF.F22==1B23 ;22-SECTOR MODE
OF.ECI==1B24 ;ERROR CORRECTION CODE INHIBIT
;ERROR REGISTER 3 STATUS BITS
E3.OCL==1B20 ;OFF CYLINDER
E3.SKI==1B21 ;SEEK INCOMPLETE
SUBTTL ERROR RECOVERY/REPORTING DEFINITIONS
;RETRY COUNTS
POSCNT==3 ;NUMBER OF TIMES TO RETRY ON POSITION FAILURE
DEVCNT==3 ;RETRIES ON DEVICE ERROR (NOT DATA OR HEADER) BEFORE RECALIBRATE
; MUST BE AT LEAST 3
RCLCNT==3 ;RECALIBRATES AFTER DEVCNT TRIES (TIMES FOR COMPLETE CYCLE)
;STATUS BITS IN LH(UDBERR)
ES.HRD==1B0 ;HARD ERROR
ES.ECC==1B1 ;ECC-CORRECTED ERROR
ES.DAT==1B2 ;DATA ERROR
ES.HDR==1B3 ;HEADER ERROR
ES.DEV==1B4 ;DEVICE ERROR (NEITHER DATA NOR HEADER)
ES.POS==1B5 ;POSITIONING ERROR
ES.FER==1B6 ;FORMAT ERROR (20-SECTOR PACK IN 22-SECT. MODE, ETC)
;UDB EXTENSIONS
RP.CNI==UDBDDP ;CONI OF RH GOES HERE
RP.CRC==RP.CNI+1 ;DATAI RH CONTROL REGISTER
RP.DBF==RP.CRC+1 ;DATAI RH DATA REGISTER
RP.CYL==RP.DBF+1 ;NUMBER OF CYLINDERS PER UNIT
RP.SCL==RP.CYL+1 ;NUMBER OF SECTORS PER CYLINDER
RP.SSF==RP.SCL+1 ;NUMBER OF SECTORS PER SURFACE
RP.USU==RP.SSF+1 ;NUMBER OF USEC PER LA REG UNIT
RP.USF==RP.USU+1 ;SSF * 64 (LA REG UNITS)
RP.LST==RP.USF+1 ;START OF LAST PAGE ON A CYLINDER
RP.REG==RP.LST+1 ;DRIVE REGISTERS GO HERE
DR.CRC==0 ;CONTROL REGISTER
DR.ST==1 ;STATUS
DR.ER==2 ;ERROR
DR.MT==3 ;MAINTENANCE
DR.ATA==4 ;ATTENTION SUMMARY
DR.DA==5 ;DESIRED ADDRESS
DR.DT==6 ;DRIVE TYPE
DR.LA==7 ;LOOK AHEAD
DR.SN==10 ;SERIAL NUMBER
DR.OF==11 ;OFFSET
DR.DC==12 ;DESIRED CYLINDER
DR.CA==13 ;CURRENT ADDRESS
DR.ER2==14 ;ERROR REGISTER # 2
DR.ER3==15 ;ERROR REGISTER # 3
DR.ECP==16 ;ECC POSITION
DR.ECB==17 ;ECC BURST
L.RP4==RP.REG+20 ;LENGTH OF RP04 UDB
;DISPATCH TABLE
RP4DSP: JRST RP4INI ;0 - INITIATION
JRST RP4SIO ;1 - START I/O
JRST RP4INT ;2 - HANDLE INTERRUPT
JRST RP4ERR ;3 - ERROR RECOVERY
JRST RP4HNG ;4 - HUNG DEVICE
JRST RP4CNV ;5 - CONVERT BLK # TO CYLINDER/SURF-SEC
JRST RP4LTM ;6 - LATENCY COMPUTATION
JRST RP4POS ;7 - START POSITIONING
JRST RP4ATN ;10- ATTENTION INTERRUPT
JRST RP4PRQ ;11- SKIP IF POSITIONING REQUIREDD
JRST RP4STK ;12- STACK SECOND TRANSFER COMMAND
;DUMMIES
RP4HNG: RET
;DISKS ARE CHECKED BY CALLING CNV AND CHECKING UDBPS1
RP4PRQ: RETSKP ;IF ASKED, SAY ALWAYS
;TRANSLATION FROM MASSBUS TYPE TO INTERNAL BLOCKTYPE
XTYPE: XWD .UTRP4,TY.RP4
XWD .UTRP5,TY.RP5
XWD .UTRP6,TY.RP6
XWD .UTRP7,TY.R7F
XWD .UTRP7,TY.R7M
XWD .UTRM3,TY.RM3
NXTYPE==.-XTYPE
SUBTTL INITIATION
;C(Q2) := UNIT NUMBER
RP4INI: SAVEQ
MOVE T3,[RP4DSP,,L.RP4] ;DISPATCH,,LENGTH
CALL PHYUDB ;SET UP UDB
RET ;RETURN IF NO SPACE
MOVSI T2,DO.DT ;READ DRIVE TYPE REGISTER
CALL RDREG ; ...
ANDI T1,777 ;MASK TO JUST DRIVE TYPE
MOVSI T2,-NXTYPE ;SEARCH TABLE FOR INTERNAL UNIT TYPE
INI1: MOVE T3,XTYPE(T2) ;GET TYPE WORD
CAIN T1,(T3) ;MATCH?
JRST INI2 ;YES
AOBJN T2,INI1 ;NO - ANY LEFT
;**;[2894] Remove 1 line, Add 2 at INI1:+4L PEd 6-JAN-83
JRST [ BUG(RP4UNF,<<T1,D>>);[2894]
RET ] ;[2894]
INI2: HLRZ T1,T3 ;FOUND - GET INTERNAL TYPE CODE
MOVE T4,T1 ;COPY FOR UDB BUILD LATER
MOVSI T2,-NDSKUT ;SEARCH TO FIND PHYSICAL PARAM TABLE
INI3: CAMN T1,DSKUTP(T2) ;MATCH?
JRST INI4 ;YES
AOBJN T2,INI3 ;NO - LOOP
BUG(RP4PNF)
INI4: MOVE T2,DSKSIZ(T2) ;GET POINTER TO PHYSICAL PARAMETER TABLE
MOVEM T2,UDBSIZ(P3) ;SAVE IN UDB
MOVE T3,CYLUNT(T2) ;GET NUMBER OF CYLINDERS
MOVEM T3,RP.CYL(P3) ;SAVE COPY
MOVE T3,SECCYL(T2) ;GET SECTORS PER CYLINDER
MOVEM T3,RP.SCL(P3) ;SAVE
SUB T3,SECPAG(T2) ;COMPUTE START OF LAST PAGE ON A CYL
MOVEM T3,RP.LST(P3) ;SAVE
MOVE T3,SECSRF(T2) ;GET SECTORS PER SURFACE
MOVEM T3,RP.SSF(P3) ;SAVE
LSH T3,6 ;COMPUTE LATOPT UNITS PER SURF
MOVEM T3,RP.USF(P3) ;SAVE
MOVE T3,USSECU(T2) ;GET USEC PER LATOPT UNIT
MOVEM T3,RP.USU(P3) ;SAVE
MOVSI T2,DO.SR ;READ STATUS REGISTER
CALL RDREG
;**;[1913]CHANGE 1 LINE AT INI4: + 16L TAM 22-JUL-81
TXO T4,US.PRQ!US.PSI ;[1913]INDICATE POSITIONING REQUIRED AND PSI
TRNE T1,DS.WRL ;WRITE LOCKED?
TLO T4,(US.WLK) ;YES - INDICATE IN STATUS
TRNE T1,DS.PGM ;DUAL PORT IN PROGRAMMABLE MODE?
TLO T4,(US.PGM) ;YES - INDICATE IN UNIT STATUS
TRNN T1,DS.MOL ;MEDIA ON LINE?
TLO T4,(US.OFS) ;SET OFF-LINE
IORM T4,UDBSTS(P3) ;SET UP STATUS AND CONFIGURATION
TRNN T1,DS.VV ;VOLUME VALID?
CALL RP4UP ;NO - ACK NOW
MOVSI T2,DO.SN ;SERIAL REGISTER
CALL RDREG ;READ IT
MOVEM T1,UDBDSN(P3) ;SAVE DRIVE SERIAL NUMBER
MOVSI T2,DO.LA ;CHECK FOR STUCK SECTOR COUNTER
CALL RDREG
MOVE T4,T1 ;SAVE FIRST VALUE
MOVEI Q1,^D100000 ;MAXIMUM NUMBER OF TIME TO TRY
INI5: MOVSI T2,DO.LA ;NOW TRY FOR A DIFFERENT VALUE
CALL RDREG
CAME T1,T4 ;STILL THE SAME?
RET ;NO - RETURN
SOJGE Q1,INI5 ;YES - TRY AGAIN
MOVE T1,CDBADR(P1) ;GET CHANNEL ADDRESS
MOVE T2,UDBAKA(P3) ;AND UNIT ADDRESS
BUG(RP4SSC,<<T1,D>,<T2,D>>)
RET ;RETURN
SUBTTL START I/O
;C(P4) := IORB , C(P3) := UDB , C(P3) := CDB
RP4SIO: SAVEQ ;SAVE REGISTERS
HRRZ T3,UDBERR(P3) ;GET FUNCTION IF ERROR RECOVERY
JUMPN T3,RP4SI1 ;ERROR RECOVERY?
LDB T3,IRYFCN ;GET FCN
CAILE T3,MXRP4F ;CHECK MAXIMUM LEGAL
BUG(RP4FEX)
RP4SI1: HLRZ Q1,RP4FCN(T3) ;TRANSLATE TO HARDWARE BITS
TRZ Q1,(XFRFLG) ;MASK
CALL RP4CON ;CONNECT TO DRIVE
RET ;UNIT DOWN (MARKED OFL)
;RETURNS T2 := CYLINDER , T3 = REMAINDER
CALL GTHWSC ;GET HW FORMAT SURF/SEC IN T4
HRLI T2,DO.DC ;SET DESIRED CYLINDER
CALL WTREG ;WRITE IN REGISTER
MOVSI T2,DO.OF ;OFFSET REGISTER
TRZE Q1,F22 ;IF 22-SECTOR MODE
TROA T2,OF.ECI+OF.F22 ; THEN CLEAR FMT22 IN OFFSET REGISTER
TRNE Q1,DXES ;IF NOT STOPPING ON ERROR
TRCA T2,OF.ECI ; CLEAR OFFSET , SET ECI
TRNN Q1,10 ;IF WRITING
CALL WTREG ; THEN CLEAR OFFSET REGISTER
MOVE T2,T4 ;GET DISK ADDRESS
HRLI T2,DO.DA ;DESIRED ADDRESS REGISTER
JRST CHSTRT ;START CHANNEL & GIVE GOOD RETURN
;ROUTINE TO STACK A SECOND TRANSFER COMMAND
RP4STK: LDB T1,IRYFCN ;GET FUNCTION
CAILE T1,MXEXFN ;LEGAL?
BUG(RP4IF2)
HLRZ Q1,RP4FCN(T1) ;GET HW FUNCTION
TRZ Q1,(XFRFLG) ;MASK
CALL PHYBLK ;GET UNIT RELATIVE ADDRESS
CALL RP4CV1 ;GET CYL,SECTOR WITHIN CYL IN T2,T3
MOVEM T3,UDBPS2(P3) ;UPDATE SECTOR
CALL GTHWSC ;GET HWFMT ADDRESS IN T4
MOVE T2,T4 ;COPY
HRLI T2,DO.DA ;BUILD DATAO WORD
CALLRET CHSTRT ;GO STACK THE COMMAND
;ROUTINE TO CONNECT TO A DESIRED UNIT
RP4CON: MOVSI T2,DO.DRC ;READ CONTROL REGISTER - SIEZE PORT
CALL RDREG ; IF IN A/B MODE
TRNN T1,CR.DVA ;PORT AVAILABLE?
JRST RP4CN2 ;NO
MOVSI T2,DO.SR ;STATUS REGISTER
CALL RDREG ;GO READ IT
ANDI T1,DS.MSK ;MASK OUT DON'T CARES
CAIE T1,DS.GUD ;DRIVE OK?
JRST RPCERR ;CONNECT ERROR
MOVSI T1,(US.WLK) ;CLEAR WRITE LOCKED
RP4CN1: TLO T1,(US.OFS) ;CLEAR OFFLINE AND UNSAFE
ANDCAM T1,UDBSTS(P3) ; ...
CALL PHYBLK ;GET PHYSICAL DISK BLOCK
HLRZ T1,UDBERP(P3) ;GET BLOCKS DONE
TRNE Q1,ERETRY
ADD T2,T1 ; START AT 1ST BLOCK NOT READ
MOVE T1,Q1 ;COPY FUNCTION WORD
CALL RP4CV1 ;GET CYLINDER AND SECTOR WITHIN CYLINDER
MOVEM T2,UDBPS1(P3) ;SAVE CYLINDER
MOVEM T3,UDBPS2(P3) ;SAVE SURFACE, SECTOR
RETSKP ;SKIP RETURN
;HERE IF A DUAL PORT DRIVE IS IN USE ON THE OTHER PORT
;THIS IS TEMPORARY UNTIL A NEW BIT IS DEFINED TO HANDLE THIS EXPLICITLY.
RP4CN2: MOVX T1,US.OFS!US.OMS ;INDICATE OFFLINE AND MESSAGE ALREADY SENT
IORM T1,UDBSTS(P3) ;SO NO I/O IS ATTEMPTED
MOVSI T2,DO.DRC ;PICK A REGISTER TO WRITE
CALL WTREG ;WRITE IT TO INDICATE ACCESS DESIRED
RET ;WE'LL BE INTERRUPTED WHEN DRIVE AVAILABLE
;HERE IF WE DIDN'T GET NICE STATUS - CHECK WRITE LOCKED
RPCERR: LDB T3,IRYFCN ;GET FCN
CAIE T3,IRFWRT ;CHECK WRITING
CAIN T3,IRFWTF ; OR WRITE FORMAT
JRST RPCER1 ;YES - CHECK ON-LINE
CAIE T1,DS.GUD+DS.WRL ;NO - WRITE LOCKED?
JRST RPCER1 ;NO - SOMETHING ELSE
MOVEI T1,0 ;YES - DONT CLEAR WLK
JRST RP4CN1 ;AND CONTINUE
RPCER1: TRNN T1,DS.MOL ;MEDIA ON LINE?
JRST [MOVSI T3,(US.OFS) ;NO -SET OFF LINE
JRST RPCER3]
TRNE T1,DS.VV ;YES - VOLUME VALID?
JRST RPCER2 ;YES - SOMETHING ELSE IS WRONG
MOVSI T1,(US.CHB!US.OIR) ;VOLUME CHANGED - MAY NEED TO CHECK HB
SKIPL UDBSTR(P3) ;UNIT IN STR?
IORM T1,UDBSTS(P3) ;YES - MUST CHECK HOME BLOCKS
CALL RP4UP ;ACK DRIVE
JRST RP4CON ;AND TRY IT NOW
RPCER2: CALL RP4RDR ;READ ALL REGISTERS
CALL RP4CLR ;CLEAR DRIVE
SETUNS: MOVEI T3,0 ;ACCUMULATE STATUS HERE
MOVE T1,RP.REG+DR.ER(P3) ;GET ERROR REGISTER
TRNE T1,ER.UNS ;FILE UNSAFE?
TLO T3,(US.OFS) ;OFF-LINE + UNSAFE
MOVE T1,RP.REG+DR.ST(P3) ;GET STATUS REGISTER
TRNE T1,DS.WRL ;WRITE LOCKED?
TLO T3,(US.WLK) ;YES.
RPCER3: IORM T3,UDBSTS(P3) ;SET IN STATUS
RET ;ERROR RETURN
;HERE TO DISCONNECT FROM A DUAL PORT DRIVE
RP4DIS: MOVSI T1,(US.PGM) ;IS THIS A VARIABLE DUAL PORT
TDNN T1,UDBSTS(P3) ;DISK?
RET ;NO.
MOVE T2,[DO.DRC+DF.REL] ;DRIVE CONTROL REG, RELEASE PORT
CALL WTREG ;SEND TO DRIVE
RET
;HERE TO DETERMINE THE CYLINDER ASSOCIATED WITH AN IORB
;P3/ UDB
;P4/ IORB
; CALL RP4CNV ;ENTERED BY CALL UDSCNV
;RETURNS+1(ALWAYS):
;T2/ CYLINDER (UDBPS1)
;T3/ SECTOR WITHIN CYLINDER (UDBPS2)
RP4CNV: CALL PHYBLK ;GET UNIT RELATIVE BLOCK ADDRESS
LDB T1,IRYFCN ;GET FUNCTION FROM IORB
CAIG T1,MXEXFN ;GREATER THAN MAXIMUM EXTERNAL FUNCTION?
SKIPN T1,RP4FCN(T1) ;OR HAVE NULL TABLE ENTRY?
BUG(RP4IFC) ;YES TO EITHER
HLRZS T1 ;GET FUNCTION CODE AND FLAGS
TRZ T1,(XFRFLG) ;MASK
RP4CV1: HRRZ T3,RP.SCL(P3) ;GET SECTORS PER CYLINDER
; TRNE T1,F22 ;22 SECTOR MODE?
; HRRZ T3,... ;GET SECTORS PER CYL IN 22 SEC MODE
IDIVI T2,(T3) ;CONVERT
RET
;VERY SPECIAL PURPOSE COMMON CODE TO TRANSLATE SECTOR WITHIN CYL
;IN T3 INTO HWFMT SURF/SECT ADDR IN T4
GTHWSC: HRRZ T4,RP.SSF(P3) ;GET SECTORS PER SURFACE
; TRNE Q1,F22 ;22 SECTOR MODE?
; HRRZ T4,.... ;GET SECTORS PER SURFACE IN 22 SECTOR
IDIVI T3,(T4) ;GET SURFACE AND SECTOR
DPB T3,[POINT 5,T4,27] ; SET T4 TO DESIRED ADDRESS
RET
SUBTTL LATENCY OPTIMIZATION
;HERE TO DETERMINE WHICH TRANSFER REQUEST TO THIS UNIT HAS
;THE SMALLEST LATENCY GREATER THAN A SPECIFIED MINIMUM.
;P1/ CDB
;P3/ UDB
;T1/ MINIMUM LATENCY IN MICROSECONDS (0 FOR COMMAND STACK COMPUTATION)
; CALL UDSLTM(CDB)
;RETURNS+1:
;NO REQUESTS AVAILABLE
;RETURNS+2:
;T1/ LATENCY OF CLOSEST REQUEST GREATER THAN SPECIFIED MINIMUM (USEC)
;T2/ PREDECESSOR OF IORB CORRESPONDING TO TIME IN T1
;T3/ IORB CORRESPONDING TO TIME IN T1
;IF COMMAND STACKING COMPUTATION WAS REQUESTED, THE DISK IS ASSUMED TO
;BE ONE PAGE BEYOND THE CURRENT TRANSFER
;CLOBBERS P4,P5,P6
;REGISTER USAGE:
;T3/ MINIMUM LATENCY,,CURRENT UNIT POSITION
;T4/ BEST LATENCY SO FAR,,PREDECESSOR TO CURRENT IORB
;P4/ CURRENT IORB
;P5/ PREDECESSOR TO BEST IORB,,BEST IORB SO FAR
;NOTE: IF THE ONLY REQUESTS AVAILABLE ARE BETWEEN THE CURRENT UNIT
; POSITION AND THE MINIMUM LATENCY THRESHOLD, THE LATENCY OF
; THE CLOSEST SUCH REQUEST IS RETURNED PLUS ONE REVOLUTION.
; THIS ELIMINATES THE SPECIAL CASE CHECKS IN SCHLTM.
RP4LTM: JUMPE T1,RP4LT6 ;COMMAND STACKING COMPUTATION?
HRRZ T2,RP.USU(P3) ;GET TIME PER 1/64. SECTOR UNIT
IDIVI T1,(T2) ;CONVERT TIME TO UNITS
HRLO P4,T1 ;SAVE AND INITIALIZE CURRENT POSITION
MOVEI T4,3 ;MAXIMUM NUMBER OF TIMES TO READ POSITION
RP4LT1: MOVSI T2,DO.LA ;READ LOOKAHEAD REGISTER
CALL RDREG ; ...
ANDI T1,3777 ;MASK UNDEFINED BITS
CAIN T1,(P4) ;SAME AS LAST READING?
JRST RP4LT2 ;YES - USE IT
HRR P4,T1 ;NO - SAVE THIS ONE
SOJG T4,RP4LT1 ;LOOP
RP4LT2: MOVE T3,P4 ;SAVE MIN LATENCY,,CURRENT POSITION
HRROI T4,UDBTWQ(P3) ;INITIALIZE BEST LATENCY,,PREDECESSOR
TLNN T3,-1 ;IF STACKING,
HRR T4,IRBLNK(T4) ;EXCLUDE HEAD
SETZB P4,P5 ;INITIALIZE CURRENT AND BEST IORBS
RP4LT3: HRRZ P4,IRBLNK(T4) ;SET CURRENT FROM PREDECESSOR
JUMPE P4,RP4LT5 ;END OF LIST?
CALL PHYBLK ;NO - GET UNIT RELATIVE ADDRESS
MOVE T1,T2 ;COPY
HRRZ T2,RP.SCL(P3) ;GET SECTOR PER CYLINDER
IDIVI T1,(T2) ;GET SECTOR WITHIN CYLINDER
MOVE T1,T2 ;COPY
HRRZ T2,RP.SSF(P3) ;GET SECTORS PER SURFACE
IDIVI T1,(T2) ;GET SECTOR WITHIN SURFACE
MOVE T1,T2 ;AS REMAINDER
LSH T1,^D6 ;CONVERT TO 1/64. SECTOR UNITS
SUBI T1,(T3) ;COMPUTE DISTANCE TO THIS REQUEST
SKIPGE T1 ;IF NEGATIVE,
ADD T1,RP.USF(P3) ;GET ABSOLUTE DISTANCE
HLRZ T2,T3 ;GET MINIMUM LATENCY SPECIFIED
CAMGE T1,T2 ;IS THIS REQUEST GREATER?
ADD T1,RP.USF(P3) ;NO - MUST DO IT ONE REVOLUTION LATER
HLRZ T2,T4 ;COMPARE TO BEST LATENCY SO FAR
CAML T1,T2 ;LESS?
JRST RP4LT4 ;NO - DO NEXT REQUEST
HRL T4,T1 ;YES - SAVE AS CURRENT BEST LAT
MOVE P5,P4 ;COPY CURRENT IORB
HRL P5,T4 ;COPY PREDECESSOR IORB
JUMPE T1,RP4LT5 ;IF ZERO LATENCY, CAN DO NO BETTER
MOVEI P6,^D7 ;RESET NUMBER OF REQUESTS TO SCAN
RP4LT4: HRR T4,P4 ;PREDECESSOR BECOMES CURRENT IORB
SOJG P6,RP4LT3 ;LOOK AT NEXT IORB
RP4LT5: JUMPE P5,RP4LTE ;IF NONE FOUND, ERROR
HLRZ T1,T4 ;GET BEST LATENCY FOUND
HRRZ T2,RP.USU(P3) ;GET USEC PER UNIT
IMULI T1,(T2) ;CONVERT BACK TO MICROSECONDS
HLRZ T2,P5 ;GET PREDECESSOR TO BEST IORB
HRRZ T3,P5 ;GET BEST IORB
RETSKP
;HERE WHEN COMMAND STACKING COMPUTATION IS REQUESTED
RP4LT6: MOVE T1,UDBPS2(P3) ;GET CURRENT SECTOR
CAMN T1,RP.LST(P3) ;LAST PAGE ON A CYLINDER?
RET ;YES - DONT
ADDI T1,4 ;ASSUME DISK IS AT THE NEXT PAGE
HRRZ T2,RP.SSF(P3) ;GET SECTORS PER SURFACE
IDIVI T1,(T2) ;COMPUTE ROTATIONAL POSITION
LSH T2,^D6 ;CONVERT TO HWFMT
MOVE P4,T2 ;COPY RESULT
JRST RP4LT2 ;JOIN COMMON CODE
RP4LTE: BUG(RP4LTF)
RET
SUBTTL POSTION REQUEST
;C(P4) := IORB , C(P3) := UDB , C(P1) := CDB
RP4POS: HLRZ Q1,RP4FCN+IRFSEK ;GET OP CODE FOR SEEK
CALL RP4CON ;SEE IF DRIVE THERE AND CONNECT
RET ;ERROR RETURN
HRLI T2,DO.DC ;C(T2) := DESIRED CYLINDER
RP4MOV: PUSH P,T2 ;SAVE ARGUMENT
MOVSI T2,DO.OF ;CLEAR OFFSET REGISTER
CALL WTREG ;...
MOVSI T2,DO.DA ;CLEAR POSSIBLE ILLEGAL
CALL WTREG ; SECTOR FROM DESIRED ADDRESS
POP P,T2 ;RESTORE DESIRED CYLINDER
JRST CHSTRT ;START CHANNEL & SKIP RETURN
SUBTTL INTERRUPT PROCESSING
;ROUTINE TO HANDLE ATTENTION INTERRUPTS
RP4ATN: MOVSI T2,DO.SR ;SET TO READ STATUS REGISTER
CALL RDREG ;...
TRNN T1,DS.MOL ;MEDIA ON-LINE?
JRST RP4OFL ;NO - OFF-LINE INTERRUPT.
TRNN T1,DS.VV ;YES - VOLUME VALID?
JRST RP4ATF ;NO - FREE INTERRUPT (ON-LINE)
MOVE T2,UDBSTS(P3) ;YES, GET STATUS OF DRIVE
TLNN T2,(US.ACT) ;EXPECTING AN INTERRUPT FROM THIS DRIVE?
JRST RP4ATU ;NO - MUST BE -11 LET GO OF IT
CALL SETIRB ;GET ACTIVE IORB(PRESERVES T1)
SKIPE T2,UDBERR(P3) ;IN ERROR RECOVERY?
JRST ERRATN ;YES, HAVE TO USE A DISPATCH ADDRESS
TRNE T1,DS.ERR ;NO, ERROR?
JRST RP4ATE ;YES
;HERE ON INTERRUPT WITH NO ERRORS
RP4ATD: AOS UDBSEK(P3) ;NOTE SEEK
PUSH P,Q1 ;PRESERVE REG
SKIPE UDBERR(P3) ;IF IN ERROR RECOVERY AND JUST WON,
CALL SFTSEK ;READ THE REGISTERS NOW - AT END
JFCL
POP P,Q1 ;RECOVER Q1
TLO Q1,-1 ;SET FLAG FOR UPPER LEVEL
CALL PHYPDN ;INFORM PHYSIO
ATNX0: MOVEI P4,0 ;NO SPECIFIC IORB TO RETURN
ATNXIT: MOVEI T2,1 ;POSITION BIT
HRRZ T1,UDBAKA(P3) ;GET CURRENT CHANNEL ADDRESS
ROT T2,(T1) ;THE BIT
HRLI T2,DO.AS ;BUILD DATAO
CALL WTREG ;WRITE ATTENTION SUMMARY REGISTER
HRRZ T3,UDBAKA(P3) ;GET THE UNIT # OF DRIVE IN ERROR
CAMN T3,CDBXFR(P1) ;IS IT THE TRANSFERRING DRIVE?
RET ;YES -- SOMEONE ELSE WANTS TO LOOK AT IT FIRST
CALLRET RP4CLR ;CLEAR DRIVE AND BACK TO CHANNEL
RP4ATU: MOVX T1,US.OFS!US.OIR!US.OMS ;DEVICE IS NOW OURS AGAIN
ANDCAM T1,UDBSTS(P3) ;SO MAKE UNIT ONLINE AGAIN
TLO Q1,-1 ;SET TO RESTART I/O
JRST ATNXIT ;JOIN COMMON EXIT
RP4ATE: HRRZ T3,UDBAKA(P3) ;ERROR - GET UNIT #
CAMN T3,CDBXFR(P1) ;SAME UNIT AS TRANSFER?
JRST ATNX0 ;YES - ERROR ON XFERING UNIT (IGNORE)
; WILL HANDLE LATER IN XFER INTERRUPT CODE
;HERE IF AN ERROR ON A NON-TRANSFERRING DRIVE
CALL RP4RDR ;READ ALL DRIVE REGISTERS
MOVE T1,RP.REG+DR.ST(P3) ;GET STATUS REGISTER
MOVE T2,RP.REG+DR.ER3(P3) ;GET ERROR REGISTER 3
MOVE T3,RP.REG+DR.ER(P3) ;GET ERROR REGISTER
TRNE T2,E3.SKI ;SEEK INCOMPLETE,
TRNE T3,ER.UNS ; AND NOT UNSAFE?
JRST RP4AT2 ;NO - JUST SEEK ERROR
TRNN T1,DS.DRY ;YES, DRIVE READY?
JRST ATNX0 ;NO - UNIT STILL DOING RECAL, WAIT
;RECALIBRATE DONE, FALL INTO POSITIONING ERROR CODE
RP4AT2: MOVSI T1,(ES.POS) ;INDICATE A POSITION ERROR
IORM T1,UDBERR(P3) ;IN RECOVERY STATE WORD
CALL RP4CDA ;CLEAR DA & DC
MOVSI T1,(IS.ERR) ;FLAG ERROR IN IORB
IORM T1,IRBSTS(P4) ; ...
TLO P4,-1 ;SET SEEK ERROR FLAG
CALLRET RP4CLR ;RESET DEVICE AND RETURN TO CHANNEL
;HERE ON FREE INTERRUPT (PACK CAME ON LINE)
RP4ATF: MOVSI T1,(US.CHB!US.OIR) ;MAY NEED TO CHECK HOME BLOCKS
SKIPL UDBSTR(P3) ; ...
IORM T1,UDBSTS(P3) ;MUST CHECK HOME BLOCKS
CALL RP4UP ;ISSUE PACK ACK
TLO Q1,-1 ;SET FLAG FOR UPPER LEVEL
JRST PHYONL ;INFORM PHYSIO
;HERE ON ATTENTION INTERRUPT IF DRIVE IS IN ERROR RECOVERY
ERRATN: MOVE T1,UDBERR(P3) ;GET FUNCTION BEING PERFORMED
SKIPL T1,RP4FCN(T1) ;GET DISPATCH ADDRESS
JRST (T1) ;GO PROCESS THE INTERRUPT
JRST ATNX0 ;DATA TRANSFER FUNCTION - DEFER
;HERE FOR INTERRUPTS OTHER THAN ATTENTION
RP4INT: CALL SETIRB ;SET UP IORB INTO P4
HRRZ T1,UDBERR(P3) ;GET FUNCTION IF ERR RECOV
SKIPN T1 ;IN ERROR RECOVERY?
LDB T1,IRYFCN ;GET FCN CODE
CAIG T1,MXRP4F ;CHECK IF LEGAL
SKIPL T1,RP4FCN(T1) ;GET TABLE ENTRY
BUG(RP4ILF)
JRST 0(T1) ;THE LEAP OF FAITH
SUBTTL READ/WRITE INTERRUPTS
RP4RED:
RP4WRT: MOVSI T2,DO.OF ;CLEAR ECI
TRNE T1,DXES ; IF THEY WERE ON (NEXT TO LAST TRY)
CALL WTREG
MOVSI T2,DO.SR ;READ THE STATUS REGISTER
CALL RDREG ;...
TRNN T1,DS.ERR ;ANY ERROR?
CALL CKERR ;CHECK CHANNEL ERRORS ALSO
JRST RP4DER ;YES - GO DECODE
CALL PHYCNT ;GET LENGTH OF TRANSFER
LSH T1,-7 ;AS BLOCKS
LDB T2,IRYFCN ;GET FUNCTION CODE
CAIN T2,IRFRED ;READ?
ADDM T1,UDBRED(P3) ;YES
CAIN T2,IRFRED ;READ?
AOS UDBRCT(P3) ;UPDATE READ COUNT
CAIN T2,IRFWRT ;WRITE?
ADDM T1,UDBWRT(P3) ; YES
CAIN T2,IRFWRT ;AGAIN
AOS UDBWCT(P3) ;UPDATE WRITE COUNT
SKIPE UDBERR(P3) ;WAS DRIVE BEING ERROR-RECOVERED?
CALL RP4RDR ;YES, READ REGISTERS AT SUCCESS
MOVSI T1,(CS.AC2) ;IF STACKED COMMAND ACTIVE
TDNN T1,CDBSTS(P1) ;DONT RELEASE PORT
CALL RP4DIS ;DISCONNECT IF DUAL PORT DRIVE
RETSKP
;HERE IF ERROR DETECTED ON DATA XFER
RP4DER: CALL RP4RDR ;READ ALL DRIVE REGISTERS
;AND FALL INTO RP4IER
;HERE ON ALL INTERRUPT DETECTED TRANSFER ERRORS
RP4IER: MOVSI T1,(IS.ERR)
IORM T1,IRBSTS(P4)
CALL RP4CLR ;CLEAR THE DRIVE
RET
;HERE ON INTERRUPT AFTER LAST PART OF XFER DONE (ECC FIXED 1ST PART)
RP4ECF: MOVSI T2,DO.SR ;READ THE STATUS REGISTER
CALL RDREG
TRNE T1,DS.ERR ;ERROR?
JRST RP4DER ;YES, GO HANDLE IT
CALL RP4RDR ;GET REGISTERS AT SUCCESS
CALL RP4IER ;NO, NOW TELL PHYSIO ABOUT THE ERROR
MOVSI T1,(ES.ECC) ;INDICATE AN ECC ERROR
IORM T1,UDBERR(P3) ; IN THE ERROR WORD
RET
SUBTTL ERROR RECOVERY CODE, ENTERED BY PHYSIO ON ERROR
REPEAT 0,<
ENTERED BY PHYSIO WHEN IS.ERR IS ON IN THE IORB, WITH UDBERP SET UP.
ON THE FIRST ERROR THE STATUS WILL BE READ INTO THE ERROR BLOCK
ERROR RECOVERY WILL BE ATTEMPTED, AND A NON-SKIP RETURN TO PHYSIO
INDICATES THAT ERROR RECOVERY IS IN PROGRESS.
A SKIP-RETURN INDICATES THAT ERROR RECOVERY IS DONE (HARD ERROR)
IF ENTERED BY PHYSIO WITH IS.ERR OFF IN THE IORB, JUST READ THE FINAL
STATUS (SOFT, SO WE RECOVERED) INTO THE ERROR BLOCK, AND SKIP-RETURN
>
RP4ERR: SAVEQ ;SAVE ACCUMULATORS
HRRZ Q1,UDBERP(P3) ;GET ERROR BLOCK (IF PRESENT)
MOVE Q2,UDBSTS(P3) ;Q2 CONTAINS STATUS,
AOS Q3,UDBERC(P3) ;AND Q3 HAS THE RETRY COUNTER
SOJN Q3,NOT1ST ;GO IF NOT THE FIRST TIME
;HERE ON FIRST ERROR, SAVE DRIVE AND CHANNEL REGISTERS
JUMPE Q1,ERR1 ;IF NO ERROR BLOCK, CANT SAVE REGISTERS
HRLI T1,RP.REG(P3) ;BUILD BLT POINTER
HRRI T1,SEBDAT+MB%REG(Q1) ;...
BLT T1,SEBDAT+MB%REG+17(Q1) ;COPY REGISTERS
MOVE T1,Q1 ;COPY ERROR BLOCK
MOVE T2,[-NEDAT,,EDAT] ;POINTER TO CONTROL TABLE
CALL SEBCPY ;COPY DATA
JFCL
CALL PHYBLK ;GET LOGICAL ADDRESS
MOVEM T2,SEBDAT+MB%LOC(Q1) ;SAVE
ERR1: TLNN Q2,(US.POS) ;IF THIS IS A READ,
LDB T1,IRYFCN ; AND AND THE DRIVE IS OFFSET,
MOVE T2,RP.REG+DR.OF(P3) ; DUE TO A PREVIOUS SECTOR THAT WAS
CAIN T1,IRFRED ; RECOVERED AT OFFSET
TRNN T2,377 ; FOR WHICH WE DIDNT RETURN TO CENTERLINE,
JRST NOT1ST
MOVEI Q3,RTCNDX ; THEN RETURN TO CENTERLINE NOW
JRST RP4OFS ; BEFORE "REAL" ERROR RECOVERY IS ATTEMPTED
NOT1ST: MOVSI T1,(IS.IER) ;ERROR RECOVERY INHIBITED?
TDNE T1,IRBSTS(P4) ; ??
JRST HRDERR ;YES - ALL ERRORS ARE HARD
MOVE T1,RP.REG+DR.ER(P3) ;GET THE ERROR REGISTER
TRNE T1,ER.UNS ;UNSAFE?
JRST [CALL SETUNS ;YES, MARK THE DRIVE UNSAFE
JRST HRDERR] ;AND CALL IT A HARD ERROR
MOVE T1,IRBSTS(P4) ;NO, ERROR BIT ON?
TLNN T1,(IS.ERR)
JRST [ TLNE Q2,(US.POS) ;SEEK ERROR?
JRST SFTSEK ;YES
LDB T1,IRYFCN ;SOFT ERROR, GET OPERATION
CAIN T1,IRFRED ;READ?
AOS UDBSRE(P3) ;YES
CAIN T1,IRFWRT ;WRITE?
AOS UDBSWE(P3) ;YES
JRST RDFINL] ;GO READ REGISTERS
MOVE T1,UDBERR(P3) ;YES, GET BITS FROM ERR WORD
MOVE T2,RP.REG+DR.ST(P3) ;GET STATUS REGISTER
TLNE T1,(ES.ECC) ;ECC RECOVERED FIRST PART?
TRNE T2,DS.ERR ;WITH NO ERRORS
SKIPA
JRST RP4ECD ;YES, WE'RE NOW FINISHED
TLNN Q2,(US.POS) ;NO, POSITIONING ERROR?
AOJA Q3,ERXFER ;NO
MOVSI T1,(ES.POS) ;YES, LIGHT A BIT
IORM T1,UDBERR(P3)
MOVSI T1,(IS.DVE) ;INDICATE DEVICE ERROR
IORM T1,IRBSTS(P4) ; ...
CAIL Q3,POSCNT ;TRIED ENOUGH?
JRST HRDSEK ;YES, IT'S HARD
JRST RP4RCL ;NO, RECALIBRATE AND TRY AGAIN
;TABLE OF DATA TO COPY AT INITIAL ERROR RECOVERY TIME
EDAT: SEBPTR MB%CNI,SBTWD,RP.CNI(P3) ;CONI
SEBPTR MB%D1I,SBTWD,RP.CRC(P3) ;TCR
SEBPTR MB%D2I,SBTWD,RP.DBF(P3) ;BAR/DBF
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
NEDAT=.-EDAT
;HERE ON ERROR OF AN TRANSFERRING UNIT
ERXFER: MOVE T1,RP.REG+DR.ER(P3) ;GET ERROR REGISTER
TRNE T1,ER.DCK ;DATA CHECK,
TRNE T1,ER.ECH ;AND NOT ECC HARD?
SKIPA T2,UDBERR(P3) ;NO
JRST ERRECC ;YES, ECC CAN FIX IT UP
TRNN T1,ER.OFS ;ERROR FOR WHICH OFFSET MIGHT WIN?
TLNE T2,(ES.DAT!ES.HDR!ES.FER)
JRST DATERR ;YES, GO TO OFFSET CODE
JRST DEVERR ;NO, DEVICE ERROR
ERRECC: MOVE T1,RP.REG+DR.OF(P3) ;FIRST CHECK IF ECC WAS ON
TRNE T1,OF.ECI ;IF NOT, DONT EVEN LOOK AT
JRST DATERR ;ECC REGS
MOVE T1,UDBERC(P3) ;GET RETRY COUNT
;**;[1860] Chnage one line at ERRECC: +4L JGZ 29-APR-81
CAIG T1,^D8 ;[1860] TIME TO TRY ECC YET?
JRST DATERR ;NO
MOVE Q3,RP.REG+DR.ECP(P3) ;GET ECC POSITION
SOJL Q3,DATERR ;LOSE IF POSITION = 0
CAIL Q3,^D36*^D128 ;IS POSITION SANE?
JRST DATERR ;NO - ACT LIKE ECH
;HERE ON ECC-CORRECTABLE ERROR
MOVSI T1,(ES.ECC) ;FLAG AS ECC
IORM T1,UDBERR(P3) ; ...
EXCH P4,Q3 ;MOVE POSITION TO BETTER AC
IDIVI P4,^D36 ;COMPUTE POSITION OF BURST
MOVE T4,RP.REG+DR.ECB(P3) ;GET ERROR BURST
EXCH P5,T4
SETZ P6, ;POSITION THE MASK
ROTC P5,(T4)
EXCH P4,Q3 ;RESTORE QUOTIENT
CALL ECCADR ;GET START OF LAST SECTOR TRANSFERRED
ADDI T1,(Q3) ;POINT TO FIRST ERROR WORD
CALL PHYMOV ;GET THE DATA WORD
MOVSS P5 ;APPLY ECC MASK TO 1ST PART
XOR T2,P5
CALL PHYSTO ;AND STORE THE ANSWER
ADDI T1,1 ;POINT TO 2ND ERROR WORD
CALL PHYMOV ;GET IT
MOVSS P6 ;FIX IT
XOR T2,P6
CALL PHYSTO ;AND STORE IT
CALL ECCUCL ;UPDATE CCW LIST, RETURN NO OF WORDS TRANSFERRED OK
JRST RP4ECD ;DONE - ERROR WAS IN LAST BLOCK (OF 4)
LSH T1,-7 ;NOT DONE - NUMBER OF BLOCKS WE READ
HRLM T1,UDBERP(P3) ;SAVE TO COMPUTE 1ST BLOCK OF XFER
MOVEI T1,ECFNDX ;INDICATE READING LAST PART
CALL SURTRY ; WHERE ECC FIXED UP THE FIRST PART
CALL RP4CLR ;MAKE SURE THE DRIVE IS READY
JRST RETRY ;GO START THE XFER
;HERE WHENN ECC IS DONE (LAST BLOCK OF PAGE OR AFTER THE REST IS READ)
RP4ECD: MOVSI T1,(ES.ECC) ;INDICATE ECC-CORRECTED ERROR
IORM T1,UDBERR(P3)
MOVSI T1,(IS.ERR) ;CLEAR ERROR BIT, SOFT ERROR
ANDCAM T1,IRBSTS(P4) ; ...
AOS UDBSRE(P3) ;NOTE SOFT READ ERROR
JRST RDFINL ;CLEAN UP AND EXIT
;HERE ON ERROR WHICH MIGHT BE RECOVERED BY OFFSET
DATERR: MOVE T1,RP.REG+DR.ER(P3) ;GET ERROR REGISTER AGAIN
SETZ T2,
TRNE T1,ER.DCK ;DATA ERROR?
TLO T2,(ES.DAT) ;YES
TRNE T1,ER.FER ;FORMAT ERROR?
TLO T2,(ES.FER) ;YES
TRNE T1,ER.HCE!ER.CRC ;HEADER ERROR?
TLO T2,(ES.HDR) ;YES
IORM T2,UDBERR(P3) ;LIGHT ERROR BIT IN ERROR WORD
MOVSI T2,(IS.DTE) ;INDICATE DATA ERROR
IORM T2,IRBSTS(P4) ; ...
MOVE Q3,UDBERC(P3) ;GET RETRY COUNTER
SUBI Q3,^D16 ;LESS THAN 16 RETRIES?
JUMPL Q3,RETRY0 ;IF SO, JUST TRY ONCE MORE
CAIL Q3,^D13 ;NO, TRIED ENOUGH?
JRST HRDTER ;YES, FINISH UP
TRNE Q3,1 ;NO, TIME TO OFFSET?
JRST RETRY ;NO, TRY 2ND TIME AT THIS OFFSET
LSH Q3,-1 ;YES, COMPUTE OFFSET VALUE
RP4OFS: MOVEI T1,OFSNDX ;INDICATE AN OFFSET
JRST RP4EPS ;AND GO DO IT
;HERE ON AN ERROR WHICH OFFSET WONT DO US ANY GOOD ON
DEVERR: MOVSI T1,(ES.DEV) ;INDICATE DEVICE ERROR
IORM T1,UDBERR(P3)
MOVSI T1,(IS.DVE) ;INDICATE DEVICE ERROR
IORM T1,IRBSTS(P4) ; ...
EXCH P1,P5 ;TEMP
IDIVI Q3,DEVCNT ;RETRY COUNT/NO OF TIMES TO RETRY
EXCH P1,P5 ;TEMP
CAILE Q3,RCLCNT ;RETRIED ENOUGH?
JRST DEVER1 ;YES, FINISH UP
JUMPN P5,RETRY0 ;NO, RETRY IF HAVENT TRIED (DEVCNT) TIMES
JRST RP4RCL ;TRIED ENOUGH - RECALIBRATE AND TRY AGAIN
DEVER1: SKIPA Q3,P5 ;Q3= 0 (TRY WITH DXES) OR 1 (LAST TIME)
HRDTER: SUBI Q3,^D13 ; OR 2 (GIVE UP)
LSTERS: JUMPG Q3,LSTER1 ;TRY FOR AS MUCH AS WE CAN GET?
LDB T2,IRYFCN ;YES, GET FUNCTION
CAIE T2,IRFRED ;IF NOT PLAIN VANILLA READ OR WRITE,
CAIN T2,IRFWRT
JRST .+2 ;(READ OR WRITE HEADERS AND DATA)
JRST HRDERR ;THEN FORGET IT
MOVEI T1,DXRNDX ;SET UP TO READ/WRITE
CAIE T2,IRFRED ;WITH DXES AND ECI ON
MOVEI T1,DXWNDX
JRST RETRY1 ;GO GET AS MUCH DONE AS POSSIBLE
LSTER1: SOJE Q3,RETRY0 ;1 LAST TIME IF Q3=1
;HERE IF THE ERROR IS HARD
HRDERR: MOVSI T1,(IS.NRT!IS.DVE) ;INDICATE HARD ERROR
IORM T1,IRBSTS(P4) ; ...
MOVSI T1,(ES.HRD) ;LIGHT HARD-ERROR BIT
IORM T1,UDBERR(P3) ; IN THE ERROR WORD
LDB T1,IRYFCN ;GET FUNCTION
CAIN T1,IRFRED ;READ?
AOS UDBHRE(P3) ;ACCOUNT
CAIN T1,IRFWRT ;WRITE?
AOS UDBHWE(P3) ;YES
;HERE TO READ THE DRIVE REGISTERS AT END (SOFT OR HARD)
RDFINL: CALL RDRFIN ;READ REGISTERS
ALLDON: HRLZI T2,DO.OF ;CLEAR OFFSET REG AND ECI
CALL WTREG ; ...
CALL RP4DIS ;DISCONNECT IF DUAL PORT DRIVE
RETSKP ;TELL PHYSIO WE SHOULDNT TRY ANY MORE
;HERE ON A SOFT SEEK ERROR
SFTSEK: AOS UDBSPE(P3) ;ACCOUNT POSITION ERROR
JRST SEKFNL ;READ REGISTERS AND FINISH
;HERE ON A HARD SEEK ERROR
HRDSEK: AOS UDBHPE(P3) ;NOTE HARD POSITION ERROR
MOVSI T1,(ES.HRD) ; ...
IORM T1,UDBERR(P3)
MOVSI T1,(IS.NRT!IS.DVE) ;FLAG ERROR AS HARD
IORM T1,IRBSTS(P4) ; ...
SEKFNL: CALL RDRFIN ;READ FINAL REGISTERS
CALL RP4DIS ;DISCONNECT IF NEEDED
RETSKP
RDRFIN: HRRZ Q1,UDBERP(P3) ;GET ERROR BLOCK AGAIN
JUMPE Q1,ALLDON ;IF NO ERROR BLOCK, CANT SAVE INFORMATION
MOVSI T1,-20 ;20 DRIVE REGISTERS
HRRI T1,RP.REG(P3) ;FROM THE UDB
MOVEI T2,SEBDAT+MB%REG(Q1) ;INTO THE ERROR BLOCK
RDFIN1: MOVE T3,(T1) ;GET A REGISTER
HRLM T3,(T2) ;SAVE IN RH (FINAL STATUS)
ADDI T2,1
AOBJN T1,RDFIN1 ;AND LOOP FOR MORE
MOVE T1,RP.CNI(P3) ;GET CONI
MOVEM T1,SEBDAT+MB%CIF(Q1) ;SAVE FINAL CONI
MOVE T1,RP.CRC(P3) ;GET TCR FINAL
MOVEM T1,SEBDAT+MB%D1F(Q1) ;SAVE
MOVE T1,RP.DBF(P3) ;GET BAR
MOVEM T1,SEBDAT+MB%D2F(Q1) ;AND SAVE
RET
;HERE TO RECALIBRATE A DRIVE
RP4RCL: MOVEI T1,RCLNDX ;RECALIBRATE
RP4EPS: CALL SURTRY ;CLEAR THE ERROR BIT
HRRZ Q1,UDBERR(P3) ;GET THE FUNCTION FOR RECOVERY
HLRZ Q1,RP4FCN(Q1) ;GET THE HARDWARE BITS
CALL RP4CON ;CONNECT TO THE DRIVE
JRST HRDERR ;ITS DOWN - LOSE
SOS 0(P) ;CHSTRT WILL SKIP - RETURN
MOVSI T2,DO.DC ;CLEAR DESIRED CYLINDER IF RECALIBRATE,
CAIE Q1,DF.OFS
JRST RP4MOV
LDB T1,USYTYP ;GET DEVICE TYPE
CAIN T1,.UTRP6 ;RP06?
SKIPA T2,OFSTB6(Q3) ;YES - GET SMALLER OFFSETS
MOVE T2,OFSTBL(Q3) ;NO - GET DATAO OFFSET REGISTER FOR RP04,5
CAIN T1,.UTRP7 ;RP07?
MOVE T2,OFSTB7(Q3) ;YES GET CORRECT OFFSETS
CAIN T1,.UTRM3 ;RM03?
MOVE T2,OFSTB3(Q3) ;YES DIFFERENT OFFSETS
;**;[7375]At RP4EPS:+17L replace 3 lines with 12 lines JCR 16-Sep-86
TRNE T2,-1 ;[7375]Offset equal to zero?
JRST CHSTRT ;[7375]No, start channel and return to PHYSIO
MOVEI Q1,DF.RTC ;[7375]Yes, assume return to centerline
MOVE T1,RP.REG+DR.ER(P3) ;[7375]Pick up the error register
TRNE T1,ER.HCE ;[7375]Header compare error present?
TRNE T1,ER.CRC ;[7375]Yes, header CRC error present?
JRST CHSTRT ;[7375]Yes, start channel and return to PHYSIO
MOVSI T2,DO.DC ;[7375]Clear the desired cylinder register
MOVEI Q1,DF.RCL ;[7375]Recalibrate drive function
MOVEI T1,RCLNDX ;[7375]Recalibrate function code
HRRM T1,UDBERR(P3) ;[7375]Save the function code in the UDB
JRST RP4MOV ;[7375]Clear some registers then start channel
;HERE ON INTERRUPT AFTER A RECALIBRATE
ERRCLI: CALL RP4CDA ;READIN PRESET TO CLEAR DRIVE
MOVEI T1,SEKNDX ;START A SEEK GOING
HRRZ Q1,UDBERP(P3) ;GET ERROR BLOCK IF PRESENT
CALL RP4EPS
SETZB P4,Q1 ;INDICATE JUST DISMISS THE INTERRUPT
RET ;AND RETURN
;HERE ON POSITION DONE INTERRUPT IF DRIVE IS IN ERROR RECOVERY
ERRPSI: CALL RP4CDA ;READIN PRESET TO CLEAR THE DRIVE
MOVSI T1,(US.POS) ;WAS ORIGINAL OP A SEEK?
TDNE T1,UDBSTS(P3) ; ?
JRST RP4ATD ; YES, SUCCESSFUL RECOVERY OF SEEK ERROR
RETRY0: LDB T1,IRYFCN ;GET FUNCTION
HRRZ Q1,UDBERP(P3) ;GET ERROR BLOCK IF PRESENT
RETRY1: CALL SURTRY ;CLEAR ERROR BIT IN IDBSTS
;HERE TO RETRY A DATA-XFER OPERATION AFTER AN ERROR
RETRY: HRRZ T1,CDBDSP(P1) ;GET CHANNEL DISPATCH
CALL CDSSIO(T1) ;START IO
JRST HRDERR ; **TEMP** UNIT REFUSED RETRY - HARD ERROR
SETZ P4, ;TELL PHYSIO TO DISMISS THE INTERRUPT
RET ;AND WAIT FOR NEXT INTERRUPT
;ROUTINE TO SET UP FOR ERROR RETRY
SURTRY: HRRM T1,UDBERR(P3) ;SAVE WHAT TO DO
JRST SETIO ;CLEAR ERROR BITS FROM IORB
SUBTTL MISC ROUTINES
;ROUTINE TO ISSUE PACK ACKNOWLEDGE AND RESET DRIVE
RP4UP: MOVSI T2,DO.SR ;READ STATUS REGISTER
CALL RDREG
MOVE T4,UDBSTS(P3) ;GET STATUS
TLZ T4,(US.PGM!US.WLK) ;CLEAR BITS FOR DUAL PORT AND WRITE LOCKED
TRNE T1,DS.WRL ;WRITE LOCKED?
TLO T4,(US.WLK) ;YES - INDICATE IN STATUS
TRNE T1,DS.PGM ;DUAL PORT IN PROGRAMMABLE MODE?
TLO T4,(US.PGM) ;YES - INDICATE IN UNIT STATUS
MOVEM T4,UDBSTS(P3) ;SET UP STATUS AND CONFIGURATION
CALL RP4CLR ;CLEAR DRIVE
MOVEI T2,DF.ACK ;PACK ACKNOWLEDGE
JRST WTREG ;DO IT
;ROUTINE TO CLEAR DRIVE
RP4CLR: MOVEI T2,DF.CLR ;CLEAR FCN
CALL WTREG ;...
MOVSI T2,DO.AS ;GET ATTENTION SUMMARY REGISTER
CALL RDREG ;...
MOVEI T3,1 ;BIT TO FIDDLE
HRRZ T4,UDBAKA(P3) ;UNIT #
LSH T3,(T4) ;FIDDLE TO CORRECT POSITION
TDNN T1,T3 ;ATTENTION NOW UP?
RET ;NO - DONE
MOVE T2,T3 ;YES , ERROR CAN'T BE CLEARED
HRLI T2,DO.AS
JRST WTREG ;CLEAR BIT IN ATTENTION SUMMARY REGISTER
;ROUTINE TO READ RP04 REGISTERS ON ANY ERROR
RP4RDR: SETZ T2, ;DRIVE NUMBER, START AT 0
MOVSI T4,-20 ;READ 20 REGISTERS
HRRI T4,RP.REG(P3) ;STORE IN RP.REG
RP4RD1: CALL RDREG ;READ A REGISTER
MOVEM T1,(T4) ;SAVE IN UDB
ADD T2,[10000,,] ;STEP TO NEXT REGISTER
AOBJN T4,RP4RD1 ;AND READ IT
CALL ERRCNI ;DO CONI, DATAI'S OF RH
MOVEM T1,RP.CNI(P3) ;SAVE CONI
MOVEM T2,RP.CRC(P3) ;SAVE DATAI CRC
MOVEM T3,RP.DBF(P3) ;SAVE DATAI DB
RET ;ALL REGISTERS READ, RETURN
;ROUTINE TO CLEAR POSSIBLE GARBAGE FROM DRIVE REGISTERS
RP4CDA: MOVEI T2,DF.PST ;ENSURE DA & DC DON'T GET LEFT
JRST WTREG ;WITH FUNNY VALUES
;HERE TO MARK UNIT OFFLINE
RP4OFL: CALL PHYOFL ;SET OFF LINE
JRST ATNXIT ;RETURN CLEARING ATTENTION
;FUNCTION TABLE
XFRFLG==1B0 ;FUNCTION TRANSFERS DATA (MUST BE SIGN)
RP4FCN: 0 ;0 - ILLEGAL
XFRFLG+<XWD DF.RED,RP4RED> ;1 - READ
XFRFLG+<XWD DF.RDF,RP4RED> ;2 - READ FORMAT
XFRFLG+<XWD DF.WRT,RP4WRT> ;3 - WRITE
XFRFLG+<XWD DF.WTF,RP4WRT> ;4 - WRITE FORMAT
DF.SEK,,ERRPSI ;5 - SEEK
SEKNDX==.-RP4FCN-1
MXEXFN==SEKNDX ;MAXIMUM EXTERNAL FUNCTION
DF.RCL,,ERRCLI ;6 - RECALIBRATE
RCLNDX==.-RP4FCN-1
XFRFLG+<XWD DF.RED+ERETRY,RP4ECF> ;7 - FINISH UP AFTER ECC FIXED PART OF XFER
ECFNDX==.-RP4FCN-1
DF.OFS,,ERRPSI ;10 - OFFSET
OFSNDX==.-RP4FCN-1
XFRFLG+<XWD DF.RED+DXES,RP4RED> ;11 - READ ALL DATA POSSIBLE
DXRNDX==.-RP4FCN-1
XFRFLG+<XWD DF.WRT+DXES,RP4WRT> ;12 - WRITE ALL DATA POSSIBLE
DXWNDX==.-RP4FCN-1
MXRP4F==.-RP4FCN-1 ;MAXIMUM LEGAL FCN
;TABLE OF OFFSETS FOR RP04,5
OFSTBL: DO.OF,,20 ;OFFSET +400 MICRO INCHES
DO.OF,,220 ;-400
DO.OF,,40 ;+800
DO.OF,,240 ;-800
DO.OF,,60 ;+1200
DO.OF,,260 ;-1200
DO.OF,,0 ;RTC
RTCNDX==.-OFSTBL-1
;OFFSET TABLE FOR RP06
;NOTE: THIS TABLE MUST BE THE SAME LENGTH AS OFSTBL
OFSTB6: DO.OF,,10 ;+200 MICRO IN
DO.OF,,210 ;-200
DO.OF,,20 ;+400
DO.OF,,220 ;-400
DO.OF,,30 ;+600
DO.OF,,230 ;+600
DO.OF,,0 ;RTC
;...
;OFFSET TABLE FOR RM03
;NOTE: THIS TABLE MUST BE THE SAME LENGTH AS OFSTBL
OFSTB3: DO.OF,,20 ;+202 MICRO IN
DO.OF,,220 ;-200 MICRO IN
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
;OFFSET TABLE FOR RP07
;NOTE: THIS TABLE MUST BE THE SAME LENGTH AS OFSTBL
OFSTB7: DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
DO.OF,,0 ;RTC
TNXEND ;FOR GOODNESS
END