Trailing-Edge
-
PDP-10 Archives
-
bb-jr93e-bb
-
7,6/ap015/rhxkon.x15
There are 2 other files named rhxkon.x15 in the archive. Click here to see a list.
TITLE RHXKON - RH11 DRIVER FOR RP06'S AND RM03'S V023
SUBTTL J EVERETT/JE/DBD 8 JULY 85
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1978,1986>
;COPYRIGHT (C) 1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
XP VRHKON,023
;TRACKS VERSION 147 OF RPXKON
;ASSEMBLY INSTRUCTIONS: RHXKON,RHXKON_KONPAR,RHXKON
ENTRY RHXKON
RHXKON::
SUBTTL DEFINITIONS
;FUNCTIONS (OP CODES IN THE CONTROL REGISTER)
FNCUNL==3 ;UNLOAD
FNCSEK==5 ;SEEK
FNCRCL==7 ;RECALIBRATE
FNCCLR==11 ;DRIVE CLEAR
FNCREL==13 ;RELEASE (DUAL PORT)
FNCOFS==15 ;OFFSET
FNCRTC==17 ;RETURN TO CENTERLINE
FNCPST==21 ;READIN PRESET
FNCACK==23 ;PACK ACKNOWLEDGE
FNCSRC==31 ;SEARCH
FNCWRT==61 ;WRITE DATA
FNCWTF==63 ;WRITE FORMAT
FNCRED==71 ;READ DATA
FNCRHD==73 ;READ FORMAT
FCOMP==400000 ;COMPATABILITY MODE (SOFTWARE ONLY, NEVER STORED IN DDB)
FESI==200000 ;ERROR STOP INHIBIT (SOFTWARE ONLY, NEVER STORED IN DDB)
;RH11 REGISTER OFFSETS
DOCR==0 ;CONTROL REGISTER
DOWC==2 ;WORD COUNT REGISTER
DOBA==4 ;BUS ADDRESS REGISTER
DODA==6 ;DESIRED ADDRESS (TRACK/SECTOR)
DOCS2==10 ;STATUS REGISTER
DOSR==12 ;DRIVE STATUS REGISTER
DOER==14 ;ERROR REG 1
DOAS==16 ;ATTENTION SUMMARY
DOLA==20 ;LOOK-AHEAD (SECTOR COUNTER)
DODB==22 ;DATA BUFFER
DODT==26 ;DRIVE TYPE
DOSN==30 ;SERIAL NUMBER
DOOF==32 ;OFFSET
DODC==34 ;DESIRED CYLINDER
DOER2==40 ;ERROR REG 2
DOER3==42 ;ERROR REG 3
DOECP==44 ;ECC POSITION
DOECB==46 ;ECC BURST (PATTERN)
;DRIVE STATUS REGISTER BITS
ATA==1B20 ;ATTN ACTIVE
ERR==1B21 ;ERROR
PIP==1B22 ;POSITION IN PROGRESS
MOL==1B23 ;MEDIUM ON LINE
WRL==1B24 ;WRITE LOCK
LST==1B25 ;LAST SECTOR TRANSFERED
PGM==1B26 ;PROGRAMMABLE
DPR==1B27 ;DRIVE PRESENT
DRY==1B28 ;DRIVE READY
VV==1B29 ;VOLUME VALID
OM==1B35 ;OFFSET MODE (RM03)
GUDSTS==MOL!DPR!DRY!VV
;ERROR REG STATUS BITS
DCK==1B20 ;DATA CHECK
UNS==1B21 ;UNSAFE
OPI==1B22 ;OPERATION INCOMPLETE
HCRC==1B27 ;HEADER CRC ERROR
HCE==1B28 ;HEADER COMPARE ERROR
ECH==1B29 ;ECC HARD
FER==1B31 ;FORMAT ERROR
PAR==1B32 ;PARITY
;ERROR REG 3 STATUS BITS
OCYL==1B20 ;OFF CYLINDER
SKI==1B21 ;SEEK CYLINDER
;OFFSET REGISTER
FMT22==1B23 ;22-SECTOR MODE
ECI==1B24 ;ECC INHIBIT
;CONTROL REGISTER BIT ASSIGNMENTS
CR.SC==100000 ;(R) SPECIAL CONDITION (ALL ERRORS)
CR.TRE==40000 ;(R/W) TRANSFER ERROR
CR.CPE==20000 ;(R) CONTROL BUS PARITY ERROR
CR.DVA==4000 ;(R) DRIVE AVAILABLE
CR.PSL==2000 ;(R/W) PORT SELECT
CR.RDY==200 ;(R) READY
CR.IE==100 ;(R/W) INTERRUPT ENABLED
;STATUS REGISTER BIT ASSIGNMENTS
CS.DLT==100000 ;(R) DATA LATE (OVERRUN)
CS.WCE==40000 ;(R) WRITE CHECK ERROR
CS.UPE==20000 ;(R/W) UNIBUS PARITY ERROR
CS.NXD==10000 ;(R) NON-EXISTANT DRIVE
CS.NXM==4000 ;(R) NON-EXISTANT MEMORY
CS.PGE==2000 ;(R) PROGRAM ERROR
CS.MXF==1000 ;(R/W) MISSED TRANSFER
CS.DPE==400 ;(R) DATA BUS PARITY ERROR
CS.OR==200 ;(R) OUTPUT READY
CS.IR==100 ;(R) INPUT READY
CS.CLR==40 ;(W) CONTROLLER CLEAR
CS.PAT==20 ;(R/W) PARITY TEST
CS.BAI==10 ;(R/W) UNIBUS ADDRESS INCREMENT INHIBIT
SUBTTL FILSER CALL PROCESSING
RPXUNL::SKIPA T1,[FNCUNL] ;UNLOAD
RPXRCL::MOVEI T1,FNCRCL ;RECAL
PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,RHXBAS##(J) ;SET UP INDEX REGISTER TO RH11 BASE ADDRESS
PUSHJ P,CONECT ;CONECT TO THE DRIVE
JRST RPXDWN ;UNIT IS DOWN
MOVSI T2,DODC ;SET TO CLEAR DESIRED CYLINDER REG
JRST RPXMOV ;AND CONTINUE
RPXPOS::MOVEI T1,FNCSEK ;SET TO DO A SEEK
PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,RHXBAS##(J) ;SET UP INDEX REGISTER TO RH11 BASE ADDRESS
PUSHJ P,CONECT ;CONECT TO THE DRIVE
JRST RPXDWN ;DOWN
HRLI T2,DODC ;SET FOR DATAO TO DESIRED CYL
RPXMOV: SETZ T4,
WRIO T4,DOOF(P1) ;CLEAR OFFSET REGISTER
WRIO T4,DODA(P1) ;CLEAR POSSIBLE ILLEGAL SECTOR
JRST RPXGO ;AND CONTINUE
RPXSTP::PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,RHXBAS##(J) ;SET UP INDEX REGISTER TO RH11 BASE ADDRESS
RDIO T2,DOCR(P1) ;GET RH11 STATUS
RDIO T3,DOCS2(P1)
HRLI T2,(T3)
MOVEI T3,CR.TRE!CR.IE
WRIO T3,DOCR(P1) ;CLEAR CONTROLLER AND ENABLE INTERRUPTS
MOVEI T3,CS.MXF ;CAUSE AN INTERRUPT
WRIO T3,DOCS2(P1)
MOVEI T3,CR.RDY
TIOE T3,DOCR(P1) ;READY BIT ON NOW?
AOS -1(P) ;YES, SKIP RETURN
MOVSI T4,400000 ;CLEAR SIGN BIT OF RPXFNC
ANDCAM T4,RPXFNC##(J) ; AS A FLAG THAT WE'RE IN RPXSTP (HNGDSK)
SETZB T1,T3 ;GET DATAI'S FROM KONEBK
POPJ P,
RPXLTM::PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,RHXBAS##(J) ;SET UP RH11 BASE ADDRESS
LDB T3,UNYPUN## ;UNIT NUMBER
MOVEI T4,CS.BAI ;BUS ADDRESS INHIBIT
TIOE T4,DOCS2(P1) ;IS IT SET?
ADDI T3,(T4) ;YES--THEN PRESERVE IT
WRIOB T3,DOCS2(P1) ;SELECT UNIT
MOVEI T4,3 ;MAKE SURE WE DONT TRY TOO MUCH
PUSH P,T1 ;SAVE TARGET BLOCK
RPXLT1: RDIO T1,DOLA(P1) ;GET CONTENTS OF LOOK AHEAD REG
MOVEI T2,CR.TRE!CR.CPE ;
TIOE T2,DOCR(P1) ;ERROR?
JRST TPOPJ## ;YES, ERROR
ANDI T1,3777 ;NO, MASK OUT USEFUL PART
CAIN T3,(T1) ;SAME AS LAST TIME (OR 1ST TIME)?
JRST RPXLT2 ;YES, WE HAVE A GOOD NUMBER
HRRZ T3,T1 ;NO, SAVE PREVIOUS LA CONTENTS
SOJG T4,RPXLT1 ;AND TRY AGAIN
MOVEI T1,^D8333 ;WONT SETTLE - ASSUME 1/2 REVOLUTION
PJRST T2POJ1## ;AND SKIP
RPXLT2: LSHC T3,-6 ;GET SECTOR CNTR, FRACTION TO T4
SKIPGE T4 ;OVER HALF 1 SECTOR?
ADDI T3,1 ;YES, BUMP SECTOR COUNT
POP P,T1 ;RESTORE TARGET BLOCK
LDB T4,UNYBPT## ;GET NUMBER OF BLOCKS PER TRACK
ADDI T1,-2(T4) ;ALLOW A 2-SECTOR FUDGE FACTOR
IDIV T1,T4 ;DESIRED SECTOR TO T2
SUB T2,T3 ;DISTANCE
SKIPGE T1,T2
ADD T1,T4 ;NEGATIVE - ADD 1 REVOLUTION
MOVEI T3,^D16667 ;TIME FOR COMPLETE REVOLUTION
IDIV T3,T4 ;COMPUTE MICRO-SECS PER SECTOR
IMUL T1,T3 ;MICROSECONDS TO TARGET
PJRST CPOPJ1## ;GOOD RETURN
RPXRDF::SKIPA T1,[FNCRHD] ;READ HEADERS AND DATA
RPXWTF::MOVEI T1,FNCWTF ;WRITE HEADERS AND DATA (FORMAT)
JRST RPXDGO
RPXRDC::SKIPA T1,[FNCRED!FCOMP];READ 22-SECTOR MODE
RPXWTC::MOVEI T1,FNCWRT!FCOMP ;WRITE 22-SECTOR MODE
JRST RPXDGO
RPXRED::SKIPA T1,[FNCRED!FESI] ;READ, DONT STOP ON ERROR
RPXWRT::MOVEI T1,FNCWRT!FESI ;WRITE, DONT STOP ON ERROR
JRST RPXDGO
RPXRDS::SKIPA T1,[FNCRED] ;READ, STOP ON ERROR
RPXWTS::MOVEI T1,FNCWRT ;WRITE, STOP ON ERROR
RPXDGO: SETZM RPXFLG##(J) ;INDICATE DATA-XFER FUNCTION
PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,RHXBAS##(J) ;SET UP RH11 BASE ADDRESS
PUSHJ P,CONECT ;CONECT TO THE DRIVE
JRST RPDWND ;DOWN
TRNE T1,FESI ;STOP ON ERROR?
AOS RPXFLG##(J) ;NO, SET RPXFLG POSITIVE
LDB T4,UNYUTP## ;GET UNIT TYPE
CAIN T4,2 ;RM03?
JRST RPXDG0 ;YES, TREAT DIFFERENTLY
TRNE T1,FCOMP ;IF 22-SECTOR MODE,
IDIVI T3,^D22 ; ADDRESSING IS DIFFERENT
TRNN T1,FCOMP
IDIVI T3,^D20 ;COMPUTE SECTOR, BLOCK
JRST RPXDG1
RPXDG0:
TRNE T1,FCOMP ;11 COMPATIBILITY MODE?
IDIVI T3,^D32 ;YES, 32 SECTORS PER TRACK
TRNN T1,FCOMP
IDIVI T3,^D30 ;RM03 HAS 30 SECTORS PER TRACK
RPXDG1: DPB T3,[POINT 5,T4,27] ;SET T4 FOR DESIRED ADDRESS REGISTER
WRIO T2,DODC(P1) ;SET DESIRED CYLINDER
SETZ T2,
TRNE T1,FCOMP ;11 COMPATIBILITY MODE?
TROA T2,ECI+FMT22 ; LIGHT FMT22 IN OFFSET REGISTER
TRNE T1,FESI ;IF NOT STOPPING ON ERROR
TRCA T2,ECI ;CLEAR OFFSET, SET ECI
TRNN T1,10 ;IF WRITING
WRIO T2,DOOF(P1) ;CLEAR OFFSET REGISTER
MOVE T3,KONCHN##(J) ;GET ADDRESS OF CHANNEL DATA BLOCK
MOVE T2,CHNIEA##(T3) ;GET INITIAL ELEVEN STYLE ADDRESS
WRIO T2,DOBA(P1) ;AND LOAD THE BUS ADDRESS REGISTER
MOVE T2,CHNBTC##(T3) ;GET THE BYTE COUNT FOR THIS TRANSFER
LSH T2,-1 ;MAKE ELEVEN STYLE WORD COUNT
MOVNS T2 ;2'S COMPLEMENT
WRIO T2,DOWC(P1) ;LOAD THE WORD COUNT REGISTER
MOVE T2,CHNNXF##(T3) ;NO-XFER FLAG
JUMPGE T2,RPXDG2 ;IS THIS A NO XFER READ?
MOVEI T2,CS.BAI ;YES--BUS ADDRESS INHIBIT
BSIOB T2,DOCS2(P1) ;SET IT
RPXDG2: MOVE T2,T4 ;DESIRED ADDRESS
HRLI T2,DODA ;SET TO DATAO THE RIGHT REGISTER
;HERE TO INITIATE AN OPERATION
;
;CALL T1= FUNCTION
; T2= REGISTER TO LOAD,,VALUE
RPXGO: HLRZ T4,T2 ;GET REGISTER TO LOAD
ADD T4,P1 ;COMPUTE ADDRESS OF REGISTER
WRIO T2,(T4) ;AND WRITE IT
LDB T4,UNYPUN## ;UNIT NUMBER GETS SAVED FOR INTERRUPT LEVEL
TLO T1,400000(T4) ;LIGHT THE DISK NOT HUNG BIT(AN RPXKON HACK)
TRNE T1,40 ;IF A DATA XFER COMMAND,
MOVEM T1,RPXFNC##(J) ;SAVE COMMAND IN RPXFNC
MOVEM T1,UNILAS##(U) ;SAVE AS LAST COMMAND FOR THE DRIVE
TRZ T1,FCOMP!FESI ;CLEAR SOFTWARE BITS BEFORE STARTING IO
TRO T1,CR.IE ;SET INTERRUPT ENABLE BIT
WRIOB T1,DOCR(P1) ;START AND TURN ON PI
DSKON
PJRST CPOPJ1## ;AND SKIP RETURN
;HERE TO ENABLE INTERRUPTS
INTENB: MOVEI T1,CR.IE ;INTERRUPT ENABLE BIT
TION T1,DOCR(P1) ;IF INT ENB SET, LEAVE IT ALONE
WRIOB T1,DOCR(P1) ; ELSE SET IT
POPJ P, ;RETURN
;HERE IF A DRIVE IS DOWN WHEN WE'RE TRYING TO START IO
RPDWND:
SETOM RPXFLG##(J) ;NOT DOING IO NOW
;HERE IF A DRIVE IS DOWN WHEN WE'RE TRYING TO SEEK/RECAL
RPXDWN:
MOVE T1,T3 ;ERROR FLAGS INTO T1
MOVEI T4,CR.IE ;INTERRUPT ENABLE BIT
BSIOB T4,DOCR(P1) ;ENABLE INTERRUPTS
DSKON
RDIO T2,DOCR(P1) ;GET "CONI" STATUS
RDIO T3,DOCS2(P1)
HRLI T2,(T3)
MOVE T3,KONEBK##+1(J);SET RH(T3)=DRIVE STATUS
HRL T3,KONEBK##+2(J); AND LH = ERROR REGISTER
POPJ P, ;AND NON-SKIP RETURN TO FILSER
SUBTTL GENERAL CONTROLLER-TO-DRIVE CONNECT ROUTINE
;CONNECT RH11 TO A DRIVE
;CALL U= UNIT DATA BLOCK
; P1= RH11 MASSBUS REGISTERS BASE ADDRESS
; T1= FUNCTION TO BE PERFORMED
;RETURN CPOPJ IF DRIVE/CONTROLLER DOWN
;RETURN CPOPJ1 IF OK (T1 PRESERVED)
; T2= CYLINDER
; T3= REMAINDER FROM CYLINDER COMPUTATION
CONECT: DSKOFF ;IF ON UUO LEVEL, GUARD AGAINST INTERRUPTS
MOVEI T4,CR.RDY ;GET RH11 READY BIT
TRNE T1,40 ;TRYING TO DO IO?
TIOE T4,DOCR(P1) ;YES, KONTROLLER BUSY?
JRST CONEC1 ;NO, ALL IS OK
MOVEI T2,CS.CLR ;SET RDY
WRIOB T2,DOCS2(P1) ;BY CLEARING CONTROLLER
AOS UNIHNG##(U) ;BUMP A COUNTER
TION T4,DOCR(P1) ;DID RDY SET?
JRST CONER2 ;NO--CALL DRIVE OFF-LINE
CONEC1:
LDB T4,UNYPUN## ;GET UNIT NUMBER
MOVEI T2,CS.BAI ;BUS ADDRESS INHIBIT
TIOE T2,DOCS2(P1) ;IS IT SET?
ADDI T4,(T2) ;YES--THEN PRESERVE IT
WRIOB T4,DOCS2(P1) ;AND SELECT PROPER UNIT
RDIO T2,DOSR(P1) ;AND READ DRIVE'S STATUS REGISTER
TRZ T2,LST+PGM+OM ;DON'T CARE ABOUT LAST SECTOR TRANSFERRED OR PGM
CAIE T2,GUDSTS ;DRIVE OK?
JRST CONERR ;NO
CONEC2: MOVE T2,UNIBLK##(U) ;YES, GET DESIRED BLOCK
LDB T3,UNYUTP## ;GET UNIT TYPE
CAIE T3,2 ;RMO3?
SKIPA T3,[^D418,,^D380];NO
MOVE T3,[^D160,,^D150];YES
TRNE T1,FCOMP ;COMPARTIBILITY MODE?
HLRS T3 ;YES,MORE SECTORS
IDIVI T2,(T3) ; ADDRESSING IS DIFFERENT
MOVEM T2,UNICYL##(U) ;SAVE IN UDB
PJRST CPOPJ1## ;AND SKIP-RETURN
;HERE IF ERROR TRYING TO CONNECT
CONERR: LDB T4,UNYPUN## ;GET UNIT NUMBER
CAIE T2,GUDSTS+WRL ;STATUS OK EXCEPT FOR WRITE-LOCK?
JRST CONER1 ;NO, REALLY IS BAD
LDB T3,[POINT 3,T1,32] ;YES, IS THIS A WRITE?
CAIE T3,6
JRST CONEC2 ;NO, ITS OK
SETZ T3, ;WRITE-INDICATE NOT OFF-LINE,
POPJ P, ; BUT BAD
CONER1: MOVEI T3,KOPOFL ;ASSUME OFF-LINE
TRNE T2,MOL ;MEDIUM ON-LINE?
TRNE T2,VV ;YES, VOLUME VALID?
JRST CONER2 ;YES
PUSHJ P,NOWUP ;ACKNOWLEDGE THE DRIVE
RDIO T2,DOSR(P1) ;READ THE STATUS REG
TRNE T2,VV ;DRIVE IS DOWN IF VV DIDNT SET
JRST CONEC1 ;AND GO TRY AGAIN
CONER2: PUSH P,U ;RDREG CLOBBERS U
PUSH P,T1
PUSHJ P,RDREG ;READ DRIVE REGISTERS
PUSHJ P,DVCLR ;NO, CLEAR THE DRIVE
POP P,T1
POP P,U
RDIO T2,DOSR(P1) ;READ STATUS REG
TRZ T2,LST+PGM+OM
CAIN T2,GUDSTS ;DID DRIVE CLEAR FIX IT?
JRST CONER4 ;YES, RETRY
HRL T2,KONEBK##+2(J);MOL AND VV ON, BUT STATUS SAYS ERROR
;READ THE ERROR REGISTER
MOVEI T3,KOPOFL## ;PRETEND THE UNIT IS OFF-LINE
TLNE T2,UNS ;UNSAFE?
TRO T3,KOPFUS## ;YES, SO INDICATE
TRNE T2,MOL ;REALLY OFF-LINE?
TRO T3,KOPUSI## ;NO, STATUS INCONSISTENT
AOJA T1,CPOPJ## ;AND NON-SKIP, INSURING THAT T1 ISNT 0
CONER4: SKIPL UNIECT##(U) ;IN ERROR RECOVERY?
JRST CONEC2 ;YES, CANT SAVE REGS
SETZM UNIECT##(U) ;NO. FLAG FILIO TO KICK DAEMON
MOVSI T2,KONEBK##(J) ;STORE REGS IN "AT ERROR" HALF
HRRI T2,UNIEBK##(U) ; OF UDB FOR DAEMON
BLT T2,UNIEBK##+17(U)
JRST CONEC2 ;AND DO THE OPERATION
;ROUTINE CALLED WHEN VV ISNT ON FOR A DRIVE - DOES A DRIVE CLEAR, ACKNOWLEDGE
;ENTER T4=DRIVE NUMBER
;PRESERVES T1,T4
NOWUP: PUSHJ P,DVCLR ;CLEAR THE DRIVE
MOVEI T2,FNCACK
WRIOB T2,DOCR(P1) ;DO A PACK ACKNOWLEDGE
POPJ P, ;AND RETURN
SUBTTL INTERRUPT LEVEL PROCESSING
RPXINT::
PUSHJ P,SAVE2## ;PRESERVE SOME AC'S
MOVE P1,RHXBAS##(J) ;SET UP INDEX REG TO RH11 BASE ADDRESS
RDIO T2,DOAS(P1) ;READ ATTN SUMMARY REGISTER
SETZB S,T4
ANDI T2,377 ;ANY ATTENTION ON?
JUMPE T2,NOATTN ;NO
PUSH P,T2 ;SAVE IT (CLEAR IF NO ERRORS LATER ON)
HRRZ T1,T2 ;BITS FOR ATTN-DRIVES
MOVEI P2,CS.BAI ;BUS ADDRESS INHIBIT
TION P2,DOCS2(P1) ;IS IT SET?
SETZ P2, ;NO--THEN DON'T PRESERVE IT
RPXIN2: LSHC T1,-1 ;TEST THE NEXT DRIVE
JUMPGE T2,RPXIN4 ;NOT THIS ONE
ADDI T4,(P2) ;PUT IN BAI IF NEEDED
WRIOB T4,DOCS2(P1) ;SELECT THIS DRIVE
SUBI T4,(P2) ;TAKE OUT BAI IF SET
RDIO T2,DOSR(P1) ;AND READ ITS STATUS REGISTER
HRRZ U,KONTBP##(J) ;SET UP U TO UDB
ADDI U,(T4)
MOVE U,(U)
TRNN T2,MOL ;ON-LINE?
JRST RPXI3C ;OFF-LINE INTERRUPT, TELL FILSER
TRNE T2,VV ;YES, VOLUME VALID?
TRNN T2,ERR ;YES, ERROR?
JRST RPXIN3 ;FREE INTERRUPT OR NO ERR
MOVSI T3,(T4) ;ERROR - WAS THE DRIVE DOING IO?
XOR T3,RPXFNC##(J)
MOVE F,RPXFLG##(J)
TLNN T3,7 ;IF SAME UNIT
JUMPGE F,RPXIN4 ;ERROR ON XFERRING DRIVE IF RPXFLG NON-NEG
;HERE IF INTERRUPT & NO XFER IN PROGRESS AND THE DRIVE HAD AN ERROR
;FILIO IGNORES US IF WE TELL HIM THERE WAS AN ERROR DURING A POSITION
;COMMAND. SO TELL HIM THAT THE POSITION COMMAND WAS SUCCESSFUL.
;THEN DO AN IMPLIED SEEK LATER ON.
MOVEI T3,SKI
TION T3,DOER3(P1) ;SKIP IF SEEK INCOMPLETE IS ON
JRST RPXI2A
RDIO T3,DOER(P1)
TRNE T3,UNS
JRST RPXI2A
TRNN T2,DRY ;IF DRIVE READY IS OFF THE UNIT IS RECALIBRATING
JRST RPXIN4 ; SO WAIT FOR NEXT INTERRUPT (DON'T TELL FILSER)
PUSHJ P,DVCLR ;RECAL DONE, CLEAR THE DRIVE
;(UNIT IS NOT ON RIGHT CYLINDER, BUT IMPLIED SEEK WILL WIN)
SKIPA T2,[1]
RPXI2A: MOVSI T2,1
ADDM T2,UNIPCT##(U) ;UPDATE NUMBER OF POSITIONING ERRORS
PUSHJ P,DVCLR ;MAKE SURE THE ERROR IS RESET
PUSHJ P,RDIPST ;CLEAR POSSIBLE GARBAGE FROM DA & DC
JRST RPXI3B ;PUSH ON
;HERE FOR ATTENTION INTERRUPT, NO ERROR INDICATED FOR DRIVE
RPXIN3: TRNN T2,VV ;FREE INTERRUPT?
PUSHJ P,NOWUP ;YES, DO A PACK ACKNOWLEDGE
RPXI3B: IOR S,BITTBL##(T4) ;LIGHT THE ATTN BIT FOR FILIO
JRST RPXIN4 ;AND CONTINUE
;HERE WHEN A UNIT GOES OFF-LINE
RPXI3C: TRNN T2,ERR ;IS THERE AN ERROR?
JRST RPXI3Z ;NO
PUSHJ P,DVCLR ;YES, CLEAR IT
RDIO T2,DOSR(P1) ;DID IT CLEAR?
TRNN T2,ERR
JRST RPXI3Z ;YES
SETZ T2, ;NO, CLEAR IT THE HARD WAY
WRIO T2,DOER3(P1)
WRIO T2,DOER2(P1)
WRIO T2,DOER(P1)
RPXI3Z: PUSHJ P,FILDN## ;TELL FILSER UNIT WENT AWAY
RPXIN4: JUMPE T1,RPXIN5 ;GO IF NO MORE ATTNS
AOJA T4,RPXIN2 ;AT LEAST 1 MORE - TRY THE NEXT DRIVE
RPXIN5: POP P,T2 ;NO ERRORS - CLEAR THE ATTN SUMMARY REGISTER
WRIO T2,DOAS(P1) ; OF ALL THE DRIVES WE JUST LOOKED AT
SKIPGE RPXFLG##(J) ;DATA XFER IN PROGRESS?
JUMPE S,INTENB ;NO--DISMISS INTERRUPT IF JUST A POWER-DOWN ATTN
;YES--FALL INTO NOATTN
NOATTN: SKIPL RPXFLG##(J) ;DATA XFER IN PROGRESS?
JRST DATINT ;YES
RDIO T2,DOCR(P1) ;NO, GET "CONI" STATUS
RDIO T4,DOCS2(P1)
TRNE T4,CS.NXD ;NON-EX DRIVE?
JRST [MOVEI T1,CS.CLR ;YES MUST CLEAR CONTROLLER
WRIOB T1,DOCS2(P1)
JRST .+1] ;GIVE INTERRUPT TO FILSER
HRLI T2,(T4)
HRRI S,OPPOS ;INDICATE POSITION INTERRUPT
JRST CALLIO ;AND TELL FILSER
DATINT: RDIO T2,DOCR(P1) ;GET THE CONTROLLER STATUS REGISTER
LSH T2,-10 ;POSITION 2 BIT ADDRESS EXTENSION
RDIO T4,DOBA(P1) ;AND THE BUS ADDRESS REGISTER
DPB T2,[POINT 2,T4,19] ;MAKE AN 18 BIT ADDRESS
RDIO T2,DOWC(P1) ;GET THE REMAINS IN THE WORD COUNT REGISTER
HRL T4,T2 ;COMBINE
MOVEM T4,KONIOC##(J) ;AND STORE IN KONIOC FOR FILIO TO COMPARE
MOVE U,RPXFNC##(J)
TRNN U,10 ;IS IT A WRITE?
TRO S,OPWRT ;(OPRED=0)
HLRZ T4,U ;DRIVE DOING XFER IS IN HERE
ANDI T4,7 ;GET ONLY DRIVE NUMBER
WRIOB T4,DOCS2(P1) ;SELECT IT AND CLEAR BAI
MOVEI T2,ECI!FMT22 ;CLEAR ECI AND/OR FMT22
TRNE U,FESI!FCOMP ; IF THEY WERE ON FOR THE DRIVE
BCIO T2,DOOF(P1) ;ZAP
TLO S,(T4) ;DRIVE NUMBER IN LH
RDIO T3,DOSR(P1) ;READ THE DRIVE STATUS REGISTER
RDIO T2,DOER(P1) ;READ THE ERROR REGISTER
HRLI T3,(T2) ;T3=ERROR,,STATUS
RDIO T2,DOCR(P1) ;GET RH11 STATUS
RDIO T4,DOCS2(P1)
HRLI T2,(T4)
MOVE U,KONCUA##(J) ;UNIT WE'RE TALKING TO
TRNN T2,CR.TRE!CR.CPE;ERROR?
TRNE T3,ERR
JRST ERROR ;YES
SKIPL RPXFNC##(J) ;CALL FROM RPXSTP (FROM HNGDSK)?
JRST ERROR ;YES, CAUSE ERROR SO WILL RETRY
SKIPG UNIECT##(U) ;IN ERROR RECOVERY?
JRST DATDON ;NO
PUSH P,T2 ;YES, READ ALL DRIVE REGS
PUSHJ P,RDREG ; SINCE WE JUST WON
POP P,T2
DATDON: SETOM RPXFLG##(J) ;NO, INDICATE NO XFER NOW IN PROGRESS
MOVE T4,KONCHN##(J) ;CHAN DATA BLOCK ADDRESS
SETZM CHNNXF##(T4) ;CLEAR NO-XFER FLAG
CALLIO: MOVEI T4,CR.TRE!CR.IE ;CLEAR ERRORS, ENABLE INTERRUPTS
WRIO T4,DOCR(P1) ;AND START
DSKON
MOVE T1,S ;T1=ATTN+DRIVE,,ERROR+FUNCT
PJRST FILINT## ;GO TELL FILSER
ERROR: TLNE T3,DCK ;DATA CHECK ERROR?
TROA S,IODTER ;YES
TRO S,IODERR ;NO
TLNE T3,FER ;FORMAT ERROR?
TROA S,IODTER+IODERR ;YES, LIGHT BOTH ERROR BITS
TRNN T4,CS.NXM!CS.DLT ;CHANNEL-TYPE PROBLEM?
JRST ERROR1 ;NO--GO ON
TRNE T4,CS.DLT ;DATA LATE?
TRO S,IOVRUN ;YES
MOVE T1,KONCHN##(J) ;GET CHANNEL DATA BLOCK
RDIO T4,@CHNUBA##(T1) ;READ UBA STATUS REGISTER
TRNE T4,UNBTMO ;DID UBA GET A NXM?
TRO S,IOCHNX ;YES
TRNE T4,UNBBME ;DID UBA HIT BAD MEMORY?
TRO S,IOCHMP ;YES
MOVEI T4,UNBTMO!UNBBME ;CLEAR ANY OF THESE UBA
BSIO T4,@CHNUBA##(T1) ; ERRORS IF SET
JRST ERRDON ;FINISH UP
ERROR1: TLNN T3,HCE+HCRC ;HEADER ERROR?
JRST ERROR2
TRO S,IOHDER+IODTER ;YES
TRZ S,IODERR
ERROR2: SKIPG RPXFLG##(J) ;IF STOPPING ON ERROR,
TRNE S,IODERR ;AND DATA ERROR IS UP
JRST ERRDON
SKIPGE UNIECT##(U) ;IF INITIAL ERROR
JRST ERRDON ; REREAD BEFORE TRYING ECC
TLNE T3,DCK ;DATA CHECK?
TLNE T3,ECH ;HARD DATA CHECK?
CAIA
TRO S,IOECCX ;NO, INDICATE RECOVERABLE ERROR
ERRDON: PUSH P,T2 ;SAVE CONI STATUS
PUSH P,T3 ;SAVE STATUS, ERROR REGISTERS
LDB T4,UNYPUN## ;GET UNIT NUMBER
PUSHJ P,RDREG
PUSHJ P,DVCLR ;CLEAR THE DRIVE
POP P,T3 ;RESTORE DRIVE REGISTERS
POP P,T2 ;RESTORE CONI
JRST DATDON ;AND GO TELL FILSER
;HERE TO COMPUTE ECC MASK, POSITION
RPXECC::MOVE T1,KONEBK##+16(J) ;GET POSITION
SOJL T1,CPOPJ## ;ERROR IF 0
MOVE T4,KONEBK##+17(J) ;GET PATTERN
SETZ T3, ;CLEAR MASK EXTENSION
MOVSI T2,DEPCPT## ;16-BIT DISK?
TDNE T2,DEVCPT##(F)
JRST RPXEC6 ;DO 16-BIT ECC
IDIVI T1,^D36 ;COMPUTE WORD LOC, POSITION IN WORD
EXCH T2,T4 ;T2,,T3 = MASK; T4 = BIT OFFSET
ROTC T2,(T4) ;POSITION MASK
PJRST CPOPJ1## ;AND SKIP-RETURN
;HERE TO DO 16-BIT ECC
RPXEC6: IDIVI T1,^D32 ;COMPUTE WORD, BIT OFFSETS (32 DATA BITS)
EXCH T2,T4 ;T2,,T3 = MASK; T4 = BIT OFFSET
JUMPLE T4,CPOPJ1## ;IF NO SHIFT NEEDED, WE'RE DONE
RPXEC7: ROTC T2,1 ;ROTATE PATTERN TOWARD ERROR
TLZE T2,200000 ;IF CARRY OUT OF HI LH
TRO T3,1 ; CARRY INTO LO RH
TRZE T2,200000 ;IF CARRY OUT OF HI RH
TLO T2,1 ; CARRY INTO HI LH
SOJG T4,RPXEC7 ;LOOP UNTIL MASK IS IN PLACE
JRST CPOPJ1## ;AND SKIP-RETURN
;ROUTINE TO CLEAR POSSIBLE GARBAGE FROM DRIVE REGS
RDIPST: SKIPA T2,[FNCPST] ;CLEAR ALL BUT DA AND DC
;ROUTINE TO CLEAR A DRIVE AND MAKE SURE IT REALLY CLEARED
;PRESERVES T1
DVCLR: MOVEI T2,FNCCLR ;CLEAR DRIVE
PUSH P,T2 ;SAVE FUNCTION CODE
RDIO T2,DOOF(P1) ;DRIVE CLEAR ZEROES OFFSET REG
EXCH T2,(P) ;SAVE DOOF, GET FUNCTION CODE
WRIOB T2,DOCR(P1) ;ZAP
WRIOB T2,DOCR(P1) ;SOME DRIVES NEED 2!
POP P,T2 ;RESTORE OFFSET REG
WRIO T2,DOOF(P1) ; SO SYSERR WILL REPORT IT
; AND TEST ON 1ST ERROR WILL WORK
RDIO T2,DOAS(P1) ;READ ATTN SUMMARY REGISTER
MOVEI T3,1 ;IS ATTN NOW UP?
LSH T3,(T4)
TDNN T2,T3
POPJ P, ;NO, EVERYTHING IS OK
MOVE T2,T3 ;YES, THIS ERROR CAN'T BE CLEARED
WRIO T2,DOAS(P1) ;CLEAR BIT IN ATTN SUMMARY REG
POPJ P, ; AND RETURN
;HERE WITH T1=NUMBER OF THE RETRY IF A DATA ERROR. TELL FILSER WHAT TO DO
RPXERR::PUSHJ P,SAVE1## ;SAVE A REGISTER
MOVE P1,RHXBAS##(J) ;AND SET UP RH11 BASE ADDRESS
TLO M,400000
SOJN T1,RPXER1 ;IF FIRST ERROR,
RDIO T3,DOSR(P1) ;READ DRIVE STATUS REGISTER
RDIO T2,DOOF(P1) ;READ THE OFFSET REGISTER
TRNE T3,OM ;OFFSET RM03?
JRST RPXER0 ;YES
TRNN T2,70 ;OFFSET RP06?
JRST RPXER1 ;NO--DRIVE ISNT OFFSET - CONTINUE
RPXER0: MOVEI T1,RTCNDX ;DRIVE IS OFFSET - RETURN TO CENTERLINE
JRST RPXER2
;HERE IF NOT 1ST ERROR, OR 1ST AND DRIVE ISNT OFFSET
RPXER1::SUBI T1,^D15 ;IF LESS THAN 16TH RETRY,
JUMPL T1,RETRY ;RETURN 0 (JUST RETRY)
CAILE T1,^D13 ;IF TRIED EVERYTHING AND DIDNT RECOVER
JRST RPXER3 ;GIVE UP
CAIN T1,^D13 ;IF THE LAST TIME
JRST LASTIM ; TRY LAST TIME
TRNE T1,1 ;IF DIDNT TRY TWICE AT THIS OFFSET,
JRST RETRY ;TRY A SECOND TIME
LSH T1,-1 ;TRIED TWICE - DO NEXT OFFSET
RPXER2: PUSHJ P,CONECT ;CONNECT TO DRIVE
JRST RETRY ;DOWN - PRETEND JUST STRAIGHT RETRY
MOVE T2,OFSTBL(T1) ;OK, GET OFFSET
LDB T1,UNYUTP## ;UNIT TYPE
SKIPE T1 ;RP06 OR RM03?
HLRS T2 ;YES, GET OTHER OFFSET VALUE
HRLI T2,DOOF ;SET TO DO OFFSET
MOVEI T1,FNCOFS ;FUNCTION = OFFSET
TRNE T2,-1 ;IS THIS OFFSET = 0?
JRST RPXR2A ;NO--THEN GO DO IT
MOVE T2,KONEBK##+2(J) ;YES--RETURN TO CENTERLINE
TRNE T2,HCE ; UNLESS HCE=1, HCRC=0
TRNE T2,HCRC
SKIPA T1,[FNCRTC]
MOVEI T1,FNCRCL ;IN WHICH CASE DO A RECAL
RPXR2A: HRROS RPXFLG##(J) ;SET RPXFLG NEGATIVE
PUSHJ P,RPXGO ;START THE OFFSET
JFCL
JRST OFFSET ;AND TELL FILSER OFFSET IS IN PROGRESS
;HERE ON A HARD ERROR
RPXER3: CAIN T1,^D14 ;DXES ON (30TH TIME)?
JRST RETRY ;YES, THIS TIME STOP ON ERROR
JRST GIVEUP ;NO, TELL DAEMON ABOUT IT
ERCODE RETRY,0 ;RETRY
ERCODE OFFSET,1 ;OFFSET
ERCODE LASTIM,2 ;LAST TIME
ERCODE GIVEUP,3 ;GIVE UP
OFSTBL: 10,,20 ;+400 MICRO INCHES
210,,220 ;-400
20,,40 ;+800
220,,240 ;-800
30,,60 ;+1200
230,,260 ;-1200
0,,0 ;RTC
RTCNDX==.-OFSTBL-1
;HERE TO CHECK CAPACITY & STATUS OF UNIT ON RH11
RPXCPY::
MOVE W,RHXBAS##(J) ;SET UP RH11 BASE ADDRESS
LDB T2,UNYPUN## ;GET UNIT NUMBER
MOVEI T3,CS.BAI ;BUS ADDRESS INHIBIT
TIOE T3,DOCS2(W) ;IS IT SET?
ADDI T2,(T3) ;YES--THEN PRESERVE IT
WRIOB T2,DOCS2(W) ;SELECT UNIT
RDIO T2,DODT(W) ;READ DRIVE-TYPE REGISTER
MOVEM T2,UNIEBK##+6(U);SAVE FOR SYSERR
LDB T3,[POINT 9,T2,35]
SETZ T4,
; CAIN T3,21 ;RP04? (NOT SUPPORTED ON 2020)
; JRST RPXCP2 ;YES, UNIT TYPE 0
CAIN T3,22 ;RP06
AOJA T4,RPXCP2 ;YES, UNIT TYPE 1
CAIE T3,24 ;RM03?
JRST RPXCP3 ;NOT A LEGAL UNIT TYPE, NO SUCH DRIVE
MOVEI T4,2 ;RMO3 IS UNIT TYPE 2
RPXCP2: RDIO T2,DOSR(W) ;YES, READ STATUS REGISTER
TRNN T2,MOL ;MOL?
TLO T4,KOPUHE ;NO, INIT IS OFF-LINE OR DOWN
RDIO T2,DOSN(W) ;READ DRIVE SERIAL NUMBER
MOVEM T2,UNIEBK##+10(U);AND STORE IN UDB
TLO T4,KOP22B## ;PRETEND RH11 IS 22 BIT
MOVE T1,BLKPRU(T4) ;BLOCKS PER UNIT
MOVE T2,BLKPUM(T4) ;BLOCKS PER UNIT INCLUDING MAINT CYLS
MOVE T3,BLKPUC(T4) ;BLOCKS PER UNIT IN 10/11 COMPAT MODE
MOVE W,BLKTBC(T4) ;BLKS PER TRK,, BLKS PER CYL
AOS (P) ;SET FOR SKIP RETURN
JRST RPXCP4 ;CLEAR POSSIBLE RAE AND EXIT
RPXCP3: MOVSI T4,KOPUHE## ;OFF LINE OR DOWN
TLO T4,KOPNSU## ;NO SUCH UNIT
SETZB T1,T2 ;NO BLOCKS PGR UNIT - CANT READ
RPXCP4: POPJ P,
BLKPRU: DEC 154280 ;406 CYLINDERS
DEC 307800 ;810 CYLINDERS
DEC 123150 ;821 CYLINDERS
BLKPUM: DEC 156180 ;411 CYLINDERS
DEC 309700 ;815 CYLINDERS
DEC 123450 ;823 CYLINDERS
BLKPUC: DEC 171798 ;22*19*411
DEC 340670 ;22*19*815
DEC 131680 ;32*5*823
BLKTBC: ^D20,,^D380 ;BLKS/TRK,,BLKS/CYL(RP04) (NOT SUPPORTED ON 2020)
^D20,,^D380 ; (RP06)
^D30,,^D150 ; (RM03)
;END FTDHIA
;ENTRY TO READ DRIVE REGS
RPXREG::
PUSHJ P,SAVE1## ;GET A REGISTER
MOVE P1,RHXBAS##(J) ;AND SET UP RH11 BASE ADDRESS
PUSH P,U ;RDREG WIPES U
LDB T4,UNYPUN## ;DRIVE NUMBER
MOVEI T1,CS.BAI ;BUS ADDRESS INHIBIT
TIOE T1,DOCS2(P1) ;IS IT SET?
ADDI T4,(T1) ;YES--THEN PRESERVE IT
WRIOB T4,DOCS2(P1) ;SELECT UNIT
PUSHJ P,RDREG ;READ REGS
PJRST UPOPJ## ;RESTORE U AND RETURN
;SUBROUTINE TO READ ALL DRIVE REGISTERS
;PRESERVES T3,T4 CLOBBERS U
RDREG: PUSH P,P2 ;GET SOME WORKING REGISTERS
PUSH P,P3 ;
MOVE T1,KONREG##(J) ;NUMBER OF DRIVE REGISTERS TO READ
MOVEI U,KONEBK##(J) ;WHERE TO STORE THEM
ADDI U,-1(T1) ;POINT AT TOP OF BLOCK
MOVE P2,[POINT 6,RH11OF]
RDREG1: ILDB P3,P2 ;GET REGISTER OFFSET
ADD P3,P1 ;COMPUTE ADDRESS OF REGISTER
RDIO T2,(P3) ;READ THE REGISTER
MOVEM T2,(U) ;SAVE IN KONTROLLER DB
SUBI U,1
SOJG T1,RDREG1 ;AND GO READ ANOTHER
MOVE P2,KONCHN##(J) ;GET ADDRESS OF CHANNEL DATA BLOCK
RDIO T2,@CHNUBA##(P2);READ UBA STATUS REGISTER
MOVEM T2,KONECR##(J) ;SAVE HERE IN KDB
RDIO T2,DOCR(P1) ;GET RPCS1
LSH T2,-10 ;POSITION 2 BIT ADDRESS EXTENSION
RDIO T1,DOBA(P1) ;GET THE ENDING BUS ADDRESS
DPB T2,[POINT 2,T1,19] ; AND PUT IN HIGH ORDER BITS
IDIVI T1,UBAMUL ;COMPUTE MAP REGISTER OFFSET
ADDI T1,UBAEXP ;ADD IN THE BASE ADDRESS
HLL T1,CHNUBA##(P2) ;PUT IN PROPER UBA NUMBER
RDIO T2,(T1) ;READ OUT MAP SLOT OF LAST WORD XFER'ED
MOVEM T2,KONEDB##(J) ;SAVE HERE IN KDB
POP P,P3 ;RESTORE THE REGISTERS
POP P,P2 ;
POPJ P, ;RETURN
;RH11 REGISTER OFFSETS IN DESCENDING ORDER OF MASSBUS ADDRESSES
RH11OF: BYTE (6) 46,44,42,40,36,34
BYTE (6) 32,30,20,26,06,16
BYTE (6) 24,14,12,0
$LIT
RPXEND: END