	.TITLE	SAVHD - BOOT/SAVE HD DRIVER
	.IDENT	/01.00/

	.MCALL	HWDDF$
	HWDDF$			;DEFINE HARDWARE DEFINITIONS

;
; HD DISK CONTROLLER REGISTERS
;
HDCS	=	0		;CONTROL STATUS
HDDA	=	2		;DATA REGISTER

CSUNI	=	1		;SET UNIT FUNCTION
CSBLK	=	2		;SET BLOCK NUMBER FUNCTION
CSBUF	=	3		;SET BUFFER ADDRESS FUNCTION
CSWCT	=	4		;SET WORD COUNT FUNCTION
CSRLB	=	5		;READ LOGICAL BLOCK FUNCTION
CSWLB	=	6		;WRITE LOGICAL BLOCK FUNCTION

BLKLEN	=	4.		; BLOCKS TO READ TO GET 1024. WORDS

;
; DEVICE AND DRIVER TABLES
; FORMAT:
;	WORD 1	- DEVICE MNEMONIC IN ASCII
;	WORD 2	- DRIVER SET UP ROUTINE CODE FOR BOOT
;	WORD 3	- DRIVER SET UP ROUTINE CODE FOR SAVE
;	WORD 4	- LOAD LENGTH STORAGE AREA
;	WORD 5	- BUFFER ADDRESS FOR I/O
;	WORD 6	- FUNCTION CODE STORAGE AREA
;	WORD 7	- DRIVER ADDRESS
;	WORD 8	- DRIVER LENGTH IN WORDS
;	WORD 9	- WRITE FUNCTION CODE
;	WORD 10	- READ FUNCTION CODE
;	WORD 11	- UNIT SELECTION
;	WORD 12	- UNIT SELECTION REGISTER ADDRESS
;	WORD 13	- ADDRESS OF CSR ADDRESS SAVE AREA
;	WORD 14	- LAST PART OF SEGMENT NAME IN RAD50
;

	.PSECT	DRVTAB,RW,D,GBL,REL,CON

	.ASCII	/HD/		; DISK DRIVE HD
	.WORD	$SETHD		;
	.WORD	$SETHD
	.WORD	HDLLEN		;
	.WORD	HDSA		;
	.WORD	HDFUN		;
	.WORD	$HDDRV		;
	.WORD	<HDEND-$HDDRV>/2;
	.WORD	CSWLB		;
	.WORD	CSRLB		;
	.WORD	0		;
	.WORD	HDFUN		;
	.WORD	HDCSR		;
	.RAD50	/HD /		;


$HDDRV::
	MOV	(PC)+,R5	;;; GET CSR ADDRESS
HDCSR:	.WORD	0		;;;
	CMP	#7,R4		;;; XXX
	BHIS	10$		;;; XXX
	MOV	R0,R4		;;; SAVE HW ROM UNIT
10$:	CMPB	HDFUN+1,#-1	;;; UNIT SPECIFIED?
	BEQ	20$		;;; NO
	MOVB	HDFUN+1,R4	;;; SELECT
20$:	MOV	R4,HDDA(R5)	;;;
	MOVB	#CSUNI,@R5	;;;
;	TST	@R5		;;; UNIT FAILED?
;	BMI	HDEXIT		;;; YES
	MOV	@#6,R2		;;; GET STARTING BLOCK NUMBER
	MOV	#0,R0		;;; GET LOAD LENGTH
HDLLEN =	.-2		;;;
30$:	MOV	R2,HDDA(R5)	;;; SET BLOCK NUMBER
	MOV	#CSBLK,@R5	;;;
;	TST	@R5		;;; OUT OF FRIVE?
;	BMI	HDEXIT		;;; YES
	MOV	#0,HDDA(R5)	;;; SET BUFFER ADDRESS
HDSA	=	.-4		;;;
	MOV	#CSBUF,@R5	;;;
	SUB	#BLKLEN,R0	;;; FULL BLOCK LEFT?
	BPL	40$		;;; YES
	ADD	#BLKLEN,R0	;;; NO, COMPUTE RESIDUAL COUNT
	BLE	HDEXIT		;;; DONE
	MOV	R0,R1		;;; COPY COUNT
	CLR	R0		;;; ZERO RESIDUAL COUNT
	BR	50$		;;;
40$:	MOV	#BLKLEN,R1	;;; SET TO READ BLKLEN*256. WORDS
50$:	ADD	R1,R2		;;; UPDATE BLOCK NUMBER
	SWAB	R1		;;; MULTIPLY BLOCK COUNT BY 256 WORDS
	MOV	R1,HDDA(R5)	;;; SET WORD COUNT
	MOV	#CSWCT,@R5	;;;
;	TST	@R5		;;; OUT OF DRIVE?
;	BMI	HDEXIT		;;; YES
	MOVB	#0,R3		;;; GET FUNCTION CODE
HDFUN	=	.-2		;;;
	MOV	R3,@R5		;;; START I/O OPERATION
	ASL	R1		;;;
	ADD	R1,HDSA		;;;
	TST	@R5		;;; I/O ERROR?
	BPL	30$		;;; NO
HDEXIT:
HDEND:	RETURN			;;; END OF DRIVER

;+
; DRIVER SET CODE TO MOVE THE DRIVER TO THE CORRECT BLOCK.  THIS CODE
; IS CALLED FROM SAVE.
;-
$SETHD::
	MOVB	$SVUNT,R4	; GET UNIT SELECT
	BIC	#177400,R4	; CLEAR HIGH BITS
	MOV	R4,$DVDRV+DRVUNT(R5)	; SET UNIT SELECT
	RETURN			; RETURN TO INSTRUCTION FOLLOWING
				; CALL IN SAVE

	.END
                                                                                                   