From 8931cfa795d6a101ac23e22163ed4346c7cfa254 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 4 Feb 2018 21:17:43 +0000 Subject: [PATCH] ubee: first cut at automatic disk controller probing --- Kernel/platform-ubee/README | 28 +++++++++++++++++++++++++++- Kernel/platform-ubee/devfd.c | 14 ++++++++++---- Kernel/platform-ubee/devhd.c | 32 +++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/Kernel/platform-ubee/README b/Kernel/platform-ubee/README index 4de171d0..33267382 100644 --- a/Kernel/platform-ubee/README +++ b/Kernel/platform-ubee/README @@ -44,7 +44,33 @@ To Do: - IDE driver (note the ubee512 emulator ide appears to be very busted as on 5.8.0) - How to tell wd1010 system from 2793 from both with 0x58 switch -- If we have wd1010 and fd wtf do we put IDE in major/minors ? + - Select 0x58 = 0 + See if track register writes to values + See if it changes when we flip 0x58 (try several cases) + Y = has 0x58 switch + - WD 2793 has a track register we can play with which is + mirrored on the ubee 4 registers down I think + - WD1010 has lots more registers + + Algorithm therefore is + + Write 0x45 (mirrrored track) Read back at 0x41/0x45 a few times + + If it mirrors to 0x41 then it's a 2793 + If it writes/reads back but does not mirror it's a WD1002-5 + + Now check if writes to 0x45 affect 0x5 with 0x58 switched + (if so its two controllers and we can repeat the probe algorithm + for the other one) + + Finally check 0x48 on the floppies. If it has low bits set then + it's a dream disk or if setting bits is reflected back it's a dream + disk. So set bit 3 (DD), read back. 0x80 -> normal else DD + + *Never write 0x41 while probing as it's precomp on the WD. 0x45 + however is either cyl_high or track_w so safe + +- If we have wd1002-5 and fd wtf do we put IDE in major/minors ? Longer Term - Support attributes, colour, RAM based fonts (load the ROM one into RAM diff --git a/Kernel/platform-ubee/devfd.c b/Kernel/platform-ubee/devfd.c index 77aa7ac8..f5367674 100644 --- a/Kernel/platform-ubee/devfd.c +++ b/Kernel/platform-ubee/devfd.c @@ -2,6 +2,7 @@ #include #include #include +#include /* * Floppy controller logic for the Microbee systems with a 2793 @@ -52,6 +53,8 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) uint8_t *driveptr = fd_tab + minor; uint8_t cmd[7]; + minor &= 0x7F; + if(rawflag) if (d_blkoff(9)) return -1; @@ -59,7 +62,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) if (fd_selected != minor) { uint8_t err; /* FIXME: We force DD for now. Side isn't handled here */ - err = fd_motor_on(selmap[minor]|FDC_DOUBLE); + err = fd_motor_on(selmap[minor & 0x7F]|FDC_DOUBLE); if (err) goto bad; } @@ -103,8 +106,11 @@ bad: int fd_open(uint8_t minor, uint16_t flag) { + uint8_t sel = (minor & 0x80) ? 1 : 0; flag; - if(minor >= MAX_FD) { + fdc_devsel = sel; + if((disk_type[sel] != DISK_TYPE_FDC && disk_type[sel] != DISK_TYPE_FDC_D) || + minor >= MAX_FD) { udata.u_error = ENODEV; return -1; } @@ -114,13 +120,13 @@ int fd_open(uint8_t minor, uint16_t flag) int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) { flag; - fdc_devsel = 0; + fdc_devsel = (minor & 0x80) ? 1: 0; return fd_transfer(minor, true, rawflag); } int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) { flag;rawflag;minor; - fdc_devsel = 0; + fdc_devsel = (minor & 0x80) ? 1: 0; return fd_transfer(minor, false, rawflag); } diff --git a/Kernel/platform-ubee/devhd.c b/Kernel/platform-ubee/devhd.c index 9b479db3..de3a9bef 100644 --- a/Kernel/platform-ubee/devhd.c +++ b/Kernel/platform-ubee/devhd.c @@ -5,12 +5,21 @@ * with additional glue chips that also manage and front up a floppy * controller for us including the DMA management. It's actually a better * floppy controller than almost anything that followed it ! + * + * Minor is arranged as + * + * S slot (0 or 1 via port 0x58) + * DDD drive identifier + * 0-2 hdc + * 3-6 fdc + * MMMM 0000 (reserved for partitioning on hd) */ #include #include #include #include +#include __sfr __at 0x40 hd_data; __sfr __at 0x41 hd_precomp; /* W/O */ @@ -61,9 +70,11 @@ static int heads[7] = { 4, 4, 4, 2, 2, 2, 2 }; static uint8_t hd_waitready(void) { uint8_t st; + uint16_t tick = 0; do { st = hd_status; - } while (!(st & 0x40)); + tick++; + } while (!(st & 0x40) && !tick); return st; } @@ -123,6 +134,11 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) /* We don't touch precomp and hope the firmware set it right */ hd_seccnt = 1; + + /* Get rid of port 58 selector */ + minor &= 0x7F; + /* Reserve low bits fo rfuture partition tables */ + minor >>= 4; while (ct < udata.u_nblock) { uint16_t b = udata.u_block / spt[minor]; @@ -183,12 +199,18 @@ bad2: int hd_open(uint8_t minor, uint16_t flag) { + uint8_t sel = (minor & 0x80) ? 1 : 0; flag; - if (minor >= MAX_HD + MAX_FDC) { + + minor &= 0x7F; + + if (disk_type[sel] != DISK_TYPE_HDC || minor >= MAX_HD + MAX_FDC) { udata.u_error = ENODEV; return -1; } - fdc_devsel = 1; + fdc_devsel = sel; + /* Reserve low bits for future partition table support */ + minor >>= 4; if (minor <= MAX_HD) { hd_sdh = 0xA0 | (minor << 3); hd_cmd = HDCMD_RESTORE | RATE_2MS; @@ -206,13 +228,13 @@ int hd_open(uint8_t minor, uint16_t flag) int hd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) { flag; - fdc_devsel = 1; + fdc_devsel = (minor & 0x80) ? 1 : 0; return hd_transfer(minor, true, rawflag); } int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) { flag; - fdc_devsel = 1; + fdc_devsel = (minor & 0x80) ? 1 : 0; return hd_transfer(minor, false, rawflag); } -- 2.34.1