.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