Trailing-Edge
-
PDP-10 Archives
-
de-10-omona-v-mc9
-
rpxkon.mac
There are 11 other files named rpxkon.mac in the archive. Click here to see a list.
TITLE RPXKON - DRIVER FOR RP04'S V12074
SUBTTL T WACHS/TW 04 OCT 78
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.
;
;COPYRIGHT (C) 1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VRPKON,12074
;ASSEMBLY INSTRUCTIONS: RPXKON,RPXKON_KONPAR,RPXKON
ENTRY RPXKON
RPXKON::
;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
F22==100 ;COMPATABILITY MODE (SOFTWARE ONLY, NEVER STORED IN DDB)
;DRIVE REGISTERS
DOCR==000000 ;DRIVE CONTROL REGISTER
DOSR==010000 ;STATUS
DOER==020000 ;ERROR
DOER3==150000 ;ERROR REG 3
DOAS==040000 ;ATTENTION SUMMARY
DODA==050000 ;DESIRED ADDRESS (TRACK/SECTOR)
DODT==060000 ;DRIVE TYPE
DOLA==070000 ;LOOK-AHEAD (SECTOR COUNTER)
DOSN==100000 ;SERIAL NUMBER
DOOF==110000 ;OFFSET
DODC==120000 ;DESIRED CYLINDER
DOECP==160000 ;ECC POSITION
DOECB==170000 ;ECC BURST (PATTERN)
;DATAI/DATAO BITS
DIERRS==3600 ;DIB ERRORS
CBTO==2000 ;CONTROL BUS TIME OUT
LR==4000 ;(LH) DISABLE STOP ON ERROR
DXES==200000 ;DISABLE STOP ON ERROR
EXTERN RPXCO4,RPXCI2,RPXDI1,RPXDI2,RPXDO2,RPXDO1,RPXFNC,RPXFLG
;RP04 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
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
DEFINE STALL,<
XLIST
IFN FTKI10!FTKA10,<
IMULI P,1 ;THIS TAKES LESS THAN 3 MIC-SECS ON KL
>
IFN FTKL10,<
IMULI P,1
IMULI P,1
>
LIST
>
;RH10
DOCRC==400000 ;CONTROL REGISTER - CONTROLLER
DODB==500000 ;DATA BUFFER
DORA==540000 ;RAE ERROR STATUS
INTERN RPALCL
;CONI/CONO BITS
CHNPAR==6 ;(LH) CHAN-DETECTED PARITY
DBPE==400000
CHNERR==120000 ;CHAN ERROR OR OVERRUN
OVERUN==20000
ALLERR==736320 ;ALL ERRORS
RPALCL==734210 ;CLEAR ALL ERRORS
DRVERR==600,,236300 ;DRIVE OR CONTROL ERRORS
DONBIT==10
BSYBIT==20
STPBIT==20
ATTNEN==40
SDRAE==200 ;(LH) SELECTED DRIVE REG ACCESS ERR
ALLCLR==734200 ;CLEAR ALL CONI ERRORS
;RH20
;REGISTERS
DO.CT2==710000 ;SECONDARY TRANSFER CONTROL
DO.PBA==72B5 ;PRIMARY BLOCK ADDRESS
DO.CT1==73B5 ;PRIMARY TRANSFER CONTROL
DO.IVI==74B5 ;INTERRUPT VECTOR INDEX
;CONI/CONO
CI.ATN==200 ;ATTEN LIGHT EVEN IF NOT ENABLED
CI.RAE==4000 ;REGISTER ACCESS ERROR
CO.RAE==4000 ;CLEAR RAE
CI.ERR==515000
CO.CLR==5010
CO.MBE==400 ;MASSBUS ENABLE
CO.INI==2000 ;MASSBUS INIT
;DATAO
DO.DRE==400 ;DISABLE REGISTER ACCESS ERROR STOP
;DATAO STCR (LH)
D2.RCP==2000 ;RESET CHANNEL PC
D2.SCS==200 ;STORE CHANNEL STATUS
;DATAI
DI.TRA==200 ;TRANSFER (SHOULD BE ON)
DI.CPE==1000 ;CONTROL BUS PARITY ERROR
;CHANNEL LOGOUT AREA
CS1MPE==1B1 ;MEM PARITY ERROR
CS1NSE==1B2 ;NEGATION OF SBUS ERR
CS1NXM==1B4 ;NXM
CS1RHE==1B10 ;RH20 ERROR
CS1LWC==1B11 ;LONG WORD COUNT
CS1SWC==1B12 ;SHORT WORD COUNT
CS1OVR==1B13 ;OVERRUN
CS1ERR==320360,,0 ;ALL CHAN LOGOUT ERRS
RPXUNL::SKIPA T1,[FNCUNL] ;UNLOAD
RPXRCL::MOVEI T1,FNCRCL ;RECAL
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,CONECT ;CONECT TO THE DRIVE
JRST RPXDWN ;DOWN
HRLI T2,DODC ;SET FOR DATAO TO DESIRED CYL
RPXMOV: PUSH P,T2 ;SAVE CYLINDER
MOVSI T2,DOOF ;CLEAR OFFSET REGISTER
PUSHJ P,DODTO
MOVSI T2,DODA ;CLEAR POSSIBLE ILLEGAL
PUSHJ P,DODTO ; SECTOR FROM DESIRED ADR REG
IFN FTKL10,<
MOVEI T2,1 ;SINCE WE COULD TALK TO THE DRIVE
LSH T2,(T3) ; IF WE WERE WAITING FOR THE FRONT-END
ANDCAB T2,RPXGON##(J) ; THERE WAS A MISSED INTERRUPT. CLEAR FLAG
TRNN T2,-1 ; WAITING FOR ANY DRIVE?
SETZM RPXGON##(J) ;NO, ZERO THE FLAG
>
POP P,T2 ;RESTORE DATAO DESIRED CYL
JRST RPXGO ;AND CONTINUE
RPXSTP::XCT RPXCI2##(J) ;(BEFORE) CONI
PUSH P,T2
IFN FTKL10,<
MOVEI T4,CO.MBE ;IF AFTER POWER FAIL
XCT RPXCO4##(J) ; THE RH20 LOST ITS IVI
PUSHJ P,RPXIVI ;SO RESET IT NOW
>
MOVEI T4,STPBIT
XCT RPXCO4##(J) ;ZAP
XCT RPXCI2##(J) ;DID IT CLEAR?
TRNN T2,BSYBIT
AOS -1(P) ;YES, SKIP RETURN
POP P,T2 ;RESTORE CONI
IFE FTKL10,<
MOVEI T4,RPALCL
>
IFN FTKL10,<
PUSHJ P,SETP1
MOVE T4,[RPALCL
CO.CLR+CO.MBE](P1)
>
XCT RPXCO4##(J)
IFN FTKL10,<
SKIPL T4,UNILAS##(U) ;IF DRIVE WAS ON OTHER PORT
SETZM RPXGON##(J) ;CLEAR DATA XFER ON OTHER PORT FLAG
>
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 FROM KONEBK
ATNENB: LDB T4,KOYPI##
IFN FTKL10,<
TLNE T1,200000 ;IF DEFERRED IO NOW GOING
TROA T4,CO.MBE ; DON'T ENABLE ATTENTION
>
TRO T4,ATTNEN!CO.MBE ;RE-ENABLE FOR INTERRUPTS
XCT RPXCO4##(J)
POPJ P,
IFN FTDOPT,<
RPXLTM::LDB T3,UNYPUN## ;UNIT NUMBER
MOVEI T4,3 ;MAKE SURE WE DONT TRY TOO MUCH
MOVSI T2,DOLA(T3) ;READ LOOK-AHEAD REGISTER
IFN FTKL10,<
PUSHJ P,SETP1
SKIPE P1
TLO T2,DO.DRE
>
PUSH P,T1 ;SAVE TARGET BLOCK
RPXLT1: XCT RPXDO2##(J)
STALL ;WAIT A WHILE
XCT RPXDI1##(J)
IFE FTKL10,<
TLNE T1,DIERRS ;ERROR?
>
IFN FTKL10,<
SKIPE P1
TLC T1,DI.TRA
TDNE T1,[DIERRS,,
DI.TRA!DI.CPE,,](P1)
>
JRST RPXLT3 ;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,^D8380 ;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
IDIVI T1,^D20 ;COMPUTE DESIRED SECTOR
SUBI T2,2(T3) ;ALLOW A 2-SECTOR FUDGE FACTOR
SKIPL T2
SKIPA T1,T2 ;T1=CURRENT-DESIRED
MOVEI T1,^D20(T2) ;NEGATIVE - ADD 1 REVOLUTION
IMULI T1,^D838 ;838 MICRO-SECS PER SECTOR
PJRST CPOPJ1## ;GOOD RETURN
RPXLT3:
IFN FTKL10,<
SKIPE P1
PUSHJ P,CLRRAE
>
JRST TPOPJ##
> ;END FTDOPT
IFN FTDSUP,<
RPXRDF::SKIPA T1,[FNCRHD] ;READ HEADERS AND DATA
RPXWTF::MOVEI T1,FNCWTF ;WRITE HEADERS AND DATA (FORMAT)
IFN FTKL10,<
MOVE T2,KONCNT##(J) ;IF WRITING-READING HEADERS AND DATA
IDIVI T2,202 ; SECTORS ARE 202 WORDS LONG
SKIPE T3 ; FILIO COMPUTED CHNNUM BASED ON 200 WDS/SECTOR
ADDI T2,1 ; AND THE RH20 HAS TO BE TOLD THE REAL NUMBER
HRRM T2,CHNNUM##(P1) ; SO RECOMPUTE CHNNUM BASED ON 202 WORDS
>
JRST RPXDGO
RPXRDC::SKIPA T1,[FNCRED] ;READ 22-SECTOR MODE
RPXWTC::MOVEI T1,FNCWRT ;WRITE 22-SECTOR MODE
TLO T1,F22 ;INDICATE 22-SECTOR MODE
JRST RPXDGO
>
IFE FTDSUP,<
RPXWTF==CPOPJ
RPXRDF==CPOPJ
RPXRDC==CPOPJ
RPXWTC==CPOPJ
>
RPXRED::SKIPA T1,[FNCRED+DXES] ;READ, DONT STOP ON ERROR
RPXWRT::MOVEI T1,FNCWRT+DXES ;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,CONECT ;CONECT TO THE DRIVE
JRST RPDWND ;DOWN
TRNE T1,DXES ;STOP ON ERROR?
AOS RPXFLG##(J) ;NO, SET RPXFLG POSITIVE
IFN FTDSUP,<
TLNE T1,F22 ;IF 22-SECTOR MODE,
IDIVI T3,^D22 ; ADDRESSING IS DIFFERENT
TLNN T1,F22
>
IDIVI T3,^D20 ;COMPUTE SECTOR, BLOCK
DPB T3,[POINT 5,T4,27] ;SET T4 FOR DESIRED ADDRESS REGISTER
HRLI T2,DODC ;SET DESIRED CYLINDER
PUSHJ P,DODTO
MOVSI T2,DOOF
IFN FTDSUP,<
TLNE T1,F22 ;IF 22-SECTOR I/O
TROA T2,ECI+FMT22 ; LIGHT FMT22 IN OFFSET REGISTER
>
TRNE T1,DXES ;IF NOT STOPPING ON ERROR
TRCA T2,ECI ;CLEAR OFFSET, SET ECI
TRNN T1,10 ;IF WRITING
PUSHJ P,DODTO ;CLEAR OFFSET REGISTER
IFN FTKL10,<
JUMPE P1,RPXDG1
MOVE T2,-1(P) ;LOC OF CHANNEL DATA BLOCK
MOVN T2,CHNNUM##(T2)
DPB T2,[POINT 10,T1,29]
TLO T1,DO.CT2!D2.RCP!D2.SCS!DO.DRE
JRST RPXDG2
RPXDG1:>
MOVE T2,KONIOC##(J) ;LOC OF THE ICWA
LSH T2,6 ;POSITION IT
TRO T1,(T2) ;INTO COMMAND
TLO T1,DOCRC ;T1=DATAO RH CNTRL REG
RPXDG2: MOVE T2,T4 ;DESIRED ADDRESS
HRLI T2,DODA ;SET TO DATAO THE RIGHT REGISTER
RPXGO:
IFE FTKL10,<
SETZ T4, ;TURN OF PI FOR THE RH10
>
IFN FTKL10,<
MOVEI T4,CO.MBE ;MAKE SURE THE MASSBUS IS ENABLED
;(BIT IGNORED FOR RH10)
SKIPE P1 ;IF AN RH20
TLO T1,DO.DRE ; DISABLE REGISTER ACCESS ERROR INTERRUPT
>
XCT RPXCO4##(J)
PUSHJ P,DODTO ;DO THE DATAO IN T2
LDB T4,UNYPUN## ;UNIT NUMBER
TLO T1,LR(T4) ;SET TO DATAO CNTRL REG (RH OR DRIVE)
PUSHJ P,SETCO ;SET PIA, ATTN ENABLE
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
IFN FTDSUP,<
TLZ T1,F22 ;MAKE SURE SOFTWARE BIT ISNT DATAO'D
>
XCT RPXDO1##(J) ;START THINGS HAPPENING
IFN FTKL10,<
SKIPE P1 ;IF RH20
PUSHJ P,RPXIVI ;SET UP INTERRUPR VECTOR ADDRESS
>
XCT RPXCO4##(J) ;TURN ON THE PI
PJRST CPOPJ1## ;AND SKIP RETURN
IFN FTKL10,<
;ROUTINE TO SET UP THE INTERRUPT VECTOR ADDRESS FOR AN RH20
RPXIVI: LDB T2,KOYPI##
LSH T2,1 ;CAUSE INTERRUPT AT 40+2N
ADDI T2,40
HRLI T2,(DO.IVI) ;SET UP DATAO INTERRUPT VECTOR REGISTER
PJRST DODTOC ;DO THE DATAO AND RETURN
>
;HERE IF A DRIVE IS DOWN WHEN WE'RE TRYING TO START IO
RPDWND:
IFN FTKL10,<
JUMPN T1,RPDWN1 ;IF DRIVE IS ON ANOTHER PORT
MOVSI T1,400000 ;INDICATE DATA-OP WE'RE WAITING FOR
MOVEM T1,RPXGON##(J)
JRST RPDWN2 ;SET RPXGON RH AND RETURN TO FILIO
RPDWN1:>
SETOM RPXFLG##(J) ;NOT DOING IO NOW
;HERE IF A DRIVE IS DOWN WHEN WE'RE TRYING TO SEEK/RECAL
RPXDWN:
IFN FTKL10,<
JUMPN T1,RPDWN3 ;CONTINUE IF NOT ON ANOTHER PORT
SKIPE RPXGON##(J) ;IF ALREADY WAITING FOR A DRIVE,
PJRST CPOPJ1## ; IGNORE THIS (IMPLIED SEEK LATER WILL WIN)
RPDWN2: LDB T1,UNYPUN## ;DRIVE IS ON ANOTHER PORT.
MOVEI T2,1 ;SET A BIT IN RPXGON INIDCATING WHICH
LSH T2,(T1) ; DRIVE WE'RE WAITING TO INTERRUPT
IORM T2,RPXGON##(J)
PUSHJ P,RPXIVI
PUSHJ P,SETCO
XCT RPXCO4##(J)
PJRST CPOPJ1## ;AND LIE TO FILIO SAYING WE STARTED THE OPERATION
RPDWN3:>
MOVE T1,T3 ;ERROR FLAGS INTO T1
IFE FTKL10,<
PUSHJ P,SETCO ;SET PIA, ATTEN ENABLE
>
IFN FTKL10,<
PUSHJ P,CLRRAE ;SET PIA, ATTNEN, CLEAR POSSIBLE RAE
>
XCT RPXCO4##(J) ;ENSURE THAT RH10 HAS A PI (POWER FAIL RECOVERY)
XCT RPXCI2##(J) ;GET CONI STATUS
MOVE T3,KONEBK##+1(J) ;SET RH (T3) = STATUS
HRL T3,KONEBK##+2(J) ; AND LH = ERROR REGISTER
POPJ P, ;AND NON-SKIP RETURN TO FILSER
;ENTER T1=FUNCTION
;EXIT CPOPJ IF DRIVE/CONTROLLER DOWN
;EXIT CPOPJ1 IF OK, T1=FUNCTION, T2=CYL, T3=REMAINDER OF CYL COMP.
CONECT:
IFN FTKL10,<
POP P,T4 ;SAVE RETURN ADDR (SETP1 LEAVES SAVE1 ON STACK)
PUSHJ P,SETP1 ;SET P1=0 OR 1 FOR RH10 OR 20
PUSH P,T4 ;RESTORE RETURN ADDRESS
>
CONECX: MOVEI T4,CO.MBE ;IF ON UUO LEVEL
XCT RPXCO4##(J) ; GUARD AGAINST INTERRUPTS
CONEC0: XCT RPXCI2##(J) ;CONI RP,T2
TRNE T1,40 ;TRYING TO DO IO?
IFE FTKL10,<
TRNN T2,BSYBIT ;YES, KONTROLLER BUSY?
>
IFN FTKL10,<
TRNN T2,BSYBIT+DONBIT ;KONTROL BUSY OR DONE
>
JRST CONEC1 ;NO, ALL IS OK
MOVEI T4,STPBIT+CO.MBE ;YES, CLEAR BUSY, SET DONE
IFN FTKL10,<
TRNE T2,BSYBIT
>
XCT RPXCO4##(J)
AOS UNIHNG##(U) ;BUMP A COUNTER
XCT RPXCI2##(J) ;CONI
IFE FTKL10,<
MOVEI T4,RPALCL
>
IFN FTKL10,<
MOVE T4,[RPALCL
CO.CLR+CO.MBE](P1)
XCT RPXCO4##(J)
>
XCT RPXCO4##(J)
TRNE T2,BSYBIT ;DID BUSY CLEAR?
JRST CONER2 ;NO, CALL THE DRIVE OFF-LINE
IFN FTKL10,<
XCT RPXCI2##(J)
TRNN T2,DONBIT ;DID WE WIN ?
JRST CONEC1 ;YES
MOVEI T4,CO.INI ;NO, I HATE TO DO IT
XCT RPXCO4##(J) ; BUT MASSBUSS INIT IS THE ONLY WAY
MOVEI T4,CO.MBE+STPBIT
XCT RPXCO4##(J) ;NOW GET THE RH20 USABLE AGAIN
MOVEI T4,CO.MBE+CO.CLR
XCT RPXCO4##(J)
>
CONEC1:
IFN FTKL10,<
MOVSI T2,DOSN ;WRITE A READ-ONLY REGISTER TO SIEZE THE DRIVE
PUSHJ P,DODTO ; SO THE FRONT-END CANT AB IT OUT FROM UNDER US
>
MOVSI T2,DOSR ;SET TO READ DRIVE'S STATUS REGISTER
PUSHJ P,DODTI
TRZ T2,LST+PGM ;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
IFN FTDSUP,<
TLNE T1,F22 ;IF 22-SECTOR MODE,
IDIVI T2,^D418 ; ADDRESSING IS DIFFERENT
TLNN T1,F22
>
IDIVI T2,^D380 ;COMPUTE CYLINDER IN T2
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
IFN FTKL10,<
JUMPN T2,CONER0 ;GO IF NOT SEIZED TO ANOTHER PORT
TLNE T1,F22 ;STATUS=0, IT MUST BE SIEZED BY FRONT END
TRO T1,F22 ;VE STATE OF F22 IN RH(T1)
HRL T1,(P) ;SAVE CONTINUE ADDRESS FOR WHEN WE GET IT
MOVSM T1,UNILAS##(U) ; SAVE FUNCTION+FLAG+ADDRESS
MOVSI T2,DOSN ;WRITE A READ-ONLY REGISTER SO WILL GET
PUSHJ P,DODTO ; INTERRUPT ON RELEASE FROM OTHER PORT
MOVSI T2,DOSR ;IF DRIVE RELEASED BEFORE WRITE
PUSHJ P,DODTI ; WE WONT GET ATTN INTERRUPTS
JUMPN T2,CONER3 ;IT DID, TRY OPERATION NOW
SETZ T1, ;T1=0 IS A FLAG
AOS INTFNC## ;BUMP INTERFERENCE-COUNT
POPJ P, ;AND TAKE NO-GOOD RETURN
CONER0:>
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
MOVSI T2,DOSR ;READ THE STATUS REG
PUSHJ P,DODTI
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
LDB T4,UNYPUN##
PUSHJ P,RDREG ;READ DRIVE REGISTERS
PUSHJ P,DVCLR ;NO, CLEAR THE DRIVE
POP P,T1
POP P,U
MOVSI T2,DOSR ;READ STATUS REG
PUSHJ P,DODTI
TRZ T2,LST+PGM
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
IFN FTKL10,<
;HERE IF WE GOT DRIVE BACK AFTER THE FE HAD IT
CONER3: HRRZS T1 ;CLEAR LH
TRZE T1,F22 ;RESTORE STATE OF F22
TLO T1,F22
JRST CONEC1 ;NOW TRY IT AGAIN
>
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 TO DO A DATAI FOR THE DRIVE
;ENTER T2=REGISTER TO READ, RETURN T2=CONTENTS OF THE REGISTER
;PRESERVES T1,T4
;DODI4 - ENTER WITH T4=DRIVE NUMBER.PRESERVES ALL ACS (EXCEPT T2)
;DODIC - NO DRIVE INVOLVED. PRESERVES ALL ACS BUT T2
DODTI4:: ;ENTRY POINT FOR ONCMOD
DODTI: LDB T3,UNYPUN## ;UNIT NUMBER
TLOA T2,(T3) ;SET TO READ IT
DODI4: TLO T2,(T4)
DODIC:
IFN FTKL10,<
SKIPE P1 ;RH20?
TLO T2,DO.DRE ;YES, DONT INTERRUPT ON RAE
>
XCT RPXDO2##(J) ;INDICATE WHICH REGISTER WE WANT
IFE FTKL10,<
STALL ;WAIT 3 MICRO-SECS
>
IFN FTKL10,<
PUSH P,T2 ;SAVE REGISTER WE WANT TO READ
IMULI T2,1 ;WAIT (IN CASE RH10)
>
XCT RPXDI2##(J) ;READ THE REGISTER
IFN FTKL10,<
XCT RPXRAE##(J) ;REGISTER ACCESS ERROR?
JRST DTIERR ;YES
DODIX: POP P,(P) ;NO, REMOVE JUNK FROM LIST
>
ANDI T2,177777 ;CLEAR GARBAGE BITS
POPJ P, ;AND RETURN
IFN FTKL10,<
;HERE ON RAE
DTIERR: TLNE T2,DI.TRA ;TRA UP?
MOVSI P1,1 ;NO, COUNT PAR ERROR IN LH (P1=1 FOR RH20)
ADDM P1,RAECNT##(J) ;COUNT THE ERROR
MOVEI P1,^D10 ;UP TO 10 RETRIES
PUSH P,T4 ;NEED TO PRESERVE T4
MOVEI T4,CO.MBE!CO.RAE
DTIER1: XCT RPXCO4##(J) ;CLEAR THE RAE
MOVE T2,-1(P) ;REGISTER WE WANT TO READ
XCT RPXDO2##(J)
STALL
XCT RPXDI2##(J) ;READ IT
XCT RPXRAE##(J) ;ERROR?
SOJG P1,DTIER1 ;YES, TRY AGAIN
XCT RPXCO4##(J) ;CLEAR IT
POP P,T4 ;RESTORE T4
MOVEI P1,1 ;RESTORE P1
JRST DODIX ;REMOVE GARBAGE AND RETURN
>
;READ CONTROLLER REG
DODTIC:
IFN FTKL10,<
SKIPE P1 ;RH20?
TLO T2,DO.DRE ;YES, DONT INTERRUPT ON RAE
>
XCT RPXDO2##(J) ;WHICH REGISTER
XCT RPXDI2##(J) ;CONTROL INFO COMES BACK WITH NO WAITING
POPJ P,
;ROUTINE TO WRITE A CONTROLLER REGISTER
DODTOC: TDZA T3,T3 ;USE UNIT 0
;ROUTINE TO WRITE A DRIVE REGISTER
;ENTER T2=REGISTER TO WRITE,,DATA TO WRITE
;PRESERVES T1,T4
;DODO4 - ENTER WITH T4=DRIVE. PRESERVES ALL ACS
DODTO: LDB T3,UNYPUN## ;UNIT
TLOA T2,LR(T3) ;SET TO WRITE THE REGISTER
DODO4: TLO T2,LR(T4)
IFN FTKL10,<
SKIPE P1 ;RH20?
TLO T2,DO.DRE ;YES, DONT INTERRUPT ON RAE
>
XCT RPXDO2##(J) ;ZAP
IFN FTKL10,<
XCT RPXRAE##(J) ;REGISTER ACCESS ERROR?
AOSA RAECNT##(J) ;YES, COUNT A NO-TRA ERROR
POPJ P, ;NO, DONE
MOVEI P1,^D10 ;UP TO 10 RETRIES
PUSH P,T4 ;PRESERVE T4
MOVEI T4,CO.MBE!CO.RAE
DOERR1: XCT RPXCO4##(J) ;CLEAR THE ERROR
XCT RPXDO2##(J) ;RETRY
XCT RPXRAE##(J) ;ERROR?
SOJG P1,DOERR1 ;YES, RETRY
XCT RPXCO4##(J) ;CLEAR THE RAE
POP P,T4 ;RESTORE T4
MOVEI P1,1 ;RESTORE P1
>
POPJ P, ;AND RETURN
;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
PJRST DODO4 ;DO A PACK ACKNOWLEDGE AND RETURN
IFN FTKL10,<
;ROUTINE TO SET P1 =0 FOR RH10, =1 FOR RH20
;PRESERVES ALL BUT P1
RPXSTW:: ;CALLED BY ONCMOD (RPXUPA)
SETP1: EXCH P1,(P) ;SAVE P1, GET CALLERS PC
PUSH P,P1 ;SAVE PC
LDB P1,[POINT 3,RPXDI2##(J),5]
CAIE P1,5 ;RH20 DEV CODES ALL START WITH 5
TDZA P1,P1 ;RH10
MOVEI P1,1 ;RH20
JUMPE P1,SETP12 ;RETURN IF AN RH10
PUSH P,T4 ;RH20, SAVE T4
PUSHJ P,SETCO ;SET UP FOR CONO (MAKE SURE CO.MBE IS ON)
SKIPE DINITF## ;IF IN ONCE-ONLY,
TRZ T4,7 ; DONT LIGHT A PIA
XCT RPXCO4##(J) ;ENABLE MASSBUS
POP P,T4 ;RESTORE T4
SETP12: POP P,(P) ;MAKE STACK RIGHT
PUSHJ P,@1(P) ;GO TO CALLER
CAIA
AOS -1(P)
POP P,P1 ;RESTORE P1
POPJ P, ;AND EXIT
;ROUTINE TO CLEAR RAE
CLRRAE: PUSHJ P,SETCO ;"REGULAR" BITS
TRO T4,CO.RAE ;CLEAR RAE
XCT RPXCO4##(J) ;ZAP THE ERROR, PRESERVE THE REST
POPJ P, ;AND RETURN
>
;ROUTINE TO SET UP BITS FOR CONO
;PRESERVES ALL BUT T4
SETCO: LDB T4,KOYPI## ;GET PIA
IFN FTKL10,<
TRO T4,CO.MBE ;BIT NEEDED FOR RH20, IGNORED FOR RH10
HLL T4,RPXGON##(J) ;IF WE ARE WAITING FOR THE FRONT END
TLNE T4,400000 ; AND WE ANT TO DO A DATA XFER
TLNE T4,200000 ;ENABLE FOR ATTENS IF XFER NOT STARTED
>
SKIPGE RPXFLG##(J)
TRO T4,ATTNEN ;ENABLE FOR ATN IF NO XFER
POPJ P, ;AND RETURN
IFN FTDUAL,<
;ROUTINE TO ISSUE A RELEASE FOR DUAL-PORT OPERATION
;PRESERVES ALL ACS
RLESE: PUSHJ P,SAVT##
LDB T4,UNYPUN##
MOVEI T2,FNCREL ;RELEASE
PUSHJ P,DODO4
PJRST CHKATN
>
;HERE ON INTERRUPT FOR AN RP04
RPXINT::
IFN FTKL10,<
PUSHJ P,SETP1 ;SET P1=0 OR 1 FOR RH10 OR 20
>
XCT RPXDI2##(J) ;SAVE REGISTER THE RH10 WAS CONNECTED TO
PUSH P,T2 ; (MIGHT INTERRUPT BETWEEN DATAO AND ITS DATAI)
PUSH P,J ;SAVE J
PUSHJ P,RPXIN1 ;DO THE REAL INTERRUPT STUFF
POP P,J ;RESTORE J
HLLZ T2,(P) ;GET DRIVE NUMBER, REGISTER NUMBER
TLZ T2,007770
TLNN T2,770000 ;CANT DATAO TO REG 4
TLO T2,010000 ; SINCE THAT WOULD SIEZE THE DRIVE
XCT RPXDO2##(J) ;SET THR RH10 BACK TO THAT REGISTER
PJRST TPOPJ## ;AND RETURN (DISMISS INTERRUPT)
;THE "REAL" INTERRUPT ROUTINE....
RPXIN1: MOVSI T2,DOAS ;SET TO READ ATTN SUMMARY REGISTER
PUSHJ P,DODIC ;(ATTN NOT ON IN CONI IF NOT ENABLED)
SETZB S,T4
ANDI T2,377 ;ANY ATTENTION ON?
IFN FTKL10,<
SKIPL RPXGON##(J) ;AND NO (POSSIBLE) POSTPONED ATTN INTERRUPTS
>
JUMPE T2,NOATTN ;NO
HRLI T2,DOAS+LR ;YES, SET TO CLEAR WHAT WE READ
PUSH P,T2 ;SAVE IT (CLEAR IF NO ERRORS LATER ON)
IFN FTKL10,<
SKIPN T1,RPXGON##(J) ;ARE WE LYING TO FILSER ABOUT SOME DRIVE?
JRST DUAINX ;NO, CONTINUE
TLZE T1,200000 ;YES, DID WE START THE "REAL" OPERATION?
JRST DUAIN4 ;YES, FINISH UP
TRNE T2,(T1) ;NO, IS THERE AN ATTEN FROM THAT DRIVE?
JRST DUAIN1 ;YES
JUMPG T1,DUAINX ;NO, REGULAR SERVICE IF IT WAS A SEEK
HRLZ T1,T2 ;DATA XFER - REMEMBER THE DRIVES
IORM T1,RPXGON##(J) ; SO WE CAN TELL FILSER AFTER THE XFER
JRST RPXIN5 ;ISSUE RELEASES AND EXIT THE INTERRUPT
;HERE IF WE TRIED TO START AN OPERATION ON A DRIVE WHICH WAS BUSY ON THE
;OTHER PORT (FRONT END). WE WROTE A READ-ONLY REGISTER IN ORDER TO GET THIS
;ATTENTION INTERRUPT WHEN THE DRIVE WAS RELEASED FROM THE OTHER PORT
DUAIN1: HRRZS T2,T1 ;DRIVE WE WERE WAITING FOR
ANDCAM T2,(P) ;CLEAR IT FROM STUFF TO DO AT END
HRLI T2,DOAS ;CLEAR ATA IN DRIVE
PUSHJ P,DODO4
JFFO T1,.+2 ;COMPUTE DRIVE NUMBER
STOPCD DUAIN2,DEBUG,NFD, ;++NO FRONT-END DRIVE
MOVNI T2,-^D35(T2)
ADDI T2,(J) ;POINT AT UDB
HRRZ U,(T2) ;SET U TO THE DRIVE
HLRZ T1,UNILAS##(U) ;FUNCTION
TRZE T1,F22
TLO T1,F22 ;SET 22-SECTOR MODE IF NEEDED
PUSHJ P,CONEC0 ;SET UP TO TALK TO DRIVE
JRST DUAIN2 ;NOT RIGHT, LET IT TIME OUT
PUSH P,UNICHN##(U) ;DATA OPS NEED CHAN DB LOC ON PDL
MOVSI T4,200000 ;INDICATE THAT THE DATA XFER HAS STARTED
SKIPG RPXGON##(J) ; IF WE ARE ABOUT TO START IT
IORM T4,RPXGON##(J) ; SO THAT SETCO WONT ENABLE FOR ATTENTIONS
HRRZ T4,UNILAS##(U) ;CONTINUE ADDRESS
PUSHJ P,1(T4) ;START OPERATION NOW
JFCL ;LOSE (SYSTEM ERROR?)
POP P,(P) ;REMOVE CHNXCB FROM LIST
DUAIN2: SKIPG RPXGON##(J) ;WAITING FOR DATA XFER?
JRST RPXIN5 ;YES, ISSUE RELEASES AND WAIT FOR DONE
SETZB T4,RPXGON##(J) ;NO, CLEAR UP THE EVIDENCE
HRRZ T2,(P) ;RESTORE OTHER DRIVE ATTN BITS
JRST DUAINX ;AND PROCESS NORMALLY
;HERE AFTER COMPLETION OF DATA XFER WHICH WAS DELAYED WHEN FRONT END HAD DRIVE
DUAIN4: HLRZS T1 ;SEEKS WHICH COMPLETED WHILE WE WAITED
TRO T2,400000(T1) ; PROCESS AS IF THEY JUST FINISHED
SETZM RPXGON##(J) ;NOT WAITING NOW
DUAINX:>
HRRZ T1,T2 ;BITS FOR ATTN-DRIVES
RPXIN2: LSHC T1,-1 ;TEST THE NEXT DRIVE
JUMPGE T2,RPXIN4 ;NOT THIS ONE
MOVSI T2,DOSR(T4) ;THIS DRIVE INTERRUPTED
PUSHJ P,DODIC ;READ ITS STATUS REGISTER
MOVEI U,KONTAB##(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
MOVEI T3,1 ;IF A DATA XFER IS IN PROGRESS
LSH T3,(T4) ; WE HAVE TO TELL FILSER ABOUT THAT FIRST
JUMPGE F,[ANDCAM T3,(P) ; SO DONT CLEAR ATTN FOR THIS
JRST RPXIN4] ; DRIVE. IT WILL INTERRUPT LATER
;HERE IF INTERRUPT & NO XFER IN PROGRESS AND THE DRIVE HAD AN ERROR
MOVEM T2,(P) ;SAVE STATUS OF DRIVE
MOVE T2,T3 ;CLEAR JUST THIS 1 ATTENTION BIT
HRLI T2,DOAS+LR(T4) ; (WILL INTERRUPT AGAIN FOR THE OTHERS)
XCT RPXDO2##(J) ;CLEAR IT
MOVSI T2,DOER3
PUSHJ P,DODI4 ;IF SEEK INCOMPLETE IS ON
TRNN T2,SKI
JRST RPXI2A
MOVSI T2,DOER
PUSHJ P,DODI4 ; AND UNSAFE IS OFF
TRNE T2,UNS
JRST RPXI2A
MOVE T2,(P)
TRNN T2,DRY ;IF DRIVE READY IS OFF THE UNIT IS RECALIBRATING
JRST TPOPJ## ; SO WAIT FOR NEXT INTERRUPT
PUSHJ P,DVCLR ;RECAL DONE, CLEAR THE DRIVE
;(UNIT IS NOT ON RIGHT CYLINDER, BUT IMPLIED SEEK WILL WIN)
SKIPA T1,[1]
RPXI2A: MOVSI T1,1
ADDM T1,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
IFN FTDUAL,<
PUSHJ P,RLESE ;DO A DUAL-PORT RELEASE
>
MOVEI T1,OPPOS+IODERR;INDICATE AN ERROR FOR FILSER
HRLI T1,(T4) ;DRIVE WHICH ERRORED
IOR T1,BITTBL##(T4) ;SET THE ATTN BIT FOR THE DRIVE
POP P,T3 ;RETURN DATAI STATUS IN T3
XCT RPXCI2##(J) ; AND CONI STATUS IN T2
PJRST FILINT## ;CALL FILIO
;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: 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
XCT RPXDO2##(J) ; OF ALL THE DRIVES WE JUST LOOKED AT
IFN FTDUAL,<
SETZ T3, ;T3 WILL HAVE ATTENTION BITS
MOVEI T4,7 ;START AT HIGH-ORDER DRIVE
LSHC T2,-^D8
RPXIN6: JUMPGE T3,RPXIN7 ;THIS DRIVE INTERRUPT?
MOVSI T2,DOSR ;YES, READ STATUS REG
PUSHJ P,DODI4
TRNE T2,PGM ;IF A DUAL-PORT DRIVE
TRNE T2,ERR ;WHICH HAS NO ERROR BITS UP IN IT
JRST RPXIN7
MOVEI T2,FNCREL ;DO A RELEASE SO OTHER PORT CAN GET IT
PUSHJ P,DODO4
RPXIN7: LSH T3,1 ;STEP TO NEXT DRIVE
TLNE T3,-1 ;ANOTHER ATTN BIT?
SOJGE T4,RPXIN6 ;YES, TEST THIS DRIVE
>
IFN FTKL10,<
SKIPL T1,RPXGON##(J) ;LIE TO FILSER WHILE WAITING FOR FE TO RELEASE DRIVE?
>
SKIPGE RPXFLG##(J) ;DATA XFER IN PROGRESS?
JUMPE S,ATNENB ;NO, DISMISS INTERRUPT IF JUST A POWER-DOWN ATTN
NOATTN:
SKIPL RPXFLG##(J) ;DATA XFER IN PROGRESS?
JRST DATINT ;YES
XCT RPXCI2##(J) ;NO, GET CONI STATUS
HRRI S,OPPOS ;INDICATE POSITION INTERRUPT
JRST CALLIO ;AND TELL FILSER
DATINT:
IFE FTKL10,<
MOVSI T2,DOCRC ;SET TO READ RH10 CNTRL REG
>
IFN FTKL10,<
MOVE T2,[DOCRC,, ;READ RH10 CNTRL REG
DO.CT1](P1) ; OR PRIMARY TRANSFER CNTRL REG
>
PUSHJ P,DODTIC
LDB T4,[POINT 3,T2,17] ;DRIVE NUMBER WE'RE TALKING ABOUT
IFN FTKL10,<
SKIPL RPXFNC##(J) ;IF CALLED FROM RPXSTP
JRST [MOVE U,KONCUA##(J) ; IF DRIVE WAS ON OTHER PORT
SKIPL UNILAS##(U) ; WE NEVER TALKED TO IT
LDB T4,UNYPUN## ; SO SET UNIT TO WHAT IT SHOULD BE
JRST .+1]
>
MOVE U,RPXFNC##(J)
TRNN U,10 ;IS IT A WRITE?
TRO S,OPWRT ;(OPRED=0)
MOVSI T2,DOOF+LR(T4) ;CLEAR ECI AND/OR FMT22
TRNN U,DXES
TLNE U,F22 ; IF THEY WERE ON FOR THE DRIVE
XCT RPXDO2##(J)
DATIN1: TLO S,(T4) ;DRIVE NUMBER IN LH
MOVSI T2,DOSR ;READ THE DRIVE STATUS REGISTER
PUSHJ P,DODI4
MOVE T1,T2 ;SAVE STATUS
MOVSI T2,DOER ;READ THE ERROR REGISTER
PUSHJ P,DODI4
HRL T3,T2 ;T3=ERROR,,STATUS
HRR T3,T1
XCT RPXCI2##(J) ;T2=CONI STATUS
IFE FTKL10,<
TRNN T2,ALLERR ;ANY ERROR?
>
IFN FTKL10,<
JUMPE P1,DATIN2 ;EASY IF RH10
MOVE T1,KONIOC##(J) ;GET ICWA
HLL T2,1(T1) ;GET BITS FROM CHAN LOGOUT AREA
TLC T2,(CS1NSE) ;MAKE THE BIT=1 IF ERROR
;AND FALL INTO DATIN2
DATIN2: TDNN T2,[ALLERR ;ANY ERROR?
CS1ERR!CI.ERR](P1)
>
TRNE T3,ERR
JRST ERROR ;YES
SKIPL RPXFNC##(J) ;CALL FROM RPXSTP (FROM HNGDSK)?
JRST ERROR ;YES, CAUSE ERROR SO WILL RETRY
MOVE U,KONCUA##(J) ;UNIT WE'RE TALKING TO
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
IFN FTDUAL,<
TRNN T3,PGM ;DUAL PORT DRIVE IN A/B?
JRST CALLIO ;NO
PUSH P,T2 ;YES, SAVE CONI
MOVEI T2,FNCREL ;ISSUE A RELEASE
PUSHJ P,DODO4
POP P,T2 ;RESTORE CONI
>
CALLIO: LDB T4,KOYPI## ;GET PI CHAN
IFE FTKL10,<
TRO T4,ATTNEN+RPALCL ;CLEAR ERRORS, ENABLE FOR ATTN INTERRUPTS
>
IFN FTKL10,<
TDO T4,[ATTNEN+RPALCL
ATTNEN+CO.CLR+CO.MBE](P1)
>
XCT RPXCO4##(J)
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
IFE FTKL10,<
TRNN T2,CHNERR ;CHAN-DETECTED ERROR?
>
IFN FTKL10,<
TDNN T2,[CHNERR
CS1MPE!CS1NXM](P1)
>
JRST ERROR1 ;NO
IFN FTKL10,<
JUMPE P1,ERRH10 ;ALL DIFFERENT FOR RH10S
TLNN T2,(CS1MPE) ;CHECK LOGOUT AREA FOR NXM
TROA S,IOCHNX
TRO S,IOCHMP
TLNE T2,(CS1OVR) ;CHECKK LOGOUT AREA FOR OVERRUN
TRO S,IOVRUN
JRST ERRDON ;AND FINISH UP
ERRH10:>
TLNN T2,CHNPAR ;YES, CHAN PARITY ERROR?
TROA S,IOCHNX ;NO, NXM
TRO S,IOCHMP ;YES
TLNE T3,OVERUN
TRO S,IOVRUN
JRST ERRDON ;FINISH UP
ERROR1: TLNE T3,HCE+HCRC ;HEADER ERROR?
TRO S,IOHDER+IODTER ;YES
SKIPG RPXFLG##(J) ;IF STOPPING ON ERROR,
TRNE S,IODERR ;AND DATA ERROR IS UP
JRST ERRDON
TLNN T3,ECH ;HARD DATA CHECK?
TRO S,IOECCX ;NO, INDICATE RECOVERABLE ERROR
ERRDON: PUSH P,T2 ;SAVE CONI STATUS
PUSH P,T3 ;SAVE STATUS, ERROR REGISTERS
IFN FTKL10,<
JUMPE P1,ERRDN0
TRNN T2,CI.RAE ;REGISTER ACCESS ERROR?
JRST ERRDN0 ;NO
PUSHJ P,CLRRAE ;YES, CLEAR IT
JRST ERRDN1 ;AND CONTINUE
ERRDN0:>
TLNN T2,SDRAE ;REGISTER ACCESS ERROR?
JRST ERRDN1 ;NO
MOVEI T2,1 ;YES, CLEAR THE BIT IN RAE REGISTER
LSH T2,(T4)
HRLI T2,DORA+LR
XCT RPXDO2##(J)
ERRDN1: 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
IDIVI T1,^D36 ;COMPUTE WORD LOC, POSITION IN WORD
MOVE T4,KONEBK##+17(J) ;GET PATTERN
EXCH T2,T4
MOVEI T3,0 ;SET T2, T3= MASK
ROTC T2,(T4)
PJRST CPOPJ1## ;AND SKIP-RETURN
;ROUTINE TO CLEAR POSSIBLE GARBAGE FROM DRIVE REGS
RDIPST: SKIPA T2,[FNCPST] ;ENSURE DA & DC REGS DON'T
;ROUTINE TO CLEAR A DRIVE AND MAKE SURE IT REALLY CLEARED
;PRESERVES T1
DVCLR: MOVEI T2,FNCCLR
PUSH P,T2
MOVSI T2,DOOF ;DRIVE CLEAR ZEROES OFFSET REG
PUSHJ P,DODI4 ; SO READ IT
EXCH T2,0(P) ; AND SAVE
PUSHJ P,DODO4 ;ZAP
PUSHJ P,DODO4 ;SOME DRIVES NEED 2!
POP P,T2 ;RESTORE OFFSET REG
HRLI T2,DOOF ; SO SYSERR WILL REPORT IT
PUSHJ P,DODO4 ; AND TEST ON 1ST ERROR WILL WORK
CHKATN: MOVSI T2,DOAS ;READ ATTN SUMMARY REGISTER
PUSHJ P,DODI4
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
HRLI T2,DOAS+LR
XCT RPXDO2##(J) ;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::TLO M,400000
IFN FTKL10,<
PUSHJ P,SETP1
>
SOJN T1,RPXER1 ;IF FIRST ERROR,
MOVSI T2,DOOF ;READ THE OFFSET REGISTER
PUSHJ P,DODTI ;(IF LAST OP WAS SOFT ERROR
TRNN T2,60 ; THE DRIVE IS LEFT IN OFFSET STATE)
JRST RPXER1 ;DRIVE ISNT OFFSET - CONTINUE
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,CONECX ;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?
HLRS T2 ;YES, GET OTHER OFFSET VALUE
HRLI T2,DOOF ;SET TO DO OFFSET
MOVEI T1,FNCOFS ;FUNCTION = OFFSET
TRNN T2,-1 ;BUT IF OFFSET=0,
MOVEI T1,FNCRTC ; DO A RETURN TO CENTERLINE
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
IFN FTDHIA,<
;HERE TO CHECK CAPACITY & STATUS OF RH10/RP04
RPXCPY::
IFN FTKL10,<
MOVEI T4,CO.MBE
XCT RPXCO4##(J)
PUSHJ P,RPXIVI ;SET UP IVI REG IN CASE OF ERROR
PUSHJ P,SETP1 ;DO MASSBUS ENABLE IF RH20
SETZ T1,
>
RPXCP1: MOVSI T2,DODT ;READ DRIVE-TYPE REGISTER
PUSHJ P,DODTI4
LDB T3,[POINT 9,T2,35]
CAIL T3,20 ;IN RANGE OF RP04-PR06 ?
CAILE T3,22
JRST RPXCP3 ;NO, NO SUCH DRIVE
CAIE T3,22 ;YES, RP06 ?
TDZA T4,T4 ;NO
MOVEI T4,1 ;YES, UNIT TYPE=1
IFN FTDUAL,<
HRLM T2,UNISER##(U) ;SAVE DRIVE TYPE
>
MOVEM T2,UNIEBK##+6(U) ;SAVE FOR SYSERR
MOVSI T2,DOSR ;YES, READ STATUS REGISTER
PUSHJ P,DODTI4
TRCN T2,MOL ;MOL?
TLO T4,KOPUHE ;NO, INIT IS OFF-LINE OR DOWN
IFN FTDUAL,<
TRNE T2,VV!MOL ;IF MOL=1 BUT VV=0
JRST RPXCP2
PUSH P,T4 ;THEN THE DRIVE WONT DO A RELEASE
MOVE T4,T3 ; SO SET VV
PUSHJ P,NOWUP ; SO THAT RELEASE WILL WORK
POP P,T4
RPXCP2:>
MOVSI T2,DOSN ;READ DRIVE SERIAL NUMBER
PUSHJ P,DODTI4
MOVEM T2,UNIEBK##+10(U) ;AND STORE IN UDB
IFN FTDUAL,<
HRL J,T2 ;RETURN SN IN J ALSO
>
IFN FT22BIT,<
XCT RPXCI2##(J) ;CONI FN'N T2
TLNE T2,4000 ;22 BIT CHAN?
TLO T4,KOP22B## ;YES
>
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,[^D20,,^D380] ;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:
IFN FTKL10,<
IFE FTDUAL,<
JUMPE P1,CPOPJ## ;NO SWEAT IF AN RH10
>
IFN FTDUAL,<
JUMPE P1,RLESE
>
TLO T4,KOP22B## ;RH20'S ARE 22 BIT CHANNEL
PUSH P,T4 ;PRESERVE T4
PUSH P,T2 ;SAVE T2
LDB T4,UNYPUN##
MOVEI T2,1
LSH T2,(T4) ;POSITION BIT TO CLEAR ATTN-SUMMARY REG
HRLI T2,DOAS+LR+DO.DRE
XCT RPXDO2##(J) ; WHICH MIGHT BE ON
IFN FTDUAL,<
LDB T4,UNYPUN##
PUSHJ P,DVCLR ;MAKE SURE ERR ISNT UP SO RELEASE WILL WIN
PUSHJ P,RLESE ;DO A DUAL-PORT RELEASE
>
PUSHJ P,CLRRAE ;CLEAR RAE, LIT IF NON-EX DRIVE
POP P,T2
PJRST T4POPJ## ;RESTORE T4 AND RETURN
> ;END IFN FTKL10'
IFE FTKL10,<
IFN FTDUAL,<
PUSHJ P,RLESE ;DO A DUAL-PORT RELEASE
>
POPJ P,
>
BLKPRU: DEC 154280 ;406 CYLINDERS
DEC 307800 ;810 CYLINDERS
BLKPUM: DEC 156180 ;411 CYLINDERS
DEC 309700 ;815 CYLINDERS
BLKPUC: DEC 171798 ;22*19*411
DEC 340670 ;22*19*815
> ;END FTDHIA
;ENTRY TO READ DRIVE REGS
RPXREG::
IFN FTKL10,<
PUSHJ P,SETP1 ;MASSBUS ENABLE IF RH20
>
PUSH P,U ;RDREG WIPES U
LDB T4,UNYPUN## ;DRIVE NUMBER
PUSHJ P,RDREG ;READ REGS
IFE FTDUAL,<
PJRST UPOPJ## ;RESTORE U AND RETURN
>
IFN FTDUAL,<
POP P,U ;RESTORE U
MOVE T2,KONEBK##+1(J) ;GET STATUS REG
TRNE T2,PGM ;IF DUAL PORTED
TRNE T2,ERR ; AND NO ERROR
POPJ P,
PJRST RLESE ;DO A RELEASE (READ REG 0 SIEZES THE DRIVE)
>
;SUBROUTINE TO READ ALL DRIVE REGISTERS
;PRESERVES T3, CLOBBERS U
RDREG: 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
RDREG1: MOVSI T2,-1(T1) ;READ A REGISTER
LSH T2,^D12
PUSHJ P,DODI4
MOVEM T2,(U) ;SAVE IN KONTROLLER DB
SUBI U,1
SOJG T1,RDREG1 ;AND GO READ ANOTHER
IFE FTKL10,<
MOVSI T2,DOCRC ;READ RH10 CONTROL REG
>
IFN FTKL10,<
MOVE T2,[DOCRC,, ;OR RH20 PTCR
DO.CT1](P1)
>
PUSHJ P,DODTIC
MOVEM T2,KONECR##(J) ;SAVE IN KDB
IFE FTKL10,<
MOVSI T2,DODB ;READ DATA BUFFER
>
IFN FTKL10,<
MOVE T2,[DODB,, ;OR RH20 PBAR
DO.PBA](P1)
>
PUSHJ P,DODTIC
MOVEM T2,KONEDB##(J) ; AND SAVE
POPJ P, ;RETURN
$LIT
RPXEND: END