Google
 

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