Trailing-Edge
-
PDP-10 Archives
-
BB-JR93K-BB_1990
-
10,7/mon/rhxkon.mac
There are 8 other files named rhxkon.mac in the archive. Click here to see a list.
TITLE RHXKON - RH11 DRIVER FOR RP06'S AND RM03'S V044
SUBTTL J EVERETT/JE/DBD 25 APR 89
SEARCH F,S,DEVPRM
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1978,1988>
XP VRHKON,044
;TRACKS VERSION 147 OF RPXKON
RPXKON::ENTRY RPXKON ;*** SO KS LINKS
RHXKON::ENTRY RHXKON
SUBTTL AUTOCONFIGURATION TABLES
;NOTE: KONTROLLER SERVICE ROUTINE IS CALLED RHXKON EVEN THOUGH
; THE UNITS ARE REFERRED TO AS RP'S TO CONFORM WITH RH10,
; RH20 IMPLEMENTATION.
;PARAMETERS TO CONTROL XXKON MACRO:
RPFIX==KOPPWX ;POSITIONING DEVICE, CAN SEEK WHILE XFERRING
RPOFS==0 ;CAN OFFSET FOR ERROR RECOVERY
RPRDC==0 ;10/11 COMPATABILITY MODE
RPUNL==0 ;DRIVE CAN BE UNLOADED
RPCPY==0 ;CAN TELL UNIT TYPE EVEN IF KONTROL IS BUSY
RPMX==0 ;CANNOT DO MULTIPLE TRANSFERS
RPDRB==0 ;DOESN'T USE DISK I/O REQUEST BLOCKS
RPBMX==0 ;NOT A BLOCK MULTIPLEX KONTROLLER
RPECA==0 ;TRY OFFSET/RECAL BEFORE TRYING ECC
RPERNO==^D16 ;16 DRIVE REGISTERS TO SAVE ON ERROR
RPXELG==MDEELG## ;ERROR LOG ROUTINE IS IN FILIO
RPXDMX==10 ;MAXIMUM DRIVES PER KONTROLLER
RPXHDN==RPXDMX-1 ;HIGHEST DRIVE NUMBER ON KONTROLLER
;DRIVER CHARACTERISTICS
; RPX = RPXCNF
; DSK = DISK
; 0 = MAXIMUM DEVICES IN SYSTEM (NO LIMIT)
; TYPRP = KONTROLLER TYPE
; RPXDMX = MAXIMUM DRIVES PER KONTROLLER
; RPXHDN = HIGHEST DRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (RPX,DSK,0,TYPRP,RPXDMX,RPXHDN,MDSEC0,MDSEC0,DR.MCD)
.ORG KONUDB ;START OF RP0X/RM0X SPECIFIC DATA
RPXUTB:!BLOCK RPXDMX ;TABLE OF POINTERS TO UDBS
RPXEBK:!BLOCK RPERNO ;STORAGE FOR ERROR REGISTERS
RPXFNC:!BLOCK 1 ;LAST DATA XFER FUNCTION
; BIT 0 = OFF IF DSK HUNG, ON IF EVERYTHING OK
; BITS 15-17 = UNIT NUMBER COMMAND ISSUED TO
; BITS 30-35 = FUNCTION CODE
RPXFLG:!BLOCK 1 ;DATA XFER IN-PROGRESS FLAG
; -1 = CONTROLLER IDLE
; 0 = XFER IN-PROGRESS, STOP ON ERROR
; 1 = XFER IN-PROGRESS, DON'T STOP ON ERROR
RPXIUM:! BLOCK RPXDMW ;IGNORE DRIVE MASK
RPXNUM:! BLOCK RPXDMW ;NEW DRIVE MASK
RPXKLN:! ;LENGTH OF KDB
.ORG
;PROTOTYPE KDB
RPXKDB: XXKON (RP)
SETWRD (RPXFLG,<-1>)
KDBEND
RPXCCM==CYLCM##
EQUATE (LOCAL,0,<RPXUDB,RPXULP,RPXULB>)
EQUATE (LOCAL,CPOPJ##,<RPXALV,RPXINI,RPXRLD,RPXEDL>)
RPXICD==DSKICD## ;PROTOTYPE INTERRUPT CODE
RPXICL==DSKICL##
RPXUDB==0 ;NO PROTOTYPE UDB
RPXULN==UNIEBK+RPERNO ;LENGTH OF UDB
RPXDSP::DRVDSP (RPX,DSKCHN##,DSKDDB##,DDBLEN##,DSKDIA##)
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKS10 (7,RH11IV,RH11CA,0,0,<MD.KON>)
MDTERM
RPXCKT: EXP TYPRP, 0 ;COMPATIBLE KONTROLLER TABLE
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
.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
SUBTTL FILSER CALL PROCESSING
RPXUNL::SKIPA T1,[FNCUNL] ;UNLOAD
RPXRCL::MOVEI T1,FNCRCL ;RECAL
PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,KDBDVC(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,KDBDVC(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,KDBDVC(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 RPXEBK
POPJ P,
RPXLTM::PUSHJ P,SAVE1## ;PRESERVE AN AC
MOVE P1,KDBDVC(J) ;SET UP RH11 BASE ADDRESS
MOVE T3,UDBPDN(U) ;PHYSICAL DRIVE 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,KDBDVC(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,KDBCHN(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
MOVE T4,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
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,RPXEBK+1(J) ;SET RH(T3)=DRIVE STATUS
HRL T3,RPXEBK+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: MOVE T4,UDBPDN(U) ;PHYSICAL DRIVE 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: MOVE T4,UDBPDN(U) ;PHYSICAL DRIVE 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,RPXEBK+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,RPXEBK(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,KDBDVC(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,KDBIUN(J) ;SET UP U TO UDB
ADDI U,(T4)
SKIPN U,(U) ;SET UP U TO UDB
JRST RPXIN6 ;NEW UNIT - BUILD A UDB FOR IT
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,KDBICP(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,KDBCHN(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
;HERE FOR INTERUPT ON AN UNKNOWN UNIT
RPXIN6: MOVE T2,BITTBL##(T4) ;TRANSLATE MASSBUS UNIT (DRIVE) TO BIT
IORM T2,RPXNUM(J) ;REMEMBER TO CONFIGURE LATER
HRROS KDBNUM(J) ;FLAG IT FOR THE REST OF THE WORLD TO SEE
JRST RPXIN4 ;GO SEE IF OTHER ATTENTION BITS TO PROCESS
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.NEX!CS.DLT ;CHANNEL-TYPE PROBLEM?
JRST ERROR1 ;NO--GO ON
TRNE T4,CS.DLT ;DATA LATE?
TRO S,IOVRUN ;YES
MOVE T1,KDBCHN(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
MOVE T4,UDBPDN(U) ;PHYSICAL DRIVE 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,RPXEBK+16(J) ;GET POSITION
SOJL T1,CPOPJ## ;ERROR IF 0
;THE FIRE CODE IN THE MASSBUS DISKS CAN GENERATE THE WRONG ECC CORRECTION.
;STATISTICALLY, THIS ONLY HAPPENS FOR AN ERROR ENVELOPE OF GREATER THAN
;FOUR BITS. THIS CODE COUNTS THE WIDTH OF THE MASK AND DECLARES THE ERROR
;NON-ECC CORRECTABLE IF THE CORRECTION PART OF THE MASK IS WIDER THAN THIS.
MOVE T2,RPXEBK+17(J) ;GET PATTERN
JFFO T2,.+1 ;FIND FIRST BIT OF PATTERN
MOVE T4,T3 ;PRESERVE NUMBER OF FIRST BIT IN PATTERN
TDZ T2,BITTBL##(T3) ;WIPE OUT THAT BIT
RPXEC8: JUMPE T2,RPXEC9 ;JUMP WHEN PATTERN IS ZERO
JFFO T2,.+1 ;FIND NEXT BIT OF PATTERN
TDZ T2,BITTBL##(T3) ;WIPE OUT THAT BIT
JRST RPXEC8 ;LOOK FOR ANOTHER
RPXEC9: SUB T3,T4 ;GET WIDTH-1 OF PATTERN
CAILE T3,4-1 ;IS PATTERN LESS THAN/EQUAL TO FOUR BITS WIDE?
POPJ P, ;NO, THEN IT IS NOT ECC CORRECTABLE
;HERE IF THE ERROR IS TRULY ECC CORRECTABLE.
MOVE T4,RPXEBK+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,KDBDVC(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,RPXEBK+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,KDBDVC(J) ;SET UP RH11 BASE ADDRESS
MOVE T2,UDBPDN(U) ;PHYSICAL DRIVE 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
LDB T3,[POINT 9,T2,35] ;GET DRIVE TYPE CODE
CAIN T3,TY.RP5 ;RP05?
MOVEI T3,TY.RP4 ;YES, JUST CALL IT AN RP04
MOVSI T4,-TYPTBL ;-VE LENGTH OF DRIVE TYPE TABLE
MOVE T1,TYPTAB(T4) ;GET AN ENTRY
CAIE T3,(T1) ;DRIVE TYPES MATCH?
AOBJN T4,.-2 ;NO, LOOP FOR A MATCH
JUMPGE T4,RPXCP4 ;NOT A LEGAL UNIT TYPE, NO SUCH DRIVE
HRRZS T4 ;ISOLATE UNIT TYPE INDEX
MOVEM T2,UNIEBK+6(U) ;SAVE FOR SYSERR
RDIO T2,.DOSR(W) ;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
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,BLKPTC(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,
$INIT
;CHECK FOR KONTROLLER UP
RPXUPA: MOVE T1,KDBDVC(J) ;GET BASE ADDRESS OF I/O REGISTERS
PUSHJ P,UBGOOD## ;IS RH11 ALIVE ?
POPJ P, ;NO - RETURN OFF LINE
SETOM RPXFLG(J) ;SET CONTROLLER IDLE
MOVE P1,KDBCHN(J) ;CHANNEL DATA BLOCK
MOVE W,KDBDVC(J) ;GET RH11 BASE ADDRESS
MOVEI T4,CS.CLR ;CONTROLLER CLEAR BIT
WRIO T4,.DOCS2(W) ;WRITE CONTROLLER STATUS REGISTER
MOVEI T4,CS.OR ;READY BIT
TION T4,(W) ;SHOULD BE ON
POPJ P, ;NOT READY, ASSUME DOWN
PJSP T1,CPOPJ1## ;GOOD RETURN
;CHECK HARDWARE WRITE PROTECT
RPXHWP: MOVE W,KDBDVC(J) ;SET RH11 BASE ADDRESS
MOVE T2,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
WRIO T2,.DOCS2(W) ;SELECT UNIT
RDIO T2,.DOSR(W) ;GET STATUS REGISTER
TRNE T2,DS.WRL ;WRITE PROTECTED?
AOS (P) ;YES-SKIP RETURN
POPJ P, ;RETURN
$HIGH
;ENTRY TO READ DRIVE REGS
RPXREG::PUSHJ P,SAVE1## ;GET A REGISTER
MOVE P1,KDBDVC(J) ;AND SET UP RH11 BASE ADDRESS
PUSH P,U ;RDREG WIPES U
MOVE T4,UDBPDN(U) ;PHYSICAL 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,RPXEBK(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,KDBCHN(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
SUBTTL AUTOCONFIGURATION
RPXCFG: XMOVEI T1,RPXMDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;DEFAULT TABLE
MOVSI T3,-1 ;MATCH ON ANY MASSBUS UNIT
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
PUSHJ P,AUTMDT## ;SCAN THE TABLES
JRST CPOPJ1## ;NO MATCHES
MOVSI T1,CP.R11 ;GET CHANNEL BITS
PUSHJ P,AUTCHN## ;BUILD A CHANNEL DATA BLOCK
POPJ P, ;NO CORE
LDB T1,[POINT 3,.CPDVC##,17] ;GET UNIBUS ADAPTER NUMBER
MOVEI T2,UBAPGS ;NUMBER OF MAPPING REGISTERS REQUIRED
PUSHJ P,AUTAMR## ;ALLOCATE UNIBUS MAPPING REGISTERS
POPJ P, ;NONE AVAILABLE
PUSHJ P,SAVE1## ;FREE UP P1
MOVE P1,.CPCHA## ;GET CHANNEL DATA BLOCK ADDRESS
MOVEM T1,CHNIMR(P1) ;STORE INITIAL UNIBUS MAPPING REGISTER
MOVEM T2,CHNMRC(P1) ;STORE NUMBER OF MAPPING REGISTERS
MOVEM T3,CHNIEA(P1) ;STORE INITIAL ELEVEN ADDRESS
SETZB J,P1 ;NO KDB YET, START WITH MASSBUS UNIT 0
RPXCF1: PUSHJ P,RPXUNI ;CONFIGURE A SINGLE UNIT
JFCL ;IGNORE ERRORS
AOBJN P1,.+1 ;ADVANCE TO NEXT UNIT
HLLZS P1 ;KEEP JUST MASSBUS UNIT NUMBER
TLNN P1,10 ;DONE THEM ALL?
JRST RPXCF1 ;NO, DO ANOTHER
SKIPN J ;HAVE A KDB?
AOS (P) ;NO--SO CHECK WITH OTHER DRIVERS
POPJ P, ;RETURN
;HERE TO CONFIGURE A SINGLE NEW UNIT
;P1 = UNIT NUMBER,,0
RPXUNI: JUMPE J,RPXUN1 ;SKIP TEST IF NO KDB YET
HRRZ T1,P1 ;GET UNIT
MOVE T1,BITTBL##(T1) ;AND IT'S BIT
TDNE T1,RPXIUM(J) ;WANT TO IGNORE THIS DRIVE?
POPJ P, ;SAY IT DOESN'T EXIST
RPXUN1: MOVE W,J ;AUTCON WANTS W SET UP
PUSHJ P,RDDTR## ;READ DRIVE TYPE REGISTER
CAIN T2,TY.RP5 ;RP05?
MOVEI T2,TY.RP4 ;YES, JUST CALL IT AN RP04
MOVSI T1,-TYPTBL ;-VE LENGTH OF DRIVE TYPE TABLE
MOVE T3,TYPTAB(T1) ;GET AN ENTRY
CAIE T2,(T3) ;DRIVE TYPES MATCH?
AOBJN T1,.-2 ;NO, LOOP FOR A MATCH
JUMPGE T1,RPXUN3 ;IGNORE THIS UNIT IF UNKNOWN TYPE
MOVE T2,T1 ;COPY TYPTAB INDEX (UNIT TYPE CODE, UNYUTP)
HLL T2,TYPTAB(T1) ;COPY UNIT TYPE FLAGS
HLLZ T1,P1 ;COPY UNIT NUMBER
HLRS T1 ;ALSO USE AS UDB TABLE OFFSET
JUMPN J,RPXUN2 ;IF WE ALREADY HAVE A KDB, PROCEED
PUSH P,T1 ;SAVE THE USEFUL ACS
PUSH P,T2
MOVNI T1,1 ;NO MASSBUS UNIT NUMBER
MOVEI T2,TYPRP ;KONTROLLER TYPE CODE
PUSHJ P,DSKKON## ;BUILD A KONTROLLER DATA BLOCK
JRST TTPOPJ## ;NO CORE
POP P,T2 ;RESTORE THE ACS
POP P,T1
RPXUN2: PUSHJ P,DSKDRV## ;BUILD AND LINK THE UDB
JRST RPXUN3 ;NO CORE
MOVSI T2,.DOSN ;SERIAL NUMBER REGISTER
PUSHJ P,RDMBR## ;READ IT
SETZ T1, ;REALLY A ONE-WORD QUANTITY
MOVE T3,UDBDSN(U) ;GET PHYSICAL DRIVE NUMBER
PUSHJ P,AUTDSN## ;FAKE UP S/N IF A ZERO
DMOVEM T1,UDBDSN(U) ;SET SERIAL NUMBER IN UDB
JRST CPOPJ1## ;RETURN
RPXUN3: SETZ U, ;INDICATE NO UDB
POPJ P, ;RETURN
;ONCE A SECOND CODE
RPXSEC: SKIPL @KDBCHN(J) ;CHANNEL BUSY?
POPJ P, ;LEAVE IT ALONE
SKIPE T1,RPXNUM(J) ;GET BIT MASK
JFFO T1,RPXSE1 ;FIND FIRST UNIT NUMBER
HRRZS KDBNUM(J) ;INDICATE NO DRIVES TO CONFIGURE
POPJ P, ;DONE
RPXSE1: PUSHJ P,AUTLOK## ;GET AUTCON INTERLOCK
POPJ P, ;TRY AGAIN NEXT TIME
PUSHJ P,SAVW## ;PRESERVE W
MOVE W,J ;COPY KDB ADDRESS TO W FOR AUTCON
MOVSS T2 ;MASSBUS UNIT = DRIVE NUMBER FOR RPX DISKS
PUSH P,T2 ;SAVE
MOVE T1,KDBDVC(J) ;COPY UNIBUS ADDRESS
MOVEI T2,RH11IV/4 ;GET IVI
DPB T2,[POINT 7,T1,9] ;STUFF IT
XMOVEI T2,RPXDSP ;DISPATCH
MOVE T3,KDBCHN(J) ;CHANNEL DATA BLOCK
PUSHJ P,AUTSET## ;SET UP CPU VARIABLES
EXCH P1,(P) ;SAVE P1, GET MASSBUS UNIT
PUSH P,KDBUNI(J) ;SAVE KDBUNI
MOVEM P1,KDBUNI(J) ;SET FOR THIS MASSBUS UNIT NUMBER (FOR RDMBR)
PUSHJ P,RPXUNI ;CONFIGURE A NEW UNIT
JFCL ;IGNORE ERRORS
PUSHJ P,AUTULK## ;RELEASE AUTCON INTERLOCK
POP P,KDBUNI(J) ;RESTORE KDBUNI
PJRST P1POPJ## ;RESTORE P1 AND RETURN
;TABLES INDEXED BY UNIT TYPE CODE
;0 = RP04/RP05, 1 = RP06, 2 = RM03, 3 = RP07
;DRIVE TYPE
TYPTAB: TY.RP4 ;RP04 (RP05 KLUDGED THE SAME)
TY.RP6 ;RP06
TY.RM3 ;RM03
1B0+TY.RP7 ;RP07 (NON-REMOVABLE MEDIA)
TYPTBL==.-TYPTAB ;LENGTH OF TABLE
;BLOCKS PER UNIT
BLKPRU: DEC 154280 ;(RP04/05) 406 CYLINDERS
DEC 307800 ;(RP06) 810 CYLINDERS
DEC 123150 ;(RM03) 821 CYLINDERS
DEC 865504 ;(RP07) 629 CYL, 32 SURF, 43 SECT
;BLOCKS PER UNIT IN MAINTENANCE MODE
BLKPUM: DEC 156180 ;(RP04/RP05) 411 CYLINDERS
DEC 309700 ;(RP06) 815 CYLINDERS
DEC 123450 ;(RM03) 823 CYLINDERS
DEC 866880 ;(RP07) 630 CYLINDERS
;BLOCKS PER UNIT IN COMPATIBILITY MODE
BLKPUC: DEC 171798 ;(RP04/RP05) 22*19*411
DEC 340670 ;(RP06) 22*19*815
DEC 131680 ;(RM03) 32*5*823
0 ;(RP07) NO COMPATIBILITY MODE
;BLOCKS PER TRACK,,BLOCKS PER CYLINDER
BLKPTC: XWD ^D20,^D380 ;(RP04)
XWD ^D20,^D380 ;(RP06)
XWD ^D30,^D150 ;(RM03)
XWD ^D43,^D1376 ;(RP07)
SUBTTL THE END
$LIT
RPXEND: END