Patchwork Re: [PATCH 06/14] fdc: support NEC PC-9821 family

login
register
mail settings
Submitter 武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?=
Date Sept. 10, 2009, 4:29 p.m.
Message ID <200909101629.AA00099@YOUR-BD18D6DD63.m1.interq.or.jp>
Download mbox | patch
Permalink /patch/33373/
State Superseded
Headers show

Comments

武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?= - Sept. 10, 2009, 4:29 p.m.
Dear Alex,

>On 09.09.2009, at 17:42, 武田 俊也 wrote:
>
>> This patch is to add NEC PC-9821 family i/o to fdc.
>>
>> diff -ur a/hw/fdc.c b/hw/fdc.c
>> --- a/hw/fdc.c	Tue Sep  8 21:26:50 2009
>> +++ b/hw/fdc.c	Wed Sep  9 21:51:23 2009
>> @@ -85,6 +85,7 @@
>>     /* Drive status */
>>     fdrive_type_t drive;
>>     uint8_t perpendicular;    /* 2.88 MB access mode    */
>> +    uint8_t seek_result;
>>     /* Position */
>>     uint8_t head;
>>     uint8_t track;
>> @@ -175,6 +176,7 @@
>>     drv->head = 0;
>>     drv->track = 0;
>>     drv->sect = 1;
>> +    drv->seek_result = 0;
>> }
>>
>> /* Recognize floppy formats */
>> @@ -387,6 +389,7 @@
>> };
>>
>> enum {
>> +    FD_SR0_NOTRDY   = 0x08,
>>     FD_SR0_EQPMT    = 0x10,
>>     FD_SR0_SEEK     = 0x20,
>>     FD_SR0_ABNTERM  = 0x40,
>> @@ -507,8 +510,10 @@
>>     uint8_t pwrd;
>>     /* Sun4m quirks? */
>>     int sun4m;
>> +    /* NEC PC-98x1 quirks? */
>> +    int pc98;
>>     /* Floppy drives */
>> -    fdrive_t drives[MAX_FD];
>> +    fdrive_t drives[4];
>
>Just change MAX_FD?

Thank you very much for comments.

I tried the patch to support changing the drive number for each machine.
This patch does not includes PC-98x1 features.
If this direction is acceptable, I reimplement PC-98x1 patch based on it.

Now the drive number is initialized to MAX_FD for each machine,
but we need to consider the meaning of MAX_FD.

Patch

diff -ur a/hw/fdc.c b/hw/fdc.c
--- a/hw/fdc.c	Thu Sep 10 22:27:13 2009
+++ b/hw/fdc.c	Fri Sep 11 00:54:56 2009
@@ -52,6 +52,8 @@ 
 /********************************************************/
 /* Floppy drive emulation                               */
 
+#define MAX_FD_BUFFER 4
+
 #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
 #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
 
@@ -424,11 +426,6 @@ 
 };
 
 enum {
-#if MAX_FD == 4
-    FD_DOR_SELMASK  = 0x03,
-#else
-    FD_DOR_SELMASK  = 0x01,
-#endif
     FD_DOR_nRESET   = 0x04,
     FD_DOR_DMAEN    = 0x08,
     FD_DOR_MOTEN0   = 0x10,
@@ -437,13 +434,8 @@ 
     FD_DOR_MOTEN3   = 0x80,
 };
 
-enum {
-#if MAX_FD == 4
-    FD_TDR_BOOTSEL  = 0x0c,
-#else
-    FD_TDR_BOOTSEL  = 0x04,
-#endif
-};
+#define FD_DOR_SELMASK(fdctrl) (fdctrl->max_fd - 1)
+#define FD_TDR_BOOTSEL(fdctrl) ((fdctrl->max_fd - 1) << 2)
 
 enum {
     FD_DSR_DRATEMASK= 0x03,
@@ -473,6 +465,8 @@ 
 struct fdctrl_t {
     /* Controller's identification */
     uint8_t version;
+    /* Max drives (must be 2 or 4) */
+    uint8_t max_fd;
     /* HW */
     qemu_irq irq;
     int dma_chann;
@@ -508,7 +502,7 @@ 
     /* Sun4m quirks? */
     int sun4m;
     /* Floppy drives */
-    fdrive_t drives[MAX_FD];
+    fdrive_t drives[MAX_FD_BUFFER];
     int reset_sensei;
 };
 
@@ -637,7 +631,6 @@ 
 static void fdc_save (QEMUFile *f, void *opaque)
 {
     fdctrl_t *s = opaque;
-    uint8_t tmp;
     int i;
     uint8_t dor = s->dor | GET_CUR_DRV(s);
 
@@ -666,9 +659,8 @@ 
     qemu_put_8s(f, &s->lock);
     qemu_put_8s(f, &s->pwrd);
 
-    tmp = MAX_FD;
-    qemu_put_8s(f, &tmp);
-    for (i = 0; i < MAX_FD; i++)
+    qemu_put_8s(f, &s->max_fd);
+    for (i = 0; i < s->max_fd; i++)
         fd_save(f, &s->drives[i]);
 }
 
@@ -694,8 +686,8 @@ 
     qemu_get_8s(f, &s->sra);
     qemu_get_8s(f, &s->srb);
     qemu_get_8s(f, &s->dor);
-    SET_CUR_DRV(s, s->dor & FD_DOR_SELMASK);
-    s->dor &= ~FD_DOR_SELMASK;
+    SET_CUR_DRV(s, s->dor & FD_DOR_SELMASK(s));
+    s->dor &= ~FD_DOR_SELMASK(s);
     qemu_get_8s(f, &s->tdr);
     qemu_get_8s(f, &s->dsr);
     qemu_get_8s(f, &s->msr);
@@ -718,8 +710,9 @@ 
     qemu_get_8s(f, &s->pwrd);
     qemu_get_8s(f, &n);
 
-    if (n > MAX_FD)
+    if (n > MAX_FD_BUFFER)
         return -EINVAL;
+    s->max_fd = n;
 
     for (i = 0; i < n; i++) {
         ret = fd_load(f, &s->drives[i]);
@@ -803,7 +796,7 @@ 
     fdctrl->data_len = 0;
     fdctrl->data_state = 0;
     fdctrl->data_dir = FD_DIR_WRITE;
-    for (i = 0; i < MAX_FD; i++)
+    for (i = 0; i < fdctrl->max_fd; i++)
         fd_recalibrate(&fdctrl->drives[i]);
     fdctrl_reset_fifo(fdctrl);
     if (do_irq) {
@@ -814,21 +807,22 @@ 
 
 static inline fdrive_t *drv0 (fdctrl_t *fdctrl)
 {
-    return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2];
+    return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) >> 2];
 }
 
 static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
 {
-    if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2))
+    if ((fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) < (1 << 2))
         return &fdctrl->drives[1];
     else
         return &fdctrl->drives[0];
 }
 
-#if MAX_FD == 4
 static inline fdrive_t *drv2 (fdctrl_t *fdctrl)
 {
-    if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
+    if (fdctrl->max_fd != 4)
+        return NULL;
+    else if ((fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) < (2 << 2))
         return &fdctrl->drives[2];
     else
         return &fdctrl->drives[1];
@@ -836,22 +830,21 @@ 
 
 static inline fdrive_t *drv3 (fdctrl_t *fdctrl)
 {
-    if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
+    if (fdctrl->max_fd != 4)
+        return NULL;
+    else if ((fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) < (3 << 2))
         return &fdctrl->drives[3];
     else
         return &fdctrl->drives[2];
 }
-#endif
 
 static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
 {
     switch (fdctrl->cur_drv) {
         case 0: return drv0(fdctrl);
         case 1: return drv1(fdctrl);
-#if MAX_FD == 4
         case 2: return drv2(fdctrl);
         case 3: return drv3(fdctrl);
-#endif
         default: return NULL;
     }
 }
@@ -921,7 +914,7 @@ 
         }
     }
     /* Selected drive */
-    fdctrl->cur_drv = value & FD_DOR_SELMASK;
+    fdctrl->cur_drv = value & FD_DOR_SELMASK(fdctrl);
 
     fdctrl->dor = value;
 }
@@ -945,7 +938,7 @@ 
     }
     FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
     /* Disk boot selection indicator */
-    fdctrl->tdr = value & FD_TDR_BOOTSEL;
+    fdctrl->tdr = value & FD_TDR_BOOTSEL(fdctrl);
     /* Tape indicators: never allow */
 }
 
@@ -1003,10 +996,8 @@ 
 
     if (fdctrl_media_changed(drv0(fdctrl))
      || fdctrl_media_changed(drv1(fdctrl))
-#if MAX_FD == 4
-     || fdctrl_media_changed(drv2(fdctrl))
-     || fdctrl_media_changed(drv3(fdctrl))
-#endif
+     || (fdctrl->max_fd == 4 && fdctrl_media_changed(drv2(fdctrl)))
+     || (fdctrl->max_fd == 4 && fdctrl_media_changed(drv3(fdctrl)))
         )
         retval |= FD_DIR_DSKCHG;
     if (retval != 0)
@@ -1109,7 +1100,7 @@ 
     uint8_t kh, kt, ks;
     int did_seek = 0;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     kt = fdctrl->fifo[2];
     kh = fdctrl->fifo[3];
@@ -1379,7 +1370,7 @@ 
     fdrive_t *cur_drv;
     uint8_t kh, kt, ks;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     kt = fdctrl->fifo[6];
     kh = fdctrl->fifo[7];
@@ -1450,13 +1441,13 @@ 
     /* Drives position */
     fdctrl->fifo[0] = drv0(fdctrl)->track;
     fdctrl->fifo[1] = drv1(fdctrl)->track;
-#if MAX_FD == 4
-    fdctrl->fifo[2] = drv2(fdctrl)->track;
-    fdctrl->fifo[3] = drv3(fdctrl)->track;
-#else
-    fdctrl->fifo[2] = 0;
-    fdctrl->fifo[3] = 0;
-#endif
+    if (fdctrl->max_fd == 4) {
+        fdctrl->fifo[2] = drv2(fdctrl)->track;
+        fdctrl->fifo[3] = drv3(fdctrl)->track;
+    } else {
+        fdctrl->fifo[2] = 0;
+        fdctrl->fifo[3] = 0;
+    }
     /* timers */
     fdctrl->fifo[4] = fdctrl->timer0;
     fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
@@ -1488,10 +1479,10 @@ 
     /* Drives position */
     drv0(fdctrl)->track = fdctrl->fifo[3];
     drv1(fdctrl)->track = fdctrl->fifo[4];
-#if MAX_FD == 4
-    drv2(fdctrl)->track = fdctrl->fifo[5];
-    drv3(fdctrl)->track = fdctrl->fifo[6];
-#endif
+    if (fdctrl->max_fd == 4) {
+        drv2(fdctrl)->track = fdctrl->fifo[5];
+        drv3(fdctrl)->track = fdctrl->fifo[6];
+    }
     /* timers */
     fdctrl->timer0 = fdctrl->fifo[7];
     fdctrl->timer1 = fdctrl->fifo[8];
@@ -1513,13 +1504,13 @@ 
     /* Drives position */
     fdctrl->fifo[2] = drv0(fdctrl)->track;
     fdctrl->fifo[3] = drv1(fdctrl)->track;
-#if MAX_FD == 4
-    fdctrl->fifo[4] = drv2(fdctrl)->track;
-    fdctrl->fifo[5] = drv3(fdctrl)->track;
-#else
-    fdctrl->fifo[4] = 0;
-    fdctrl->fifo[5] = 0;
-#endif
+    if (fdctrl->max_fd == 4) {
+        fdctrl->fifo[4] = drv2(fdctrl)->track;
+        fdctrl->fifo[5] = drv3(fdctrl)->track;
+    } else {
+        fdctrl->fifo[4] = 0;
+        fdctrl->fifo[5] = 0;
+    }
     /* timers */
     fdctrl->fifo[6] = fdctrl->timer0;
     fdctrl->fifo[7] = fdctrl->timer1;
@@ -1548,7 +1539,7 @@ 
 {
     fdrive_t *cur_drv;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     fdctrl->data_state |= FD_STATE_FORMAT;
     if (fdctrl->fifo[0] & 0x80)
@@ -1589,7 +1580,7 @@ 
 {
     fdrive_t *cur_drv;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
     /* 1 Byte status back */
@@ -1605,7 +1596,7 @@ 
 {
     fdrive_t *cur_drv;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     fd_recalibrate(cur_drv);
     fdctrl_reset_fifo(fdctrl);
@@ -1639,7 +1630,7 @@ 
 {
     fdrive_t *cur_drv;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     fdctrl_reset_fifo(fdctrl);
     if (fdctrl->fifo[2] > cur_drv->max_track) {
@@ -1708,7 +1699,7 @@ 
 {
     fdrive_t *cur_drv;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
         cur_drv->track = cur_drv->max_track - 1;
@@ -1724,7 +1715,7 @@ 
 {
     fdrive_t *cur_drv;
 
-    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl));
     cur_drv = get_cur_drv(fdctrl);
     if (fdctrl->fifo[2] > cur_drv->track) {
         cur_drv->track = 0;
@@ -1865,7 +1856,7 @@ 
 {
     unsigned int i;
 
-    for (i = 0; i < MAX_FD; i++) {
+    for (i = 0; i < fdctrl->max_fd; i++) {
         fd_init(&fdctrl->drives[i], fds[i]);
         fd_revalidate(&fdctrl->drives[i]);
     }
@@ -1881,7 +1872,9 @@ 
     dev = isa_create_simple("isa-fdc", io_base, 0, isairq, -1);
     fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
 
+    fdctrl->max_fd = MAX_FD;
     fdctrl->dma_chann = dma_chann;
+
     DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
 
     fdctrl_connect_drives(fdctrl, fds);
@@ -1904,7 +1897,9 @@ 
     sysbus_connect_irq(&sys->busdev, 0, irq);
     sysbus_mmio_map(&sys->busdev, 0, mmio_base);
 
+    fdctrl->max_fd = MAX_FD;
     fdctrl->dma_chann = dma_chann;
+
     DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
     fdctrl_connect_drives(fdctrl, fds);
 
@@ -1926,6 +1921,7 @@ 
     sysbus_mmio_map(&sys->busdev, 0, io_base);
     *fdc_tc = qdev_get_gpio_in(dev, 0);
 
+    fdctrl->max_fd = MAX_FD;
     fdctrl->dma_chann = -1;
 
     fdctrl_connect_drives(fdctrl, fds);
@@ -1979,6 +1975,8 @@ 
                           &fdctrl_write_port, fdctrl);
     isa_init_irq(&isa->busdev, &fdctrl->irq);
 
+    fdctrl->max_fd = MAX_FD;
+
     return fdctrl_init_common(fdctrl);
 }
 
@@ -1992,6 +1990,8 @@ 
     sysbus_init_irq(dev, &fdctrl->irq);
     qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
 
+    fdctrl->max_fd = MAX_FD;
+
     return fdctrl_init_common(fdctrl);
 }
 
@@ -2006,7 +2006,9 @@ 
     sysbus_init_irq(dev, &fdctrl->irq);
     qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
 
+    fdctrl->max_fd = MAX_FD;
     fdctrl->sun4m = 1;
+
     return fdctrl_init_common(fdctrl);
 }