From 6843d179ef4942fab477cccd1f805c1f3a2436f7 Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Tue, 15 Oct 2024 13:43:37 -0600 Subject: [PATCH] [directfd] Add IODELAY floppy delay emulation to DF driver --- elks/arch/i86/drivers/block/bios.c | 5 +++-- elks/arch/i86/drivers/block/directfd.c | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/elks/arch/i86/drivers/block/bios.c b/elks/arch/i86/drivers/block/bios.c index b2e211130..885f43c1a 100644 --- a/elks/arch/i86/drivers/block/bios.c +++ b/elks/arch/i86/drivers/block/bios.c @@ -129,8 +129,9 @@ int BFPROC bios_disk_rw(unsigned cmd, unsigned num_sectors, unsigned drive, static unsigned lastcyl; unsigned ms = abs(cylinder - lastcyl) * 4 / 10; lastcyl = cylinder; - ms += 10 + num_sectors; /* 1440k @300rpm = 100ms + ~10ms/sector + 4ms/tr */ - if (drive == 1) + if (drive == 0) + ms += 10 + num_sectors; /* 1440k @300rpm = 100ms + ~10ms/sector + 4ms/tr */ + else ms += 8 + (num_sectors<<1); /* 360k @360rpm = 83ms + ~20ms/sector + 3ms/tr */ unsigned long timeout = jiffies + ms*HZ/100; while (!time_after(jiffies, timeout)) continue; diff --git a/elks/arch/i86/drivers/block/directfd.c b/elks/arch/i86/drivers/block/directfd.c index c6c80fa4b..c83ff0901 100644 --- a/elks/arch/i86/drivers/block/directfd.c +++ b/elks/arch/i86/drivers/block/directfd.c @@ -125,6 +125,7 @@ char USE_IMPLIED_SEEK = 0; /* =1 for QEMU with 360k/AT stretch floppies (not real hw) */ #define CHECK_DIR_REG 1 /* =1 to read and clear DIR DSKCHG when media changed */ #define CHECK_DISK_CHANGE 1 /* =1 to inform kernel of media changed */ +#define IODELAY 0 /* =1 to emulate delay for floppy on QEMU */ /* adjustable timeouts */ #define TIMEOUT_MOTOR_ON (HZ/2) /* 500 ms wait for floppy motor on before I/O */ @@ -136,6 +137,8 @@ char USE_IMPLIED_SEEK = 0; /* =1 for QEMU with 360k/AT stretch floppies (not rea //#define DEBUG printk #define DEBUG(...) +#define abs(v) (((int)(v) >= 0)? (v): -(v)) + #define bool unsigned char /* don't require stdbool.h yet */ static void (*do_floppy)(); /* interrupt routine to call */ @@ -771,8 +774,23 @@ static void rw_interrupt(void) static void DFPROC setup_rw_floppy(void) { DEBUG("setup_rw-"); - setup_DMA(); +#if IODELAY + int num_sectors = read_track? + floppy->sect + (read_track && (floppy->sect & 1) && !head) + : CURRENT->rq_nr_sectors; + DEBUG("[%ur%u]", current_drive, num_sectors); + static unsigned lasttrack; + unsigned ms = abs(track - lasttrack) * 4 / 10; + lasttrack = track; + if (current_drive == 0) + ms += 10 + num_sectors; /* 1440k @300rpm = 100ms + ~10ms/sector + 4ms/tr */ + else + ms += 8 + (num_sectors<<1); /* 360k @360rpm = 83ms + ~20ms/sector + 3ms/tr */ + unsigned long timeout = jiffies + ms*HZ/100; + while (!time_after(jiffies, timeout)) continue; +#endif do_floppy = rw_interrupt; + setup_DMA(); output_byte(command); output_byte(head << 2 | current_drive); output_byte(track);