Interface

.Page
;++
;		Interface Routines
;--

SelSide	.Equ *
	Ldx	#0
	Lda	#20
	Bit	IIob+Side
	Beq	SetSel
	Inx

SetSel	.Equ *
	Lda	Ca0+High
	Lda	Ca1+High
	Lda	Side0Sel,x
	Txa
	Rts

SetLow	.Equ *
	Ldx	#Low			; set Side Select line low
	Beq	SetSel

SetHigh	.Equ *
	Ldx	#High			; Set line high
	Bne	SetSel

ReadWp	.Equ *
	Jsr	SetHigh
RdS2	Lda	Ca1+Low
RdS1	Lda	Ca2+Low
ReadIt	.Equ *				; Read sense bit & rotate into ccC
	Lda	Q6H			; Ensure state machine in proper state
	Lda	Q7L			; Read sense daata into bit 7
	Asl	A			; Move bit 7 into carry
	Rts

ReadIndx	.Equ *
	Clc
Rid	.Equ *
	Jsr	SetHigh
	Lda	Ca0+Low
	Bcc	RdS1			; set Ca2 = 0
	Bcs	RdS2			; set Ca1 & Ca2 = 0

ReadDip	.Equ *
	Sec
	Bcs	Rid

DoStrb	.Equ *
	Sta	LStrb+High
	Nop
	Nop
	Sta	LStrb+Low
	Rts

TrMtOff	.Equ *				; Will turn motors off
	Sta	Ca2+High
	Lda	#00
	Beq	TurnMtr

TrMtrOn	.Equ *				; Will turn the Sony motor on
	Sta	Ca2+Low
	Lda	#0FF

TurnMtr	.Equ *
	Sta	MtrOn			; Set state register in Ram
	Jsr	SetLow			; Set side select line low
	Sta	Ca0+Low
	Jmp	DoStrb

TMOn	.Equ *				; Turn on motor & setup for tach reading
	Jsr	TrnMtrOn			; will leave Ca0 = 0
	Lda	#80.			; 400(5*80) msec constant
	Jsr	Wait
SetTach	.Equ *
	Jsr	SetHigh			; set Side Select = 1 for Tach input
	Lda	Ca2+Low			; '10011' for tach mode
	Rts

SetDrexX	.Equ *				; use value in Xreg for direction
	Stx	Direct
SetDrct	.Equ *
	Jsr	SetLow			; set Side Select line low
	Sta	Ca0+Low
	Sta	Ca1+Low
	Ldx	Direct			; 0 or 1 for offset of direction
	Sta	Ca2,x
	Jmp	DoStrb

DoStep	.Equ *
	Lda	#1
	Sta	Temp1			; Try twice
	Jsr	SetLow			; Set Side Select line low
	Sta	Ca1+Low
	Sta	Ca2+Low
	Jsr	DoStrb
$10	Jsr	WaitAlt			; Wait 12 ms for /Step to go high
	Jsr	ReadIt			; ccC = /Step -- 0 = low & 1 = high
	Bcs	DoStDone			; /Step is high so all is cool
	Lda	#StepErr
	Sta	Iob+SeekErr		; For external debugging aid ( FCC01B )
	Dec	Temp1
	Bpl	$10			; wait another 12 ms
DoStDone	.Equ *				; fall through and exit w no error
	Rts

DoSeek	.Equ *
	Jsr	SetDrct			; Set the direction
$23	Jsr	DoStep
	Dec	StpAmt			; Count down the number of steps to take
	Bne	$23			; Exit upon reaching zero
	Rts

SetSpeed	.Equ *
	Jsr	TrkClss			; Return w/ "Y" = class of IIob+Track
SetSpdy	.Equ *				; already has "y" = track class
	Sty	CurClass
	Lda	MSpdTbl,y
	Sta	PwmReg
	Rts

SetRMode	.Equ *
	Jsr	SelSide			; use value in IIob+Side to set proper side
	Sta	Ca0+Low
	Sta	Ca1+Low
	Sta	Ca2+High			; 'x100' is input to MCI PAL on Sony
	Rts

UnClamp	.Equ *
	Jsr	SetLow
	Sta	Ca2+High			; '0111'
	Lda	LStrb+High
	Lda	#150.			; 3/4 sec (200*5 usec ) delay for ejection
	Jsr	Wait			; Will wait & return w/ carry cleared
	Lda	LStrb+Low
	Lda	#0
	Sta	Clamped			; Tell me disk is no longer clamped
	Clc
	Rts

HardInit	.Equ *				; Initialize hardware -- PWM & Iwm
	Ldx	#0e	
$7	Sta	IOSpace,x			; Reset all IWM internal latches to zero state
	Dex	
	Dex
	Bpl	$7			; Loop 8 times
	Lda	#202.
	Jsr	Wait			; wait for 1.01 sec for timer to expire

	Ldx	#0			; $10000 times before timeout
	Stx	Temp1

$15	Dex	
	Bne	$30
	Dec	Temp1
	Beq	HardAbort			; If timeout then IWM is out to lunch

$30	Lda	Q6H			; Put IWM state machine into SENSE mode
	Lda	Q7L			; Read status data
	Tay				; Save IWM's status information
	And	#20			; Test bit #5
	Bne	$15			; Wait for bit #5 to be clear ( 0 )

	Tya				; Restore status info
	And	#IWMMode			; Mask off unneeded bits

	Cmp	#IWMMode			; look for proper bits to be set
	Beq	$45			; if same then all is OK


	Lda	#IWMMode			; Asynch, 8 MHz, latch, 2 usec calls, no timer
	Sta	Q7H			; Setup to proper Sony mode
	Lda	Q7L			; back to SENSE mode
	Jmp	$15			; Walk through & make sure it works

$45	Sta	DrEna+High		; Select drive 1
	Sta	MtEna+On			; Now enable that drive for ever and ever
	Ldx	MSpdTbl			; Default speed code for track 0
	Stx	CntEna+Low		; Enable counter/comparator
	Stx	PWMReg			
	Stx	PwmEna+High		; Enable output of Pwm pulse
	Rts

HardAbort	.Equ *
	Lda	#IWMError			; Fatal error w/ IWM -- does not respond
	Sta	Iob+ErrStat
	Jmp	FatalErr			; Abort and never return

ChkDrv	.Equ *				; Check for drive connected and number of sides
	Lda	#1
	Sta	Iob+NoSides		; Assume single sided drive
	Jsr	SetLow			
	Sta	Ca2+High			; '0111'
	Sec				; Assume no drive exists
	Lda	Q7L			; High bit = status
	Bmi	$30			; If bit7 = 1 then no drive is connected
	Dec	DrvConn			; Set drive connected flag
	Clc	
	Sta	Ca0+Low			; Assume only single sided
	Ldx	Q7L
	Bpl	$23			 
	Inc	Iob+NoSides		; 2 = double sided drive
	Ora	#20			; Set double sided flag for format field
$23	Sta	FmtType			; For use in formatting
$30	Rts				; ccC = 0 ==> drive connected