From: Alan Cox Date: Mon, 3 Dec 2018 14:57:19 +0000 (+0000) Subject: fdc765, zx+3: Now working on the +3 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=298cb0f1ca4167297c62ae91244cd1cc23cb8427;p=FUZIX.git fdc765, zx+3: Now working on the +3 - Fix assorted bugs - Add drive B support - Hack for single sided media for now (need to address properly with disk ioctls) --- diff --git a/Kernel/dev/devfdc765.c b/Kernel/dev/devfdc765.c index 70264f08..2ef9e4b3 100644 --- a/Kernel/dev/devfdc765.c +++ b/Kernel/dev/devfdc765.c @@ -10,19 +10,26 @@ #include #include #include -#include +#include static timer_t spindown_timer, recal_timer; +static uint8_t lastdrive; +static uint8_t trackpos[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + int devfd_open(uint8_t minor, uint16_t flag) { flag; - if(minor != 0) { + if(minor > FDC765_MAX_FLOPPY) { udata.u_error = ENODEV; return -1; } + fd765_do_nudge_tc(); - fd765_track = 0xff; /* not on a known track */ + + trackpos[minor] = 0xFF; + if (minor == lastdrive) + fd765_track = 0xff; /* not on a known track */ return 0; } @@ -67,40 +74,56 @@ static uint8_t fd_recalibrate(void) return 1; } -/* Set up the controller for a given block, seek, and wait for spinup. */ -static void fd_seek(uint16_t lba) +/* Set up the controller for a given block, seek, and wait for it. + By the time we are called the motor is assumed to be at speed */ + +static uint8_t fd_seek(uint16_t lba) { + uint8_t i = 0; + /* Hack for the moment until we introduce the proper floppy ioctls + here and in the platform code */ +#ifdef CONFIG_FDC765_DS uint8_t track2 = lba / 9; uint8_t newtrack = track2 >> 1; fd765_sector = (lba % 9) + 1; fd765_head = track2 & 1; +#else + uint8_t newtrack = lba / 9; + fd765_sector = (lba % 9) + 1; + fd765_head = 0; +#endif if (newtrack != fd765_track) { - for (;;) - { + while (i++ < 5) { fd765_track = newtrack; nudge_timer(); fd765_do_seek(); if ((fd765_status[0] & 0xf8) == 0x20) - break; - - fd_recalibrate(); + return 0; + if (i != 5) + fd_recalibrate(); } + return 1; } + return 0; } /* Select a drive and ensure the motor is on. */ static void fd_select(int minor) { - (void)minor; - + if (lastdrive != minor) { + trackpos[lastdrive] = fd765_track; + fd765_track = trackpos[minor]; + lastdrive = minor; + } + fd765_drive = minor; fd765_motor_on(); nudge_timer(); } -static int devfd_transfer(bool is_read, uint8_t is_raw) +static int devfd_transfer(uint8_t minor, bool is_read, uint8_t is_raw) { int ct = 0; int tries; @@ -118,7 +141,7 @@ static int devfd_transfer(bool is_read, uint8_t is_raw) // if (!is_read) // return blocks << BLKSHIFT; - fd_select(0); + fd_select(minor); fd765_is_user = is_raw; fd765_buffer = udata.u_dptr; @@ -133,7 +156,9 @@ static int devfd_transfer(bool is_read, uint8_t is_raw) if (fd_recalibrate()) continue; } - fd_seek(lba); + /* Seek failed - no point trying the I/O again */ + if (fd_seek(lba)) + continue; /* Not all machines can make the timing for this, or have real controllers that can do it */ @@ -156,7 +181,8 @@ static int devfd_transfer(bool is_read, uint8_t is_raw) if (tries == 3) { /* FIXME: will be the drive num once we fix that */ - kprintf("fd%d: I/O error %d:%d - %d\n", 0, is_read, lba, fd765_status[0]); + kprintf("fd%d: I/O error %d:%d - %d:%d\n", minor , is_read, lba, + fd765_status[0], fd765_status[1]); udata.u_error = EIO; break; } @@ -171,12 +197,12 @@ static int devfd_transfer(bool is_read, uint8_t is_raw) int devfd_read(uint8_t minor, uint8_t is_raw, uint8_t flag) { flag;minor; - return devfd_transfer(true, is_raw); + return devfd_transfer(minor, true, is_raw); } int devfd_write(uint8_t minor, uint8_t is_raw, uint8_t flag) { flag;minor; - return devfd_transfer(false, is_raw); + return devfd_transfer(minor, false, is_raw); } diff --git a/Kernel/dev/devfdc765.h b/Kernel/dev/devfdc765.h index 7b4e710b..cf5afcf1 100644 --- a/Kernel/dev/devfdc765.h +++ b/Kernel/dev/devfdc765.h @@ -23,6 +23,7 @@ extern uint8_t fd765_sector; extern uint8_t fd765_status[8]; extern uint8_t* fd765_buffer; extern uint8_t fd765_sectors; -extern bool fd765_is_user; +extern uint8_t fd765_drive; +extern uint8_t fd765_is_user; #endif /* __DEVFDC765_DOT_H__ */ diff --git a/Kernel/platform-zx+3/fdc765.s b/Kernel/platform-zx+3/fdc765.s index 5c289954..f1108174 100644 --- a/Kernel/platform-zx+3/fdc765.s +++ b/Kernel/platform-zx+3/fdc765.s @@ -52,9 +52,9 @@ .globl _fd765_buffer .globl _fd765_is_user .globl _fd765_sectors - .globl _fd765_disc + .globl _fd765_drive - .globl _vborder + .globl _vtborder .globl diskmotor @@ -117,13 +117,13 @@ _fd765_status: .ds 8 ; 8 bytes of status data ; Sends the head/drive byte of a command. -; (Drive #0 is always used.) -; FIXME: add drive 1 support send_head: - ld a, (_fd765_head) + ld hl, (_fd765_head) ; l = head h = drive) + ld a, l add a add a + add h jr fd765_tx ; Performs a RECALIBRATE command. @@ -131,7 +131,7 @@ send_head: _fd765_do_recalibrate: ld a, #0x07 ; RECALIBRATE call fd765_tx - ld a, #0x00 ; drive #0 FIXME + ld a, (_fd765_drive) ; drive # call fd765_tx jr wait_for_seek_ending @@ -146,11 +146,14 @@ _fd765_do_seek: jr wait_for_seek_ending _fd765_track: .db 0 -_fd765_head: - .db 0 _fd765_sector: .db 0 -_fd765_disc: +; +; These two must remain adjacent see send_head +; +_fd765_head: + .db 0 +_fd765_drive: .db 0 ; Waits for a SEEK or RECALIBRATE command to finish by polling SENSE INTERRUPT STATUS. @@ -184,7 +187,7 @@ wait_ms_loop2: dec a jr nz, wait_ms_loop pop bc - ld a,(_vborder) + ld a,(_vtborder) out (0xFE),a ret @@ -302,7 +305,7 @@ read_finished: call fd765_read_status call tc_fix - ld a,(_vborder) + ld a,(_vtborder) out (0xFE),a pop af @@ -394,7 +397,7 @@ write_finished: call fd765_read_status call tc_fix - ld a,(_vborder) + ld a,(_vtborder) out (0xFE),a pop af diff --git a/Kernel/platform-zx+3/fdc765_platform.h b/Kernel/platform-zx+3/platform_fdc765.h similarity index 60% rename from Kernel/platform-zx+3/fdc765_platform.h rename to Kernel/platform-zx+3/platform_fdc765.h index f431ac05..3d05e9f0 100644 --- a/Kernel/platform-zx+3/fdc765_platform.h +++ b/Kernel/platform-zx+3/platform_fdc765.h @@ -3,3 +3,6 @@ */ #define FDC_MOTOR_TIMEOUT 10 /* Seconds */ + +#define FDC765_MAX_FLOPPY 2 /* Two drives */ +