LOOP

.Page
;++
;
;			RESTART
;
; Restart is the entry point after a reest to the 6504.  This is also reffered
; to as a cold start.  It will first wait for memory to be valid, then it will
; setup the stack, reset the drives, clear all of the used RAM, transfer all
; "soft" parameters from the ROM to the RAM, initialize all timing constants,
; Check for Disk In Place and clamp any disks that are there, raise the DISK
; DIAG line and then finally look for a command.
;
;--
;
; REGISTERS
;  In
;	Random values assumed
;  Out
;	All Destroyed
;++
.Page
;++

Restart	.Equ *				; Main entry point for the 6504 from reset

;	Clear decimal mode;
;	Disable interrupts to the 6504;
;	Switch off interrupt to the 68K;
;	Set stack pointer to 0B0;
;	Enable MEMPOY for 68K

	Cld				; Clear decimal mode
	Sei				; Mask off interrupts
					; Following 3 steps needed only for warm restart
DnWhWt	Sta	BootL			; Tell host I'm not ready yet
	Sta	FDirL			; Set FDir Low, no interrupt yet to the 68K
	Sta	DisL			; Enable 68K to read memory
	Ldx	#StackSt
	Txs				; Set stack to grow down from 01CF
	Jsr	HardInit			; Initialize hardware -- PWM, IWM, Latches
	Jsr	RomTest			; Will never return if error is found
	Jsr	RamTest			; currently an Rts
	Lda	#00
	Jsr	Wait			; Wait for Sony to power up -- about 1.25 second

;	For x:=#LstUsed DOWNTO 000 DO			Reset variable memory for 6504
;	   Mmemory,x := 000;			This resets all counters to 000

	Ldx	#LstUsed			; Length of variable area
	Lda	#00			; something to clear with
Restart1	Sta	GoByte,x			; Init to 0
	Dex
	Bne	Restart1
	Sta	GoByte			; and do the last/first byte

;	For x:=sharesz down to 0 do			Initialize shared variables
;	   ShareRam,x := ShareRom,x;

	Ldx	#SharesZ			; Length of shared variable space
Restart2	Lda	ShareRom,X		; Move Bytes from Rom
	Sta	ShareRam,X		; and into RAM
	Dex				; Next Byte
	Bpl	Restart2			; Done yet?

	Ldx	#4			; move 5 bytes, zero based
Xfer1	Lda	SavAdr,x
	Sta	AdrMk1,x			; initialize Address mark table
	Lda	SavDat,x
	Sta	DatMk1,x			; initialize Data mark table
	Dex
	Bpl	Xfer1

	Dec	KOff
	Ldx	#CmdLength
	Stx	CmdX			; Index for command saving
	Ldx	#SavIndex
	Stx	SaveL

	Lda	MaxDDly
	Sta	WtHih
	Bne	Loop1			; Must see if a disk is inserted

;	*** NOTE *** Loop must be the very next routine
.Page

;++
;
;			LOOP
;
; This is the main 'idle' loop where the 6504 spends most of its time when not
; doing anything useful.  The main functions of the 'LOOP' is to shut off the
; motors after they have been used, sample the DIP and BUTTON when needed,
; and look for commands from the 68K.
;
; REGISTERS
;  In
;	A =	Any value
;	X =	Any value
;	Y =	Any value
;  Out
;	Loop never exits, only calls other procedures
;
; CALLS
;	GetDIP	Get the DIP status
;	Trnrk	Park the heads and turn off the motors
;	Cmd	Interprets, syntax checks, and dispatches all commands
;
;++
.Page

;++
;	Decrement 3 byte counter.  When all 3 bytes = 0 then turn motors off
;	( even if they are already off ), & look for disk in place
;--

Loop	.Equ *			; Start of main loop
	Inc	ImAlive
	Dec	WtLow		; Decremnent low byte of motor off wait
	Bne	Loop2
	Dec	WtMid		; Decrement Middle byte
	Bne	Loop2
Loop1	.Equ *			; Entry point for immediate check of DIP
	Jsr	GetDIP		; Time to make some noise and get some status
	Dec	WtHih		; Decrement high byte
	Bne	Loop2
	Jsr	TrMtOff		; turn off motor and reset motor on flag to zero
	Lda	MaxDDly
	Sta	WithHih

Loop2	Lda	Iob+GoByte
	Bpl	Loop
	Jsr	Cmd		; Try to execute the command
	Jmp	Loop		; Go back to the loop ands spin some more

.Page
;++
;		ROMTest
;--

RomTest	.Equ *			; Entry point to test checksum of Eprom
	Rts
	Lda	#0
	Tay
	Sta	RangeL
	Sta	RangeH
	Sta	InxPtrL
	Lda	#10
	Sta	InxPtrH
	Tax
$21	Clc
	Iny			; y = +1
	Lda	RangeL
	Adc	@InxPtr,y		; This should be (InxPtr),y   ARS 12 JAN 89
	Sta	RangeL
	Dey			; y = +0
	Lda	RangeH
	Adc	@InxPtr,y
	Sta	RangeH
	Clc
	Bpl	$43
	Sec
$43	Rol	RangeH
	Rol	RangeH
	Iny
	Iny			; Y = +2
	Bne	$21
	Lda	RangeL
	Bne	RomErr
	Lda	RangeH
	Beq	RamTest
RomErr	Sta	Iob+DrvError
	Sta	DisL		; Enable 68K to read memory
	Sta	BootH		; And reset flag line also
	Jmp	ProgErr1		; Bad Eprom -- tell host & loop forever

RamTest	.Equ *			; Test for bar Ram
	Rts

;++
;
;			GetDIP
;
; REGISTERS
;
;	All are destroyed
;
; CALLS
;	UpdInt	Updates interrupt status and raises FDir if needed
;	ReadDIP	Read DIP status
;	EnblTest	Test IMsk	against x-reg if drive is enabled
; Note:
;	Should code ever get modified for a two drive system, this should
; be re-written to alow commands to be received during the one second wait
;++
.Page

GetDIP	.Equ *				; Entry point for GetDIP
	Lda	DrvConn
	Bne	$40			; if <> 0 then drive is connected
	Jsr	ChkDrv			; check for drive connected & number of sides
	Bcs	GetDip5			; Exit if still no drive connected
$40	Sta	BootL			; Set flag to tell host I'm busy
	Jsr	ReadDIP			; Read the status of the DIP into carry
	Bcs	GetDIP4			; ccC = 1 ==> no DIP -- clear Clamped Disk Flag
	Lda	Clamped			; Already a clamped disk?
	Bne	GetDIP5			; No, need to clamp if not already clamped

	Lda	#OneSec			; One second wait constant
	Jsr	Wait			; Wait for Sony drive to return to it's senses
	Jsr	ReCalMtr			; Turn on motor & make sure head is at track 0
	Dec	Clamped			; Set clamped falg to 'FF'

	Jsr	EnablTest			; If drive enabled then tell host disk inserted
	Bcc	GetDIP5			; If carry set then disk enabled

	Lda	#010			; use drive 80
GetDIP2	Ora	Ist			; Combine with current Ist
	Sta	Ist
	Bne	GetDIP5

GetDIP3	.Equ *

GetDip4	Lda	#00
	Sta	Clamped			; Tell me no disk is clamped

GetDIP5	.Equ *				; Fall through and test for button pressed
	Sta	BootH			; Clear busy flag to host
					; Fall thru & update interrupt to host ( maybe )

.Page

UpdInt	.Equ *				; Entry point for UpdInt

; Ist.7 := Ist.6 or Ist.5 or Ist.4;

	Lda	Ist
	And	#070
	Beq	UpdInt2			; Skip if none is on
	Ora	#080			; Set bit 7 if any bit is on
	Sta	Ist			; And put back into Ist

; if (Ist.7 and Imsk.7) then
;    FDir := High
; Else
;    FDir := Low
; Return from UpdInt

UpdInt2	And	Imsk			; Now test against the mask
	Sta	OkToGo			; Remember if an interrupt is pending
	Beq	UpdInt3			; Skip if no interrupt is pending
	Sta	FDirH			; Raise interrupt
	Rts
UpdInt3	Sta	FDirL			; Clear interrupt
	Rts