trs80: further work on the hd driver
authorAlan Cox <alan@linux.intel.com>
Wed, 10 Dec 2014 23:19:50 +0000 (23:19 +0000)
committerAlan Cox <alan@linux.intel.com>
Wed, 10 Dec 2014 23:19:50 +0000 (23:19 +0000)
Still needs a floppy boot block to begin testing

Kernel/platform-trs80/devhd.c

index cba79c5..ca43c88 100644 (file)
@@ -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;
 }