updates to floppy code

This commit is contained in:
FeralChild64 committed 2021-08-23 19:20:38 +02:00
1 parent 9b57b0c656
commit d91f7916c0
2 files changed
+51 -117

No files matched your search

@@ -1,84 +0,0 @@
; Helper routines for low-level disk operations
lowlevel_fd_ensure_presence_refresh:
jsr lowlevel_fd_wait_clr_BUSY ; to be extra sure
; XXX stepping head is definitely needed, but probably still not enough
; lda #%00011000 ; step head 1 track in (XXX: check if it is really in)
; sta FDC_COMMAND ; $D081
; jsr lowlevel_fd_wait_clr_BUSY
; lda #%00010000 ; step head 1 track out (XXX: check if it is really out)
; sta FDC_COMMAND ; $D081
; jsr lowlevel_fd_wait_clr_BUSY
; FALLTROUGH
lowlevel_fd_ensure_presence:
lda FDC_STATUS_B ; $D083 ; check if disk is inserted
and #$08
beq @not_present
rts
@not_present:
pla
pla
jsr lowlevel_fd_motor_off ; if disk not present, disable drive motor
; XXX set error code, invalidate buffers, etc.
sec
rts
lowlevel_fd_motor_on:
lda FDC_CONTROL
and #%00100000
bne lowlevel_fd_rts ; if motor already enabled, do nothing
; XXX find out why it is not disabled at all
; lda #%00100000 ; enable drive motor and LED
; tsb FDC_CONTROL ; $D080
; Allow some time for spin-up; according to https://wiki.osdev.org/Floppy_Disk_Controller
; 300 ms should be more than enough
; XXX reenable this
; phx
; ldx #$0F
; jsr wait_x_bars
; plx
bra lowlevel_fd_wait_clr_BUSY
lowlevel_fd_motor_off:
lda #%00100000 ; disable drive motor and LED
trb FDC_CONTROL ; $D080
; FALLTROUGH
lowlevel_fd_wait_clr_BUSY:
bit FDC_STATUS_A ; $D082
bmi lowlevel_fd_wait_clr_BUSY
rts
lowlevel_fd_wait_set_RDREQ:
bit FDC_STATUS_B ; $D083
bpl lowlevel_fd_wait_set_RDREQ
; FALLTROUGH
lowlevel_fd_rts:
rts
+51 -33
View File
@@ -1,5 +1,6 @@
; Read a sector pair from a block device
; Read a sector pair from a block device, flow partially based on:
; - https://github.com/MEGA65/mega65-tools/blob/master/src/tests/floppytest.c
lowlevel_xx_readsector:
@@ -11,48 +12,46 @@ lowlevel_xx_readsector:
lowlevel_fd_readsector:
; Set drive
lda #%00001111 ; set drive 0 (internal) and side 0
trb FDC_CONTROL ; $D080
cpx #$01
beq @1
lda #%00000001 ; if needed, switch to drive 1 (external)
tsb FDC_CONTROL
@1:
; Ensure disk is present
jsr lowlevel_fd_ensure_presence_refresh
; Check if buffer contains data from given track
; XXX compare device and unit too
; Check if buffer contains data from given track, sector, drive
lda PAR_TRACK
cmp BUFTAB_TRACK+1
bne lowlevel_readsector_force
; Check if sectors match
bne lowlevel_fd_readsector_force
lda PAR_SECTOR
and #%11111110
cmp BUFTAB_SECTOR+1
bne lowlevel_readsector_force
bne lowlevel_fd_readsector_force
; XXX compare drive
; Data already loaded into buffer - do nothing
clc
rts
lowlevel_readsector_force:
lowlevel_fd_readsector_force:
jsr lowlevel_fd_motor_on ; enable drive motor and LED
jsr lowlevel_fd_ensure_presence
; Set drive, motor ON
lda #%10000000 ; select floppy buffer
lda #$68
cpx #$01
beq @1
inc
@1:
sta FDC_CONTROL ; $D080
; Select floppy buffer
lda #%10000000
trb SD_BUFCTL ; $D689
; Wait until BUSY flag clears
@2:
lda FDC_STATUS_A ; $D082
bmi @2
; Select physical track and sector based on logical ones from PAR_TRACK and PAR_SECTOR
lda PAR_TRACK
@@ -84,21 +83,30 @@ lowlevel_readsector_force:
inc
sta FDC_SECTOR ; $D085
; Reset buffers
lda #$00
sta FDC_COMMAND ; $D081
; Ask the controller to read the sector XXX how to detect errors, missing disk, etc.?
lda #$40
sta FDC_COMMAND ; $D081
jsr lowlevel_fd_wait_set_RDREQ ; wait till sector is found
jsr lowlevel_fd_wait_clr_BUSY ; wait for BUSY flag to clear
; Wait for busy flag to assert XXX how much? 1 second? most likelly too much...
; Wait for DRQ and EQ flags to go high
ldy #71
@3:
ldx #$00
jsr wait_x_bars
dey
bne @3
@lp1:
; Wait until BUSY flag clears
@4:
lda FDC_STATUS_A ; $D082
and #%01100000
cmp #%01000000 ; XXX is this correct? .A seems to stay at $40 at this point
bne @lp1
bmi @4
; Copy sector to buffer in RAM
@@ -125,3 +133,13 @@ lowlevel_readsector_force:
clc
rts
lowlevel_fd_motor_off:
; XXX set correct drive
lda #$00
sta FDC_CONTROL ; $D080
rts