1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-07 19:21:02 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

975 lines
32 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE RHXKON - RH11 DRIVER FOR RP06'S AND RM03'S V043
SUBTTL J EVERETT/JE/DBD 23 AUG 88
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,043
;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
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