Google
 

Trailing-Edge - PDP-10 Archives - bb-pbdea-bb - 10,7/unsmon/fhxkon.mac
There are 12 other files named fhxkon.mac in the archive. Click here to see a list.
TITLE FHXKON DEVICE DEPENDENT RC-10/RD-10 SUBROUTINES V116
SUBTTL RG UNDERWOOD/TW  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
; 1973,1974,1975,1976,1977,1978,1979,1980,1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1973,1988>


XP VFHXKN,116		;VERSION NUMBER FOR MAP AND GLOB

;ASSEMBLY INSTRUCTIONS: FHXKON,FHXKON/C_S,KONPAR,FHXKON

ENTRY	FHXKON


ALLERR==177720		;ALL ERRORS EXCEPT SEARCH (SINCE SEARCH
			; CAN ONLY BE CLEARED BY DOING A FUNCTION)

XP	FHALCL,177710	;CLEAR ALL ERRORS
SRCERR==200000		;SEARCH ERROR
OVRERR==100		;OVERRUN

;DEFINED IN KONKON

REPEAT 0,<
FHXCI1:	CONI	FH'N,T2
FHXCOT:	CONO	FH'N,(T1)
FHXCO1:	CONO	FH'N,(T2)
FHXDI2:	DATAI	FH'N,T3
FHXDOT:	DATAO	FH'N,T1
FHXIWD:	0		;INITWD
>

;CONO/CONI FORMAT [CONO FUNCTION,*IF RESET OF CONI]
; BIT(S)
; 0-4		.SPARE
;  5		[SPARE]MAINT.SEG
;  6		[SPARE]PROTECTION AREA
; 7-17		[SPARE]
;  18		[SELECT SECTOR COUNTER(1)]DATA TRANSFER IN PROGRESS
;  19		[SELECT SECTOR COUNTER(0)]SEARCH ERROR
;  20		[*]DISK DESIGNATION ERROR
;  21		[*]TRACK SELECT ERROR
;  22		[*]DISK NOT READY
;  23		[*]POWER SUPPLY FAILURE
;  24		[*]DISK PARITY ERROR
;  25		[*]CHAN DATA PARITY ERROR
;  26		[*]CHAN CW PARITY ERROR
;  27		[*]NON-X-MEM
;  28		[*]PROTECTION ERROR(ILLEGAL WRITE)
;  29		[*]OVER-RUN
;  30		[WRITE CW]CW WRITTEN INTO MEMORY
;  31		[*]BUSY
;  32		[*]DONE
; 33-35		PI CHAN ASSG
;DATAO FORMAT

; 0-1		DISK SELECTION
; 2-10		TRK SELECTION(BIT2=UPPER(1).OR LOWER(0)TRACKS0-99 IN TWO BCD CHAR)
; 11-17		SEGMENT SELECT(TWO BCD CHAR 0-79)
; 18-23		INITIAL PARITY CHARACTER
;   24		DISABLE DISK PARITY ERROR STOP
;   25		DISABLE CHAN PARITY ERROR STOP(CHAN DATA PARITY ONLY)
;   26		WRITE
; 27-34		INITIAL CONTROL WORD ADDRESS
;   35		WRITE EVEN PARITY INTO MEMORY(DURING READ ONLY)


;DATA: FORMAT

; 0-17		SPARE
; 18-23		INITIAL PARITY REGISTER
; 24,25		SPARE
; 26,27		SECTOR COUNTER SELECTED
; 28-35		SECTOR COUNTER

SUBTTL	AUTOCONFIGURATION


FHFIX==400000			;BIT 0 = 1 IF FIXED HEAD DEVICE
FHOFS==400000			;NO OFFSET CAPABILITY
FHRDC==400000			;NO 10/11 COMPATABILITY MODE
FHUNL==400000			;NO UNLOAD CAPABILITY
FHCPY==KOPIDL			;KONTROLLER MUST BE IDLE TO DETERMINE UNIT TYPE
FHMX==0				;CANNOT DO MULTIPLE TRANSFERS
FHDRB==0			;DOESN'T USE DISK I/O REQUEST BLOCKS
FHBMX==0			;NOT A BLOCK MULTIPLEX KONTROLLER
FHECA==0			;TRY OFFSET/RECAL BEFORE TRYING ECC
FHERNO==0			;NO DRIVE REGISTERS TO SAVE ON ERROR
FHXELG==DPEELG##		;ERROR LOG ROUTINE IS IN COMMOD

FHXDMX==10			;MAXIMUM NUMBER OF DRIVES ON KONTROLLER
FHXHDN==FHXDMX-1		;HIGHEST DRIVE NUMBER ON KONTROLLER

;DRIVER CHARACTERISTICS
;	FHX	= FHXCNF
;	DSK	= DISK
;	0	= MAXIMUM DEVICES IN SYSTEM (NO LIMIT)
;	TYPFH	= KONTROLLER TYPE
;	FHXDMX	= MAXIMUM DRIVES PER KONTROLLER
;	FHXHDN	= HIGHEST DRIVE NUMBER ON KONTROLLER
;	MDSEC0	= SECTION FOR KDB/UDB
;	MDSEC0	= SECTION FOR DDB
DRVCHR	(FHX,DSK,0,TYPFH,FHXDMX,FHXHDN,MDSEC0,MDSEC0,<DR.MCD>)

	.ORG	KONUDB		;START OF KONTROLLER SPECIFIC DATA
FHXUTB:!BLOCK	FHXDMX		;UDB TABLE
FHXEBK:!BLOCK	1		;DUMMY STORAGE FOR REGISTERS
FHXIOB:!			;START OF SPECIAL I/O INSTRUCTIONS
FHXCI1:!BLOCK	1
FHXCOT:!BLOCK	1
FHXCO1:!BLOCK	1
FHXDI2:!BLOCK	1
FHXDOT:!BLOCK	1
FHXIOE:!			;END OF SPECIAL I/O INSTRUCTIONS
FHXIWD::!BLOCK	1		;INITWD STORAGE
FHXIUM:! BLOCK	FHXDMW		;IGNORE DRIVE MASK
FHXNUM:! BLOCK	FHXDMW		;NEW DRIVE MASK
FHXKLN:!			;LENGTH OF KDB
	.ORG

;PROTOTYPE KDB
FHXKDB:	XXKON	(FH)
	SETWRD	(FHXCI1,<CONI	000,T2>)
	SETWRD	(FHXCOT,<CONI	000,(T1)>)
	SETWRD	(FHXCO1,<CONO	000,(T2)>)
	SETWRD	(FHXDI2,<DATAO	000,T3>)
	SETWRD	(FHXDOT,<DATAO	000,T1>)
	KDBEND

EQUATE	(LOCAL,0,<FHXULP,FHXULB>)
EQUATE	(LOCAL,CPOPJ##,<FHXALV,FHXEDL,FHXHWP,FHXINI,FHXRLD>)

	FHXCCM==CYLCM##
	FHXICD==DSKICD##	;PROTOTYPE INTERRUPT CODE
	FHXICL==DSKICL##

	FHXUDB==0		;NO PROTOTYPE UDB
	FHXULN==UNIEBK+FHERNO	;LENGTH OF UDB

FHXDSP:	DRVDSP	(FHX,DSKCHN##,DSKDDB##,DDBLEN##,DSKDIA##)

;DEFAULT MONGEN'ED DEVICE TABLE

DEFMDT:	MDKL10	(7,170,0,0,<MD.KON>)	;DEVICE CODE 170
	MDKL10	(7,174,0,0,<MD.KON>)	;DEVICE CODE 174
	MDTERM				;TERMINATE TABLE

FHXCKT:	EXP	0			;COMPATIBLE KONTROLLER TABLE
FHXCFG:	XMOVEI	T1,FHXMDT##	;MONGEN'ED DEVICE TABLE
	XMOVEI	T2,DEFMDT	;DEFAULT TABLE
	MOVNI	T3,1		;NO MASSBUS UNIT OR DRIVE INFORMATION
	MOVEI	T4,MD.KON	;MATCH ON KONTROLLER DEFINITION
	PUSHJ	P,AUTMDT##	;SCAN THE TABLES
	  JRST	CPOPJ1##	;NO MATCHES
	PUSHJ	P,SAVE1##	;SAVE P1
	MOVSI	T1,0		;I/O BUS-STYLE CHANNEL
	PUSHJ	P,AUTCHN##	;BUILD A CHANNEL DATA BLOCK
	  POPJ	P,		;NO CORE
	MOVNI	T1,1		;NO MASSBUS UNIT NUMBER
	MOVEI	T2,TYPFH	;KONTROLLER TYPE
	PUSHJ	P,DSKKON##	;BUILD A KDB
	  POPJ	P,		;GIVE UP IF NO CORE
	MOVSI	T1,-<FHXIOE-FHXIOB> ;NUMBER OF WORDS TO CHECK
	XMOVEI	T2,FHXIOB(J)	;STARTING WORD
	HRRZ	T3,.CPDVC##	;<DEVICE CODE>/4
	PUSHJ	P,AUTDVC##	;SET DEVICE CODES
	MOVE	T1,KDBCSO(J)	;GET CONSO SKIP CHAIN ADDRESS
				;***NEED SYMBOL (DONE)
	MOVEI	T2,10		;AND INTERRUPT FLAGS
	HRRM	T2,DICDIF##(T1)	;SET THEM
	MOVSI	P1,-1		;NO MASSBUS UNIT,,DRIVE 0

FHXCF1:	PUSHJ	P,FHXDRV	;AUTOCONFIGURE A SINGLE DRIVE
	  JFCL			;IGNORE ERRORS
	HRRZ	T1,P1		;GET DRIVE NUMBER
	CAIGE	T1,FHXDMX-1	;DONE ALL DRIVES?
	AOJA	P1,FHXCF1	;LOOP BACK FOR MORE
	JRST	CPOPJ1##	;TRY ANOTHER DEVICE ON CHANNEL

;CONFIGURE A SINGLE DRIVE
FHXDRV:	HRRZ	T1,P1		;GET UNIT
	MOVE	T1,BITTBL##(T1)	;AND IT'S BIT
	TDNE	T1,FHXIUM(J)	;WANT TO IGNORE THIS DRIVE?
	POPJ	P,		;SAY IT DOESN'T EXIST
	XMOVEI	T1,FHXMDT##	;MONGEN'ED DEVICE TABLE
	XMOVEI	T2,DEFMDT	;AND THE DEFAULT TABLE
	MOVE	T3,P1		;DRIVE INFORMATION
	PUSHJ	P,AUTMDT##	;FOUND A DRIVE MATCH?
	  POPJ	P,		;NO
	HRLZ	T1,P1		;PHYSICAL DRIVE NUMBER
	HRR	T1,P1		;UDB TABLE INDEX
	MOVEI	T2,TYPFH	;FLAGS,,UNIT TYPE
	PUSHJ	P,DSKDRV##	;BUILD A UDB
	  JFCL			;FAILED
	JRST	CPOPJ1##	;RETURN
;ONCE A SECOND CODE
FHXSEC:	SKIPL	@KDBCHN(J)	;CHANNEL BUSY?
	POPJ	P,		;LEAVE IT ALONE
	SKIPE	T1,FHXNUM(J)	;GET BIT MASK
	JFFO	T1,FHXSE1	;FIND FIRST UNIT NUMBER
	HRRZS	KDBNUM(J)	;INDICATE NO DRIVES TO CONFIGURE
	POPJ	P,		;DONE
FHXSE1:	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
	PUSH	P,T2		;SAVE PHYSICAL DRIVE NUMBER
	MOVE	T1,KDBDVC(J)	;DEVICE CODE
	XMOVEI	T2,FHXDSP	;DISPATCH
	MOVE	T3,KDBCHN(J)	;CHANNEL DATA BLOCK
	PUSHJ	P,AUTSET##	;SET UP CPU VARIABLES
	EXCH	P1,(P)		;SAVE P1, PHYSICAL DRIVE NUMBER
	TLO	P1,-1		;NO MASSBUS UNIT
	PUSH	P,KDBUNI(J)	;SAVE KDBUNI
	MOVEM	P1,KDBUNI(J)	;SET FOR THIS MASSBUS UNIT NUMBER (FOR RDMBR)
	PUSHJ	P,FHXDRV	;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
;SUBROUTINES TO INITIATE DATA TRANSFER.(ENTER WITH U AND J SET-UP)

FHXKON::
FHXRDC::
FHXRDF::
FHXRED::TDZA	T4,T4		;HERE TO READ W/O STOP ON ERROR
FHXWTF::
FHXWTC::
FHXWRT::MOVEI	T4,1B26		;HERE TO WRITE W/O STOP ON ERROR
	TRO	T4,3B25		;SUPPRESS STOP ON ERROR (BOTH CHN MEM AND DEV)
	JRST	FHXGO
FHXRDS::TDZA	T4,T4		;HERE TO READ AND STOP ON ERROR
FHXWTS::MOVEI	T4,1B26		;HERE TO WRITE AND STOP ON ERROR
FHXGO:	XCT	FHXCI1(J)	;CONI FH'N,T2
	TRNE	T2,ALLERR	;NO ERROR CONDITIONS(INCL BUSY)ALLOWED
	JRST	FHXPOP
	MOVE	T1,UNIBLK(U)	;T1 _ LOGICAL BLOCK NUMBER
	PUSHJ	P,CNVBLK	;CONVERT LOGICAL BLOCK TO BARE DATAO IN ITWD
	IOR	T1,KDBICP(J)	;INSERT INIT CHAN CNTL WD ADDR
	IORI	T1,(T4)		;  AND FUNCTION CNTL FLAGS
	MOVEM	T1,FHXIWD(J)	;SAVE COMPLETED INITWD FOR OTHERS
	SETZ	T2,
	XCT	FHXCO1(J)	;CONO FH'N,(T2)
	XCT	FHXDOT(J)	;DATAO FH'N,T1
	MOVEI	T2,DSKCHN##	;PI CHAN FOR DISK
	XCT	FHXCO1(J)	;CONO FH'N,(T2)	;TURN ON PI
	XCT	FHXCI1(J)	;CONI FH'N,T2
	TRNE	T2,7		;IS THE PI THERE?
	PJRST	CPOPJ1##	;YES, GOOD RETURN
FHXPOP:	MOVEI	T1,FHALCL	;NO, CLEAR OUT THE ERRORS
	XCT	FHXCOT(J)	; SO WILL RETRY NEXT TIME
	TRNN	T2,3B23		;UNIT OFF-LINE?
	TDZA	T1,T1		;NO
	MOVEI	T1,KOPOFL	;YES, INDICATE OFF-LINE
	XCT	FHXDI2(J)	;DATAI FM'N,T3
	POPJ	P,		;GO TELL FILSER
;CONVERT LOGICAL BLOCK IN T1 TO DISK DATAO INITWD IN T1(LOGICAL BLOCK# IS LOST)



CNVBLK:	LDB	T3,UNYBPT##	;GET # BLOCKS/TRACK
	IDIVI	T1,(T3)		;EXTRACT TRACK ADDR, (T1)=TRACK, (T2)=SEGMENT
	PUSH	P,T2		;SAVE SEGMENT
	IDIVI	T1,^D10		;CONVERT TRACK TO BCD
	CAIL	T1,^D10		;A SHORT-CUT BECAUSE RANGE=0-199/10=0-19
	ADDI	T1,6		;A BCD TENS CHAR
	LSH	T1,4		;LEFT JUSTIFIED TO MAKE ROOM FOR UNITS
	IOR	T1,T2		;NOW THE UNITS, HENCE A BCD TRACK ADDR
	ROT	T1,-^D11	;PROPERLY JUSTIFIED FOR DATAO WD
	EXCH	T1,(P)		;SAVE TRACK AND FETCH SEGMENT
	LDB	T2,UNYUTP##	;GET UNIT TYPE (RD-10 =0 RM10B =1)
	TRC	T2,1		;SET RD=1 - RM=0
	LSH	T1,1(T2)	;SEGMENT*2(OR 4)=128 WORD BLOCK
	IDIVI	T1,^D10		;CONVERTED TO BCD ADDR.
	LSH	T1,4		;LEFT JUSTIFY TENS CHAR
	IOR	T1,T2		;INSERT UNITS CHAR
	HRLZS	T1		;JUSTIFY FOR DATAO
	IORM	T1,(P)		;AND SAVE AWAY
	MOVE	T1,UDBPDN(U)	;PHYSICAL DRIVE NUMBER
	ROT	T1,-2		;JUSTIFIED
	IORM	T1,(P)		;UNIT NUMBER SAVED AWAY
	JRST	TPOPJ##		;EXIT

;THIS DEVICE DOESN'T POSITION!
FHXPOS::HALT	CPOPJ1##
FHXUNL::
FHXECC::
FHXERR::STOPCD	CPOPJ1##,DEBUG,CIF,	;++RC10 ISNT FANCY
FHXREG::POPJ	P,		;NO MASSBUS REGS TO READ


;SUBROUTINE TO COMPUTE ROTATIONAL LATENCY
;CALL:	MOVE	T1,LOGICAL BLOCK DESIRED
;	PUSHJ	P,FHXLTM
;	  ERROR RETURN-DEVICE NOT READY OR BUSY
;	OK RETURN, T1 CONTAINS NO. OF MICROSECONDS TILL GET TO SECTOR
;ROUTINE IS WRITTEN TO BE FAST AS POSSIBLE SINCE CALLED IN LOOP ON PI LEVEL

FHXLTM::XCT	FHXCI1(J)	;READ CONTROLLER STATUS-CONI F4'N,T2
	TRNE	T2,ALLERR	;ANY ERRORS (INCLUDING BUSY)
	POPJ	P,		;YES, ERROR RETURN
	MOVE	T2,UDBPDN(U)	;GET PHYSICAL DRIVE NUMBER
	LSH	T2,^D16		;SHIFT TO UNITS POSITION
	IORI	T2,DSKCHN##	;PREPARE T2
	XCT	FHXCO1(J)	;SELECT UNIT AND SECTOR COUNTER-CONO FH'N,T2
	XCT	FHXDI2(J)	;READ SECTOR COUNTER
	ANDI	T3,377		;MASK OUT ALL BUT SECTOR INFO
FHXLTL:	MOVE	T2,T3		;SAVE SECTOR
	XCT	FHXDI2(J)	;READ SECTOR COUNTER AGAIN
	ANDI	T3,377		;MASK OUT ALL BUT SECTOR INFO
	CAME	T3,T2		;ARE THEY THE SAME?
	JRST	FHXLTL		;NO, READ AGAIN-COUNTERS IN TRANSITION
	ANDI	T2,17		;YES, MASK FOR UNITS POSITION
	LSH	T3,-4		;RIGHT JUSTIFY TENS CHAR
	IMULI	T3,^D10		;CONVERT TO BINARY
	ADDI	T3,(T2)		;ADD UNITS FOR BINARY
	MOVEI	T2,UNPUTP	;UNIT TYPE BIT
	TDNN	T2,UNIUTP(U)	;IS IT AN RM10B DRUM
	JRST	FHXLTD		;NO, RD10 DISK

;HERE TO COMPUTE LATENCY FOR RM10B DRUM (BRYANT) ON RC10
	IDIVI	T1,^D30		;NO, COMPUTE DESIRED BLOCK FROM LOGICAL BLOCK NO.
				; 30=NO. OF 128 WORD BLOCKS PER REVOLUTION
	LSH	T2,1		;CONVERT TO DESIRED 64 WORD SECTOR
	SUBI	T2,3(T3)	;DISTANCE=DESIRED-ACTUAL 64 WORD SECTOR
				;ALLOW FOR 3 SECTORS AHEAD=850 MICROSECS.
	JUMPGE	T2,FHXLT1	;IS DISTANCE POSITIVE?
	ADDI	T2,^D61		;NO, ADD NO. OF 64 WORD SECTORS PER REV.
	JUMPL	T2,.-1		;IS IT STILL NEGATIVE (3 OUT OF 3600 TIMES)?
FHXLT1:	IMULI	T2,^D285	;NO, CONVERT TO NO. OF MICROSECONDS
				; 285 MICROSECONDS PER 64 WORD SECTOR.
	JRST	FHXLTE		;MOVE RESULT TO T1 AND SKIP RETURN
;HERE TO COMPUTE LATENCY FOR RD10 DISK (BURROUGHS) ON RC10
FHXLTD:	IDIVI	T1,^D20		;COMPUTE DESIRED BLOCK FROM LOGICAL BLOCK NO.
				; 20=NO. OF 128 WORD BLOCKS PER REVOLUTION
	LSH	T2,2		;CONVERT TO DESIRED 32 WORD SECTOR.
	SUBI	T2,2(T3)	;DISTANCE=DESIRED-ACTUAL 32 WORD SECTOR
				; ALLOW FOR 2 SECTORS AHEAD=262 MICROSEC.
	JUMPGE	T2,FHXLT2	;IS DISTANCE POSITIVE?
	ADDI	T2,^D81		;NO, ADD NO. OF 32 WORD SECTORS PER REV.
	JUMPL	T2,.-1		;IS IT STILL NEGATIVE (2 OUT OF 6400 TIMES)?
FHXLT2:	IMULI	T2,^D431	;YES, CONVERT TO NO. OF MICROSECONDS
FHXLTE:	MOVE	T1,T2		;RETURN IN T1
	AOS	(P)		;SKIP RETURN - DO NOT JRST CPOPJ1 FOR SPEED
	POPJ	P,		;RETURN
;SUBROUTINE TO INTERFACE FHX WITH FILINT
;ENTERED FROM COMMON WITH AC-J AND P SET-UP

FHXINT::XCT	FHXCI1(J)	;CONI FH'N,T2
	MOVE	U,KONCUA(J)	;U _ UNIT DATA BLOCK ADDR
	MOVS	T4,UDBPDN(U)	;PHYSICAL DRIVE NUMBER TO LH (T4)
	MOVE	T3,FHXIWD(J)	;T3 _ LAST DEVICE INITWD
	TRNE	T3,1B26		;WAS IT A WRITE?
	TRO	T4,OPWRT	;YES,SET WRITE FUNCTION
	TRNN	T2,ALLERR!SRCERR	;ANY ERRORS ON INTERRUPT
	JRST	XFRDUN		;NO,GO

;HERE ON ANY INTERRUPT ERROR.

	TRNE	T2,7B27!1B29	;CHAN PARITY OR NXM OR DATA LATE?
	JRST	REFER		;YES, REFRENCE THE BAD LOC
	TRNE	T2,1B24		;DISK PARITY ERROR?
	TROA	T4,IODTER
	TRO	T4,IODERR

XFRDUN:	XCT	FHXDI2(J)	;DATAI FH'N,T3 - ARG TO FILINT
	MOVEI	T1,FHALCL	;THEN CLEAR THE DEVICE
	TRNE	T2,1B22		;LEAVE NOT-READY UP SO FHXGO WILL NOTICE
	MOVEI	T1,1B32
	XCT	FHXCOT(J)
	MOVE	T1,T4		;T1 _ FILINT STATUS WORD
	PJRST	FILINT##	;EXIT TO FILINT
REFER:	TRNE	T2,OVRERR	;OVERRUN?
	TRNE	T2,ALLERR!SRCERR-OVRERR	;YES, ONLY OVERRUN?
	JRST	REFER3		;NO, LOSE
	MOVE	T1,KDBICP(J)	;YES, GET L(ICWA)
	PUSH	P,P1
	MOVE	P1,UDBKDB(U)
	MOVE	P1,KDBCHN(P1)
	LDB	T3,CNTPT1##+0	;L(LAST IOWD USED)+1
	SKIPE	T1,(T3)		;IS IT LAST IOWD?
	JRST	REFER2		;NO, REAL ERROR
	LDB	T1,ADRPT2##+0	;FIRST ADR OF LAST IOWD
	LDB	T3,CNTPT2##+0	;COUNT OF LAST IOWD
	TDO	T3,CNTFIL##
	MOVNS	T3
	ADD	T3,T1		;LAST ADR +1
	MOVE	T1,KDBICP(J)
	LDB	T1,ADRPT1##+0	;LAST ADR+1 STORED BY CHAN
REFER2:	POP	P,P1
	CAMN	T1,T3		;WAS LAST WORD OBTAINED BY CHAN?

	JRST	XFRDUN		;YES, IGNORE THE ERROR, WE WON ANYWAY
	TRO	T4,IOVRUN+IODERR	;NO, INDICATE OVERRUN
REFER3:	TRNE	T2,6B27		;CHAN-DETECTED ERROR
	TRO	T4,IOCHMP+IODERR	; CORE-PARITY ERROR
	TRNE	T2,1B27
	TRO	T4,IOCHNX+IODERR	;NXM
	JRST	XFRDUN		;CONTINUE
;HERE TO CHECK THE CAPACITY & STATUS OF A UNIT
; IF CALLED BY ONCE-ONLY REQUIRES F AND .UPMBF TO BE SET UP

FHXCPY::MOVSI	T4,KOPUHE	;SET FOR UNIT HAD ERROR RETURN
	XCT	FHXCI1(J)	;CONI FH'N,T2
	TLNE	T2,(1B5)	;MAINT. SEGMENT SWITCH ON?
	JRST	FHXCL1		;OFF LINE - NON-SKIP RETURN
	SKIPN	DINITF##	;IN ONCE-ONLY?
	JRST	FHXCP5		;NO, ASSUME CONTROLLER IS OK
	MOVEI	T3,^D5		;NUMBER OF TIMES TO RETRY BEFORE SAYING OFF-LINE
FHXCP1:
;	MOVE	T1,KONCOM(J)
;	HRRZM	T1,@KDBICP(J)	;SETUP LOW CORE CHANNEL WORD
	MOVE	T2,.USMBF
	MOVEM	T2,(T1)		;SETUP IOWD
	SETZB	T2,1(T1)	;END OF LIST
	XCT	FHXCO1(J)	;CONO FH'N,(T2)
	MOVE	T1,UDBPDN(U)	;PHYSICAL DRIVE NUMBER
	ROT	T1,-2		;POSITION FOR DATAO
	TLO	T1,160		;SECTOR BCD 70, TRACK 0. ILLEGAL ON RM10B
	IOR	T1,KDBICP(J)
	XCT	FHXDOT(J)	;DATAO FH'N,T1 , CAUSE READ INTO MONITOR BUFFER
	MOVEI	T1,^D120000	;SETUP COUNT FOR TIME OUT ON DONE FLAG TEST
FHXCP2:	XCT	FHXCI1(J)	;CONI FH'N,T1
	TRNE	T2,1B31		;BUSY STILL UP?
	SOJG	T1,FHXCP2	;YES, TRY AGAIN
	TRNN	T2,1B32		;NO, DONE UP?
	SOJG	T1,FHXCP2	;NO, TRY AGAIN
	TDNN	T2,[1377,,170220]	;YES. ANY ERRORS?
	JUMPG	T1,FHXCP6	;NO. IT'S THERE IF DIDNT TIME OUT
	MOVEI	T1,FHALCL
	XCT	FHXCOT(J)
	SOJG	T3,FHXCP1	;TRY AGAIN
	JRST	FHXCL1		;COUNT EXPIRED & NO DONE FLAG -OFF-LINE RETURN
FHXCP5:	MOVE	T1,UDBPDN(U)	;PHYSICAL DRIVE NUMBER
	ROT	T1,-2		;POSITION IT
	TLO	T1,177777	;ILLEGAL ADR SO DSK WON'T DO IO
	XCT	FHXDOT(J)	;CONNECT CONTROL TO RIGHT UNIT
	XCT	FHXCI1(J)	;READ UNIT STATUS (DRIVE TYPE)
FHXCP6:	MOVEI	T4,0		;ASSUME IT'S AN RD10
	TLNE	T2,(1B4)	;IS IT AN RD10?
	MOVEI	T4,1		;NO, AN RM10B
	HRRZ	T2,CAPDAT(T4)	;GET # BLOCKS ON UNIT
	MOVE	W,CAPDAT(T4)	;GET # BLOCKS PER TRACK
	MOVEI	T3,0		;NO COMPATABILITY MODE
	AOS	0(P)		;SKIP RETURN AFTER FHXCL1
FHXCL1:	MOVEI	T1,FHALCL
	XCT	FHXCOT(J)
	MOVE	T1,T2		;RESTORE # BLOCKS ON UNIT
	POPJ	P,

CAPDAT:	XWD	^D20,^D4000	;RD-10 DATA
	XWD	^D30,^D2700	;RM-10B DATA
	$INIT

;CHECK TO SEE IF KONTROLLER IS UP
FHXUPA:	MOVEI	T1,FHALCL+DSKCHN## ;CLEAR ALL ERROR FLAGS
	XCT	FHXCOT(J)	;CONO FH'X,(T1)
	XCT	FHXCI1(J)	;CONI FH'X,T2
	TRNN	T2,1B23!1B31!1B32 ;ANYTHING WRONG
	TRNN	T2,7		;ARE THE PI BITS THERE?
	POPJ	P,		;YES - ERROR RETURN
	JRST	CPOPJ1##	;OK RETURN

	$HIGH
;SUBROUTINE TO STOP UNIT AND CLEAR BUSY
FHXSTP::XCT	FHXCI1(J)	;DO CONI, DATAI
	XCT	FHXDI2(J)
	MOVEI	T1,20		;TRY TO CLEAR BUSY
	XCT	FHXCOT(J)
	PUSH	P,T2
	XCT	FHXCI1(J)
	TRNN	T2,20		;DID IT CLEAR ?
	AOS	-1(P)		;YES, SKIP
	PJRST	T2POPJ##	;RESTORE CONI AND RETURN
FHXRCL::POPJ	P,		;RECALIBRATE GIVES ERROR RETURN
	LIT

FHXEND:	END