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