From: Alan Cox Date: Wed, 10 Dec 2014 23:19:50 +0000 (+0000) Subject: trs80: further work on the hd driver X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=7e6e530833516209453f30d976e6cf3b83f7751e;p=FUZIX.git trs80: further work on the hd driver Still needs a floppy boot block to begin testing --- diff --git a/Kernel/platform-trs80/devhd.c b/Kernel/platform-trs80/devhd.c index cba79c55..ca43c88f 100644 --- a/Kernel/platform-trs80/devhd.c +++ b/Kernel/platform-trs80/devhd.c @@ -23,9 +23,9 @@ __sfr __at 0xCF hd_cmd; #define HDCMD_RESTORE 0x10 #define HDCMD_READ 0x20 #define HDCMD_WRITE 0x30 -#define HDCMD_VERIFY 0x40 +#define HDCMD_VERIFY 0x40 /* Not on the 1010 later only */ #define HDCMD_FORMAT 0x50 -#define HDCMD_INIT 0x60 +#define HDCMD_INIT 0x60 /* Ditto */ #define HDCMD_SEEK 0x70 /* Seek and restore low 4 bits are the step rate, read/write support @@ -33,13 +33,25 @@ __sfr __at 0xCF hd_cmd; #define MAX_HD 4 - +/* Wait for DRQ or an error */ static uint8_t hd_waitready(void) { uint8_t st; do { st = hd_status; - } while (st & 0x80); + } while (!(st & 0x40)); + return st; +} + + + +/* Wait for DRQ or an error */ +static uint8_t hd_waitdrq(void) +{ + uint8_t st; + do { + st = hd_status; + } while (!(st & 0x09)); return st; } @@ -49,20 +61,21 @@ static uint8_t hd_xfer(bool is_read, uint16_t addr) int ct = 256; uint8_t *ptr = (uint8_t *)addr; - if (!(hd_status & 0x08)) + /* Error ? */ + if (hd_status & 0x01) return hd_status; if (is_read) { /* Ought to check DRQ per byte ? */ while (ct--) { *ptr++ = hd_data; } - return 0; } else { while (ct--) { hd_data = *ptr++; } - return 0; } + /* Should be returning READY, and maybe SEEKDONE */ + return hd_status; } /* @@ -93,26 +106,36 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) /* We assume 32 sectors per track for now. From our 512 byte PoV that's 16 */ - /* For our test purposes we use a disk with 32 sectors, 8 heads so - our blocks map out as ccccccccCCCCCCCCHHHSSSS */ + /* For our test purposes we use a disk with 32 sectors, 4 heads so + our blocks map out as 00cccccc ccCCCCCC CCHHSSSS + + This matches a real ST506 which is 153 cyls, 4 heads, 32 sector */ + + hd_precomp = 0x20; /* For now, matches an ST506 */ hd_seccnt = 1; sector = ((block & 15) << 1) + 1; - hd_secnum = sector; - hd_cyllo = (block >> 7) & 0xFF; - hd_cylhi = (block >> 15) & 0xFF; - head = (block >> 4) & 7; + hd_secnum = sector; + hd_cyllo = (block >> 6) & 0xFF; + hd_cylhi = (block >> 14) & 0xFF; + head = (block >> 4) & 3; hd_precomp = 0; /* FIXME */ hd_sdh = 0x80 | head | (minor << 3); while (ct < 2) { for (tries = 0; tries < 4; tries++) { + /* issue the command */ hd_cmd = cmd; - err = hd_waitready(); - if (err == 0) { + /* DRQ will go high once the controller is ready + for us */ + err = hd_waitdrq(); + if (!(err & 1)) { err = hd_xfer(is_read, dptr); - break; + /* Ready, no error ? */ + if ((err & 0x41) == 0x40) + break; } + if (tries > 1) { hd_cmd = HDCMD_RESTORE; hd_waitready(); @@ -139,10 +162,11 @@ bad2: int hd_open(uint8_t minor, uint16_t flag) { flag; - if (minor > MAX_HD) { + if (minor >= MAX_HD) { udata.u_error = ENODEV; return -1; } + return 0; }