TODO
-Write boot block loader and load image (packed) from FDC
-Write FDC drivers
+Floppy drive B - set drive info and propogate it
+
+Floppy drive B - set parameters at init time
+
+Petty coloured stripes when reading/writing floppy
+
Move buffers into upper part of bank 7 to see if can get kernel below
C000 + E000 upwards to get bigger user image ?
in bottom of that chunk.
Would give direct mapped video
-
-
-FDC
-
-Reuse amstradnc code
-
-How to twiddle tc ?? - do we in fact even have that ability ? looks like
-we instead have to discard or stuff bytes if sector size mismatched
-
-add delays
-
-Use the jp p and other tricks to make timing on the spectrum
-for r/w loops
-
-Ensure we have the correct head settle on a seek
-
-motor on needs big delay loop but can be done without di on (yay!)
-
-motor off is software
.globl _fd765_sectors
.globl _fd765_disc
+ .globl _vborder
.globl diskmotor
; Waits for a SEEK or RECALIBRATE command to finish by polling SENSE INTERRUPT STATUS.
wait_for_seek_ending:
+ ld a,#0x05
+ out (0xFE),a
+
ld a, #0x08 ; SENSE INTERRUPT STATUS
call fd765_tx
call fd765_read_status
bit 5, a ; SE, seek end
jr z, wait_for_seek_ending
+ ld a, #0x02
+ out (0xFE),a
+
; Now settle the head (FIXME: what is the right value ?)
ld a, #30 ; 30ms
;
dec a
jr nz, wait_ms_loop
pop bc
+ ld a,(_vborder)
+ out (0xFE),a
ret
_fd765_motor_off:
push af
call nz, map_process_always
+ ld a,#0x05
+ out (0xFE),a
+
di ; performance critical,
; run with interrupts off
xor a
- call fd765_tx ; send the final unused 0 byte
+ call fd765_tx ; send the final unused byte
; to fire off the command
ld hl, (_fd765_buffer)
ld bc, #0x2ffd
ei
call fd765_read_status
+ call tc_fix
+
+ ld a,(_vborder)
+ out (0xFE),a
pop af
ret z
jp map_kernel
+;
+; We will get an error reported that the command did not complete
+; because the tc bit is not controllable. Spot that specific error
+; and ignore it.
+;
+tc_fix:
+ ld hl,#_fd765_status
+ ld a,(hl)
+ and #0xC0
+ cp #0x40
+ ret nz
+ inc hl
+ bit 7,(hl)
+ ret z
+ res 7,(hl)
+ dec hl
+ res 6,(hl)
+ ret
+
;
; Write is much like read just the other direction
;
_fd765_do_write:
- di ; performance critical, run with
; interrupts off
ld a, #0x45 ; WRITE SECTOR MFM
call setup_read_or_write
push af
call nz, map_process_always
+ ld a,#0x05
+ out (0xFE),a
+
+ di
+
xor a
call fd765_tx ; send the final unused 0 byte
; to fire off the command
call _fd765_do_nudge_tc ; Tell FDC we've finished
ei
call fd765_read_status
+ call tc_fix
+
+ ld a,(_vborder)
+ out (0xFE),a
pop af
ret z
add b ; add first sector
dec a ; 6: last sector (*inclusive*)
call fd765_tx
- ld a, #27 ; 7: Gap 3 length (27 is standard for 3.5" drives)
+ ld a, #0x2A ; 7: Gap 3 length (2A is standard for 3" drives)
call fd765_tx
; We return with the final unused 0 value not written. We need all
; the other stuff lined up before we write this.