	.IF	LIST8
	.LIST
	.PAGE
	.ELSE
	.NOLIST
	.ENDC
;****************************************************************************
;
;	Floppy Disk Driver Routines.
;
;	File:	SAGE.BIOS8.TEXT
;	Date:	20-Sep-83
;	Issue:	2A
;
;
;	COPYRIGHT (c) 1982, 1983 SAGE Computer Technology
;	All Rights Reserved
;
;****************************************************************************
;
;	History:
;
;	1     13-Jun-82 Initial release.
;	1A     9-Dec-82 Massive changes to motor control.
;	2     23-Mar-83 Initial SAGE IV release.
;	2A    20-Sep-83 Set waiting for up to speed flag.
;
;****************************************************************************


.PAGE
;****************************************************************************
;
;	Turn Motor On (Foreground routine)
;
;	On Entry:
;	  A4 is pointer to base of drive information.
;
;	Registers modified: D0, A0
;
;****************************************************************************

MOTORON
	MOVE.L	A5,-(A7)	;Save working register
	LEA	FI_DRVMT,A0	;Set up motor control area address
	MOVE.B	FI_MOTOR(A0),D0
	BNE.S	$80		;Motor was already on
	MOVE.B	#0AH,F8255	;Turn on 'both drives on' signal

;	Now schedule motor up to speed delay
$60	CLR.L	D0		;Set up 300 millisecond delay
	MOVE.W	FI_MODLY(A4),D0
	MOVE.L	D0,8(A0)
	LEA	TOMOTON,A5	;Set up timeout address
	MOVE.L	A5,4(A0)
	BSR	ESCHED		;Enter the turn on schedule
	MOVE.B	#1,FI_MOTOR(A0) ;Set Waiting for up to speed flag
$70	MOVEA.L (A7)+,A5	;Restore working register
	RTS

;	Motor was already on
$80	CMPI.B	#4,D0
	BNE.S	$70		;Not awaiting turn off
	MOVE.B	#2,FI_MOTOR(A0) ;Make motor active
	BSR	CSCHED		;Cancel motor off delay
	BRA.S	$70

.PAGE
;****************************************************************************
;
;	Select a Drive (Foreground routine)
;
;	On Entry:
;	  A4 is pointer to base of drive information.
;
;	Registers modified: D0, A0
;
;****************************************************************************

SELECT
	LEA	FI_DRVMT,A0	;Address motor control
	MOVE.L	FI_HIST(A0),D0
	LSR.L	#8,D0		;Shift previous entries over
	MOVE.L	D0,FI_HIST(A0)
	BSR	RD1SEC		;Get one second clock value
	SUB.W	FI_LASTT(A0),D0
	CMPI.W	#2,D0		;Split into 4 categories
	BLS.S	$10		; <= 2 seconds
	CMPI.W	#10.,D0
	BLS.S	$20		; <= 10 seconds
	CMPI.W	#30.,D0
	BLS.S	$30		; <= 30 seconds
	MOVEQ	#4,D0		;Type 4 for > 30 seconds
	BRA.S	$40
$10	MOVEQ	#1,D0		;Type 1 for <= 2 seconds
	BRA.S	$40
$20	MOVEQ	#2,D0		;Type 2 for <= 10 seconds
	BRA.S	$40
$30	MOVEQ	#3,D0		;Type 3 for <= 30 seconds
$40	MOVE.B	D0,FI_HIST(A0)	;Store new access time code

	BSR	MOTORON		;Turn on motor
$80	MOVEQ	#6,D0		;Set up select for drive 0
	TST.B	FI_DRV(A4)
	BEQ.S	$90		;Was drive 0
	ADDQ.B	#2,D0		;Change to select for drive 1
$90	MOVE.B	D0,F8255
	MOVE.B	#1,FI_SEL(A4)
$100	RTS

.PAGE
;****************************************************************************
;
;	Deselect a Drive (Foreground routine)
;
;	On Entry:
;	  A4 is pointer to base of drive information.
;
;	Registers modified: D0, A0
;
;****************************************************************************

DESELECT
	MOVEQ	#7,D0		;Set up deselect for drive 0
	TST.B	FI_DRV(A4)
	BEQ.S	$5		;Was drive 0
	ADDQ.B	#2,D0
$5	MOVE.B	D0,F8255
	CLR.B	FI_SEL(A4)
	BSR	RD1SEC		;Save one second count
	LEA	FI_DRVMT,A0	;Address motor control
	MOVE.W	D0,FI_LASTT(A0)
	MOVEM.L D1/A1,-(A7)	;Save registers D1, A1
	MOVE.B	FI_MOTOR(A0),D0 ;Check if already scheduled
	ANDI.B	#5,D0
	BEQ.S	$10		;Not scheduled
	BSR	CSCHED		;Cancel previous schedule
$10	LEA	TOMOTOFF,A1	;Set up routine address
	MOVE.L	A1,4(A0)	;  for timeout
	CLR.L	D0
	MOVE.L	FI_HIST(A0),D1
	MOVE.B	D1,D0		;Fourth back * 1
	LSR.L	#7,D1
	ADD.B	D1,D0		;Third back * 2
	LSR.L	#8,D1
	ADD.B	D1,D0
	LSR.L	#1,D0
	ADD.B	D1,D0		;Second back * 3
	LSR.W	#6,D1
	ADD.B	D1,D0		;First back *4
	CMPI.B	#20.,D0		;Check total of weighted scores
	BLS.S	$20		; <= 20.
	CMPI.B	#30.,D0
	BLS.S	$30		; <= 30.
	MOVEQ	#2,D0		; > 30. give 2 seconds
	BRA.S	$40
$20	MOVEQ	#10.,D0		; <= 20 give 10 seconds
	BRA.S	$40
$30	MOVEQ	#30.,D0		; <= 30 give 30 seconds
$40	SWAP	D0		;Make into seconds count
	MOVE.L	D0,8(A0)	;Save relative timeout time in entry
	BSR	ESCHED		;Enter the schedule
	MOVEM.L (A7)+,D1/A1	;Restore A1, D1
	MOVE.B	#4,FI_MOTOR(A0) ;Set up code for waiting to turn motor off
	RTS

.PAGE
;****************************************************************************
;
;	Motor Off Schedule Timeout
;
;	Registers modified: D0, A0
;
;****************************************************************************

TOMOTOFF
	LEA	FI_DRVMT,A0	;Address motor control
	MOVE.B	#0BH,F8255	;Turn off motors
	CLR.B	FI_MOTOR(A0)
	RTS



;****************************************************************************
;
;	Motor On Schedule Timeout
;
;	Registers modified: D0
;
;****************************************************************************

TOMOTON
	MOVE.B	#2,FI_MOTOR(A2) ;Indicate drive is active
	TST.B	FI_STREQ(A2)
	BEQ.S	$10		;Don't start now
	CLR.B	FI_STREQ(A2)	;Clear startup request
	BSET	#FGFLOP_B,FGTASKS+1 ;Set up floppy foreground flag
$10	RTS

                                                                                                                                                                                                                                                                                                                                                                                        