Trailing-Edge
-
PDP-10 Archives
-
bb-x130a-sb
-
dpxkon.mac
There are 11 other files named dpxkon.mac in the archive. Click here to see a list.
TITLE DPXKON - DEVICE DEPENDENT RP10/RP01(RP02) DRIVER V120
SUBTTL T WACHS/TH 22 FEB 83
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<
COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
>
;DATE LOAD EDIT #
;---- ---- ------
;7-APR-81 70150 114
;11-AUG-81 70172 115
;9858-
;12-JAN-82 70126 116
;16-MAR-82 70137 117
;10144
;22-FEB-83 70126 120
;
XP VDPKON,122 ;DEFINE VERSION FOR GLOB AND MAP
;ASSEMBLY INSTRUCTIONS: DPXKON,DPXKON/C_S,KONPAR,DPXKON
;ALL INTERN AND EXTERN DECLARATIONS:
ENTRY DPXKON
BSYBIT==20 ;DP KONTROL BUSY
STPBIT==20 ;STOP DP(CLEAR BUSY, SET DONE
; CAUSE INTERRUPT)
ALLERR==177720
DPCLR==:177710
DPATTN==:776
STATBT==176 ;READY, ONLINE, UNSAFE,NO SUCH DEV, RD ONLY
STATB2==174 ;ALL EXECPT READ ONLY
UNSAFE==10 ;FILE UNSAFE
SEKINC==100
ENDCYL==200000
SRCHER==40000
CORPAR==12 ;CHAN-DETECTED CORE PARITY ERROR BITS
NXMERR==10000 ;CHAN-DETECTED NXM
DLERR==20000 ;DATA LATE (OVER RUN)
DPDONE==:10
PARDIS==5000 ;DISABLE STOP ON PAR ERROR
;THESE LOCATIONS ARE DEFINED IN COMMON FOR EACH KONTROL
;THEY ARE INDEXED BY J:
REPEAT 0,<
DPXCO1: CONO DP'N,(T2)
DPXDOT: DATAO DP'N,T1
DPXDO1: DATAO DP'N,T2
DPXDI1: DATAI DP'N,T2
DPXCIT: CONI DP'N,T1
DPXCI2: CONI DP'N,T2
DPXDI3: DATAI DP'N,T3
DPXFNC: 0
DPXIWD: 0
>
DPXKON:: ;CAUSE LOADING ON LIBRARY SEARCH
IFN FTDSUP,<
DPXWTF::MOVEI T4,OPWTF ;WRITE FORMAT (HEADERS)
JRST DPXGO
>
IFE FTDSUP,<
DPXWTF==:CPOPJ## ;CAN'T WRITE HEADERS IF NO SUPER-USETO
>
DPXRDC::
DPXRDF::
DPXRED::TDZA T4,T4 ;OP=0(READ)
DPXWTC::
DPXWRT::MOVEI T4,OPWRT
JRST DPXGO ;START MOVING DATA
DPXRDS::TDZA T4,T4 ;OP=0(READ)
DPXWTS::MOVEI T4,OPWRT
HRLI T4,1 ;LH=1 - STOP ON ERR
DPXGO: PUSHJ P,KONECT ;CONNECT RP10 TO DRIVE, SET UP T1
JRST DPXDWN ;ERROR - UNIT NOT READY
MOVE T2,@KONIOC##(J) ;LOC OF FIRST IOWD
MOVE T2,(T2) ;INITIAL IOWD ITSELF
MOVEM T2,DPXIWD##(J) ;SAVE IN CONTROL DATA BLOCK
DPXGO1: LDB T4,UNYBPT ;T3 HAS SURFACE*SECTOR
IDIV T3,T4 ;T3=SURF T4=SECTOR
DPB T3,[POINT 5,T1,18] ;STORE SURFACE
DPB T4,[POINT 4,T1,23] ;STORE SECTOR
OR T1,KONIOC##(J) ;INITIAL KON WD ADDR
DPXGO2: TRZE T1,1 ;SEEK INC?
JRST RECAL2 ;YES
SETZM T2 ;TURN OFF RP10 PI CHANNEL
XCT DPXCO1##(J) ;CONO DPN,(T2)
POP P,DPXFNC##(J) ;SAVE FUNCTION (CAN'T GET INTERRUPTED
; NOW TILL DATA TRANSFER IS DONE)
XCT DPXDOT##(J) ;START THE OPERATION
LDB T2,KOYPI## ;TURN PI CHANNEL BACK ON
XCT DPXCO1##(J)
JRST CPOPJ1## ;GIVE GOOD (SKIP) RETURN TO FILSER
DPXPOS::HRROI T4,OPPOS ;FUNCTION=POSITION, DISABLE PARITY STOP
JRST DPXRC1 ;CONNECT TO UNIT AND DO POSITIONING
DPXRCL::MOVEI T4,OPCAL ;FUNCTION=RECALIBRATE
DPXRC1: PUSHJ P,KONECT ;CONECT TO DRIVE, SET UP T1
JRST DPXDWN ;ERROR - UNIT NOT READY
JRST DPXGO2 ;START RP10 GOING (FUNCTION ON END OF PD LIST)
DPXUNL::
DPXERR::
DPXECC::STOPCD CPOPJ1##,DEBUG,RIF, ;++RP10 ISNT FANCY
DPXREG::POPJ P, ;NO MASSBUS REGS TO READ
;HERE WHEN A UNIT IS NOT READY. (ERROR BITS FOR T1 IN T3)
;SINCE IT MAY BECOME READY BEFORE THE CONTROLLER IS USED AGAIN, AND IF IT
; DOES WE WILL GET A FREE INTERRUPT, DPXFNC MUST BE RESET SO THAT WE WONT
; TELL FILSER ABOUT A SPURIOUS DATA INTERRUPT
DPXDWN: MOVEI T1,OPPOS ;SET UP A "POSITION" FUNCTION
MOVEM T1,DPXFNC##(J) ;IN THE KONTROLLER DATA DBLOCK
IOR T1,T3 ;ADD ERROR BITS
LDB T2,KOYPI## ;ENSURE THAT RP10 HAS A PIA
XCT DPXCO1##(J) ; (IN CASE OF POWER FAIL RECOVERY)
XCT DPXCI2##(J) ;COMI BITS INTO T2
XCT DPXDI3##(J) ;DATAI BITS INTO T3
POPJ P, ;GIVE NON-SKIP RETURN TO FILSER
;SUBROUTINE TO CONNECT RP10 TO A UNIT, FUNCTION IN T4
;RETURNS CPOPJ IF CANT CONNECT OR WRITE-PROTECTED ON A WRITE REQUEST
; WITH HARDWARE FUNCTION (DATAO) IN T1 ERROR BITS IN T3
;CPOPJ1 NORMALLY, FUNCTION ON END OF PD LIST, FUNCTION STILL IN T4
KONECT: XCT DPXCIT##(J) ;CONI DPN,T1
TRNN T1,BSYBIT ;BUSY?
JRST KONEC1 ;NO
MOVEI T2,STPBIT ;YES. CLEAR BUSY, SET DONE
XCT DPXCO1##(J)
AOS UNIHNG##(U) ;COUNT THE ERROR IN UNIHNG
JRST KONECT ;TRY, TRY AGAIN
KONEC1: PUSHJ P,CLRSET ;CONNECT TO DRIVE, DATAI T2 (SIM ERROR)
IFN FTDSUP,<
CAIN T4,OPWTF ;IF TRYING TO FORMAT,
TLNN T2,1 ;WRITE-HEADER LOCKOUT MUST BE OFF
>
TLNE T2,STATBT ;UNIT OK?
JRST KONERR ;NO - CHECK WRITE LOCK
KONEC2: DPB T4,[POINT 3,T1,2];YES. SET OPERATION IN T1
TLNN T4,1 ;STOP ON ERROR?
TRO T1,PARDIS ;NO, DISABLE STOP ON ERROR
EXCH T4,(P) ;SAVE FUNCTION ON PD LIST
;(CAN'T DO A MOVEM DPXFNC SINCE
;WE MIGHT GET A POSITION INTERRUPT
;BEFORE THE DATA-TRANSFER STARTS)
MOVE T2,UNIBLK(U) ;DESIRED BLOCK
LDB T3,UNYBPY ;NUMBER OF BLOCKS/CYLINDER
IDIV T2,T3 ;CYLINDER IN T2
DPB T2,[POINT 8,T1,13] ;SAVE IN T1
TRNE T2,400 ;EXTRA BIT IN CYLINDER NUMBER (RP03)?
TRO T1,200000 ;YES SET BIT IN DATAO WORD
MOVEM T2,UNICYL(U) ;SAVE CYLINDER IN UNIT DB
PJRST 1(T4)
KONERR: TLNN T2,STATB2 ;WAS THE STATUS "ERROR" WRITE LOCK?
TRNE T4,1 ;YES. IS THE OPERATION A WRITE?
TDZA T3,T3 ;NO-CLEAR POPJ ERROR BITS
JRST KONEC2 ;READ-ONLY IS OK
TLNE T2,SEKINC
JRST KONER2
TLNE T2,70 ;NOT-READY, FILE UNSAFE, OR OFF-LINE?
TRO T3,KOPOFL ;YES-LIGHT BIT FOR FILSER
TLNE T2,UNSAFE ;FILE UNSAFE
TRO T3,KOPFUS ;YES, LIGHT BIT FOR FILSER
POPJ P, ;ERROR STATUS
;HERE ON SEEK INCOMPLETE
KONER2: TRO T1,1 ;IDICATE SEEK INCOMPLETE
JRST KONEC2 ;AND CONTINUE
;ROUTINE TO COMPUTE LATENCY TIME FOR A UNIT LESS A SAFETY FACTOR
; TO INSURE THAT A COMPLETE REVOLUTION WILL NOT BE MISSED
; 0 FOR AN ANSWER MEANS CLOSEST POSSIBLE NEXT BLOCK
REPEAT 0,<
TABLE SHOWING INSTANEOUS TIME RELATION BETWEEN SECTOR COUNTER
AND ACTUAL SECTOR POSITION FOR RPO2 AND RP01 UNITS:
SECTOR COUNTER: 20
!19!! 0! 1! 2! 3! 4! 5! 6! 7! 8! 9!10!11!12!13!14!15!16!17!18!19!
RP02: ! 9 ! 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ! 8 !
RP01: ! 4 ! 0 ! 1 ! 2 ! 3 !
>
DPXLTM::LDB T2,UNYPUN ;PHYSICAL UNIT NO. ON THIS CONTROLLER
ROT T2,-6 ;SHIFT TO UNITS POSITION FOR DATAO
TLO T2,<OPSEL>B20 ;SET OPERATION TO SELECT
XCT DPXDO1##(J) ;DO A DATAO DPX,T2 TO SELECT UNIT
XCT DPXDI1##(J) ;DO A DATAI DPX,T2 TO READ SECTOR COUNTER
XCT DPXDI1##(J) ;READ A SECOND TIME SINCE COUNTER IS
; STROBBED INTO BUFFER ON TRAILING EDGE OF DATAI
TLC T2,60 ;COMPLEMENT ON-LINE,ON-CYL
TLNE T2,60 ;ON-LINE AND ON-CYL?
POPJ P, ;NO, ERROR RETURN, T1=UNSPECIFIED
LDB T4,[POINT 4,T2,22] ;GET ACTUAL HALF SECTOR COUNTER
LDB T3,UNYBPT ;NO. OF BLOCKS PER TRACK(REVOLUTION)
IDIVI T1,(T3) ;T2 GETS DESIRED SECTOR NO.(RP02=0-9;RP01=0-4)
LSH T2,1 ;CONVERT TO HALF SECTOR LIKE HARDWARE
CAIE T3,^D10 ;IS THIS AN RP02?
ADDI T2,2(T2) ;NO, MUST BE RP01, CONVERT TO QUARTER SECTOR
; PLUS 2
SUB T2,T4 ;DESIRED HALF SECTOR - MOD20(ACTUAL HALF SECT+2)
; GIVES NO. OF HALF(QUART) SECTORS TO WAIT
; TO GET TO DESIRED HALF(QUART) SECTOR(-20 THRU +20)
HRREI T1,0(T2) ;MOVE NO. OF HALF SECTORS TO WAIT
; SINCE HARDWARE CONVENIENTLY HAS A BUILT
; IN SAFETY FACTOR, NO NEED TO SUBTRACT
; ANYTHING HERE.
JUMPGE T1,DPXLT1 ;IF DISTANCE IS NEGATIVE
ADDI T1,^D20 ;ADD NO. OF HALF SECTORS IN ONE REVOLUTION
; SINCE DISK SPINS IN ONE DIRECTION
DPXLT1: IMULI T1,^D1250 ;CONVERT HALF SECTORS TO MICROSECONDS
JRST CPOPJ1## ;AND GIVE GOOD RETURN
;HERE WHEN A UNIT HANGS DURING A TRANSFER (IE DOES NOT INTERRUPT)
;ATTEMPT TO CLEAR CONTROL AND CAUSE AN INTERRUPT
DPXSTP::XCT DPXDI1##(J) ;READ IN UNIT STATUS OF LAST UNIT CONTROLLER
; CONNECTED TO, THE ONE TRANSFERRING (DATAI DPX,T2)
MOVE T3,T2 ;SAVE IN T3 FOR RETURN
XCT DPXCIT##(J) ;READ CONTROL STATUS (CONI DPX,T1)
PUSH P,T1 ;SAVE ON STACK
MOVEI T2,STPBIT ;STOP THE UNIT BIT
XCT DPXCO1##(J) ;STOP UNIT AND CLEAR PI (SO NO INT.)
XCT DPXCIT##(J) ;READ STATUS (CONI DPX,T1)
TRNN T1,BSYBIT ;IS BUSY FLAG NOW OFF?
AOS -1(P) ;YES; SET SUCCESSFUL RETURN
MOVEI T2,FNCHNG ;INDICATE HUNG-RECOVERY
IORM T2,DPXFNC##(J) ; INTERRUPT
LDB T2,KOYPI## ;PI FOR THIS KONTROLLER
XCT DPXCO1##(J) ;RESTORE PI AND GET INTERRUPT (CONO DPX,T2)
PJRST T2POPJ## ;RETURN PREVIOUS CONI STATUS IN T2
;OK OR ERROR RETURN
;CHECK IF KONTROL IS ALIVE
DPXALV::XCT DPXCIT##(J) ;CONI
TRNE T1,7 ;IS IT ALIVE?
POPJ P,
LDB T2,KOYPI## ;NO. GIVE IT A PI
XCT DPXCO1##(J)
POPJ P, ;AND RETURN
;HERE FROM COMMON ON AN INTERRUPT
;ACS HAVE BEEN SAVED, J AND P SET UP
DPXINT::XCT DPXCIT##(J) ;CONI DPN,T1
PUSH P,T1 ;SAVE CONI BITS
MOVE U,KONCUA(J) ;UNIT DATA BLOC LOC
HRRZ S,DPXFNC##(J) ;S=FUNCTION
TRZE S,FNCHNG ;HUNG RECOVERY?
JRST DEVERR ;YES, RETURN AN ERROR
TRNE S,74 ;POSITIONING INTERRUPT?
JRST POSINT ;YES
TRNE T1,ALLERR ;ERROR?
JRST ERROR ;TOO BAD
TRNN T1,ENDCYL ;DATA INTERRUPT. END OF CYLINDER?
JRST DATAIN ;NO
;HERE ON END-OF-CYLINDER
MOVE F,KONIOC##(J) ;INITIAL KONTROL WORD ADDRESS
HLRZ T1,1(F) ;LOC(LAST IOWD)+1
SUBI T1,1 ;R=LOC OF LAST IOWD
HRRZ T2,(T1) ;INITIAL ADDR. OF LAST IOWD
HRRZ T3,1(F) ;NO - LOC. OF LAST DATA WORD
SUBI T3,1(T2) ;# OF WORDS TRANSFERRED
CAIG T3,2 ;WAS THIS IOWD STARTED?
JRST ERROR ;NO - END CYLINDER WAS FROM PREVIOUS IOWD
TRNE S,1 ;OP = WRITE?
SUBI T3,2 ;YES. CHAN STORE IS 2 TOO HIGH
TRNN T3,177 ;EVEN NUMBER OF BLOCKS MOVED?
JRST ERROR ;NO. POSSIBLE CHANNEL ERROR
;HERE ON A POSSIBLE CHANNEL ERROR. THE WORDCOUNT COMPUTATION GAVE A "FUNNY" COUNT,
; WITH END OF CYLINDER. THIS IS POSSIBLE IF IT IS THE LAST IOWD,
; AND END OF CYLINDER CAME UP ON THE LAST WORD XFERRED
TRNE S,1 ;WRITING?
ADDI T3,2 ;YES. ADD BACK THE 2 WORDS
HLRE T4,(T1) ;-WDCNT OF LAST IOWD
TRNE T4,177 ;NOT EVEN MULTIPLE OF 200 WORDS?
TRNE T3,176 ;YES, 200 OR 201 WORDS COMPUTED?
JRST ENDTS1 ;NO
JRST ERROR ;YES, REAL END OF CYLINDER
ENDTS1: ADD T3,T4 ;+NO OF WORDS XFERRED (-1?)
SKIPN 1(T1) ;LAST IOWD?
AOJE T3,DATAIN ;YES. OK IF T3=-1
MOVE T1,(P) ;RESTORE CONI BITS FOR DEVERR
JRST DEVERR ;NO. CHANNEL ERROR (WRONG WORDCOUNT)
;HERE WHEN ALL DATA IS IN CORE
DATAIN: XCT DPXDI1##(J) ;DATAI DPN,T2
LSH T2,-^D15 ;SHIFT DRIVE NUMBER
HLLM T2,S ;SAVE DRIVE IN LH(S)
DATIN1: MOVEI T3,OPPOS ;SET FUNCTION=POSITION, SO ON NEXT
MOVEM T3,DPXFNC##(J) ; INTERRUPT WE DONT TELL FILSER ABOUT THIS DATA
XCT DPXDI1##(J) ;DATAI DPN,T2
CLRATN: MOVE T3,T2 ;SAVE DATAI WORD
ANDI T2,DPATTN ;GET ATTENTION BITS
JUMPE T2,INTXIT ;THROUGH IF NONE
HRLI T2,<OPCLR>B20 ;SET TO CLEAR ATTENTIONS
XCT DPXDO1##(J) ;DATAO DPN,T2 - CLEAR ATTNS
LSH T2,^D27 ;POSITION ATTNS IN LH
ORM T2,S ;SAVE IN S
INTXIT: LDB T2,KOYPI## ;DPN PI CHANNEL
TRO T2,DPCLR ;SET TO CLEAR THE RP10
XCT DPXCO1##(J) ;CLEAR ALL BUT PI ASSIGNMENTS
MOVE T1,S ;RETURN TO FILSER WITH T1 =
;BITS 0-7 = ATTENTIONS
;BITS 15-17 = DRIVE NUMBER(IF DATA INTERRUPT)
;BITS 18-23 = ERROR INDICATION
;BITS 33-35 = FUNCTION
POP P,T2 ;T2 = CONI BITS
PJRST FILINT ;RETURN TO FILSER
;HERE ON A POSITIONING INTERRUPT
POSINT: XCT DPXDI1##(J) ;DATAI DPN,T2
TRNN S,70 ;SPECIAL INTERRUPT?
;(RECALIBRATE OR FREE POSITIONING)
JRST CLRATN ;NO. SET ATTNS IN LH AND GO TO FILSER
LDB T1,UNYPUN ;YES. U=SPECIAL UNIT #
MOVNS T1 ;SET TO COMPUTE RIGHT ATTN BIT
MOVEI T3,400
LSH T3,(T1) ;T3= ATTN BIT WHICH SHOULD BE ON
TDNN T2,T3 ;IS IT FOR "SPECIAL" UNIT?
JRST POSIN3 ;NO. DON'T WORRY ABOUT IT
MOVE T4,DPXFNC##(J)
TRNN T4,OPPOS
JRST POSIN1
TLNE T2,SEKINC
JRST DEVERR
JRST POSIN3
POSIN1: TLO T3,<OPCLR>B20 ;YES. CLEAR THIS ATTN
MOVE T1,T3 ;(LEAVE THE OTHER ATTNS FOR LATER)
XCT DPXDOT##(J) ;DATAO DPN,T1
TRZN T4,10 ;FREE POSITION?
JRST POSIN2 ;NO. MUST BE FROM RECALIBRATE
TLNE T2,SEKINC
JRST POSIN4
LDB T1,UNYPUN ;YES. GET UNIT NUMBER
ROT T1,-6 ;POSITION TO DRIVE FIELD
POP P,T2 ;PD LIST HAS CONI BITS - REMOVE IT
SOS (P) ;DPXGO1 WILL EXIT CPOPJ1
PUSHJ P,KONEC2 ;SET UP FOR DATA IO COMMAND
STOPCD .+1,DEBUG,KDS, ;++KONEC2 DIDN'T SKIP
PJRST DPXGO1 ;START NEW DATA COMMAND AND EXIT THE INTERRUPT
;WAS A RECALIBRATE INTERRUPT FOR SELECTED DRIVE
POSIN2: TRZ T4,20 ;RESET RECALIBRATE BIT
MOVEM T4,DPXFNC##(J) ;SAVE IN FUNCTION
MOVE T1,UNICYL(U) ;GET DESIRED CYLINDER
LDB T2,UNYPUN ;T2=DRIVE
LSH T1,^D22 ;POSITION NEW CYLINDER ADDRESS
TLZE T1,10000 ;EXTENDED CYLINDER NUMBER (RP03)?
TRO T1,200000 ;YES, SET EXTENDED BIT
DPB T2,[POINT 3,T1,5] ;SET UP DRIVE NUMBER
TLO T1,<OPPOS>B20 ;POSITION TO IT
MOVEI T2,10 ;INDICATE "FREE" POSITIONING
ORM T2,DPXFNC##(J)
XCT DPXDOT##(J) ;DATAO DPN,T1
JRST TPOPJ## ;AND EXIT THE INTERRUPT
;HERE WHEN "WRONG" ATTENTION BIT IS UP
POSIN3: MOVEI S,OPPOS ;JUST A POSITIONING INTERRUPT
JRST CLRATN ;GO CLEAR THE ATTENTION AND TELL FILSER
;HERE ON SEEK INCOMPLETE AFTER FREE POSITION
POSIN4: TRC S,IODERR+10 ;TURN ON IODERR, TURN OFF 10
LDB T2,UNYPUN ;UNIT (DATAI MAY RETURN 0
HRLZS T2 ;INSTEAD OF RIGHT DRIVE AFTER SEEK INCOMPLETE
JRST DATIN1 ;GO TELL FILSER
ERROR: TLNN T1,CORPAR ;NO, CORE PARITY ERROR?
TRNE T1,NXMERR!DLERR ;NO. NXM OR DATA LATE?
JRST REF ;YES. REFRENCE THE LOC
CHANER: TLNE T1,DATBTS ;DATA ERROR (PARITY)?
TROA S,IODTER ;DATA ERROR
DEVERR: TRO S,IODERR ;YES
TRNE T1,SRCHER ;SEARCH ERROR (HEADERS)?
TRO S,IOHDER ;YES
JRST DATAIN ;LOOK AT ATTNS AND GO TO FILSER
;HERE ON SEEK-INCOMPLETE
RECAL2: TLO T1,<OPCAL>B20 ;RECALIBRATE TO BRING DRIVE TO LIFE
XCT DPXDOT##(J)
POP P,T1 ;FUNCTION
TRO T1,20 ;INDICATE RECALIBRATE
MOVEM T1,DPXFNC##(J)
PJRST CPOPJ1## ;AND TELL FILSER ALL'S OK
DATBTS=5
ERRBTS=143720
REF: TRNN T1,NXMERR!DLERR ;CHAN - DETECTED ERROR
TROA S,IOCHMP!IODERR ;CORE PARITY ERR
TRO S,IOCHNX!IODERR ;NXM OR DATA LATE
TRNE T1,DLERR ;DATA LATE (=OVERRUN)?
TRO S,IOVRUN ;YES
JRST CHANER ;SET IODERR AND CONTINUE
;SUBROUTINE TO GET STATUS OF A UNIT
; ENTER WITH U=UNIT DATA BLOCK ADR. J=KONTROLLER DATA BLOCK ADR.
; RETURN WITH T2=UNIT STATUS FROM DATAI, GOOD-BITS ARE COMPLEMENTED
; SO ERRORS CAN BE CHECKED EASILY
DPXSTS::MOVEI T2,DPCLR ;ENTRY TO CLEAR CONO
XCT DPXCO1##(J) ;DO THE CONO TO RP10
CLRSET: LDB T1,UNYPUN ;UNIT NUMBER
ROT T1,-6 ;POSITION TO DRIVE FIELD
TLO T1,<OPSEL>B20 ;SET OPERATION = NOP
TLC T1,10000 ;FIRST CONNECT TO ANOTHER DRIVE
XCT DPXDOT##(J) ;SO THAT RECONNECTING TO RIGHT
TLC T1,10000 ;DRIVE WILL GIVE GOOD STATUS INFORMATION
XCT DPXDOT##(J) ;DATAO DPN,T1
XCT DPXDI1##(J) ;DATAI DPN,T2
TLC T2,60 ;INVERT BITS WHICH SHOULD BE 1
POPJ P, ;AND EXIT
IFN FTDHIA,<
;HERE TO CHECK CAPACITY & STATUS OF A UNIT
DPXCPY::PUSHJ P,DPXSTS ;GET STATUS OF OF THIS UNIT IN T2
PUSH P,T2 ;SAVE STATUS
MOVSI T4,KOPUHE## ;ASSUME ERRORS
TLO T4,KOPNSU## ;ALSO SUCH UNIT
TLNE T2,4 ;DOES NOT EXIST
JRST DPXCP3 ;NO, GIVE DON'T ASK QUESTION RETURN
SETZ T4, ;ASSUME UNIT IS UP
SKIPN DINITF## ;IN ONCE-ONLY?
JRST DPXCP3 ;NO, ASSUME CONTROLLER IS UP
TLCN T2,60 ;UNIT ON CYLINDER & ON-LINE?
TLNE T2,110 ;YES - SEEK INCOMPLETE,FILE UNSAFE
TLO T4,KOPUHE## ;YES - INDICATE UNIT HAD ERROR
LDB T2,[POINT 11,T2,10] ;GET DRIVE & CYLINDER # FOR DATAO
TLO T2,417400 ;(10,,370000)_^D14 - SELECT AN ILLEGAL SECTOR
ROT T2,-^D14 ;SHIFT INTO CORRECT POSITION FOR DATAO
OR T2,KONIOC##(J)
XCT DPXDO1##(J) ;DO A DATAO DPX,T2
MOVEI T2,^D1000 ;LOOP 1000 TIMES
DPXCP1: XCT DPXCIT##(J) ;DO A CONI DPX,T1
TRNE T1,DPDONE ;DONE YET?
JRST DPXCP2 ;YES
SOJG T2,DPXCP1 ;NO, LOOP
MOVSI T4,KOPNSU## ;UNIT DOESN'T EXIST
JRST DPXCP3 ;CONTROLLER IS DEAD
DPXCP2: TRNN T1,200 ;ILLEGAL SECTOR?
TLO T4,KOPUHE## ;NO - SOMETHING'S AMISS!
DPXCP3: LDB T2,KOYPI##
XCT DPXCO1##(J) ;GIVE RP10 A PI
XCT DPXCIT##(J) ;CONI DP'N,T1
SKIPN DINITF## ;IF ATTACH COMMAND,
TRNE T1,7 ;IF THE CONTROLLER ISN'T THERE,
CAIA
JRST T2POPJ## ;NEITHER IS THE UNIT
POP P,T2 ;RESTORE UNIT STATUS TO T2
TLNE T1,20 ;22-BIT CHAN?
TLO T4,KOP22B## ;YES
TRNE T2,2000 ;SKIP IF UNIT NOT RP03
JRST DPXCP4 ;IS RP03, SET UP
MOVEI T1,^D40000 ;# BLOCKS ON UNIT (RP02)
MOVEI T2,^D40600 ;# BLOCKS INCLUDING MAINT CYLS
HRRI T4,1 ;RETURN RP02 TYPE CODE
JRST DPXCP5 ;TEST IF UNIT UP AND RETURN
;HERE IF UNIT IS RP03
DPXCP4: MOVEI T1,^D80000 ;# BLOCKS (RP03)
MOVEI T2,^D81200 ;# BLOCKS INCLUDING MAINT CYLS
HRRI T4,2 ;RETURN RP03 TYPE CODE
DPXCP5: SETZ T3, ;NO 10/11 COMPATABILITY MODE
MOVE W,[^D10,,^D200] ;BLKS PER TRK,,BLKS PER CYL
TLNN T4,KOPUHE## ;UNIT UP?
AOS (P) ;YES, SKIP-RETURN
IFN FTDUAL,<
HRRZS J ;NO SERIAL NUMBER
>
POPJ P, ;RETURN TO CALLER
> ;END FTDHIA
LIT
DPXEND: END