Commit 78ae820cfeb04cb05b25bc024c4736cd80bf0007

Authored by blueswir1
1 parent 46d3233b

FDC fix 9/10 (Hervé Poussineau):

- Supports up to 4 floppy drives if MAX_FD is set to 4.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4289 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 75 additions and 10 deletions
hw/fdc.c
@@ -417,7 +417,11 @@ enum { @@ -417,7 +417,11 @@ enum {
417 }; 417 };
418 418
419 enum { 419 enum {
  420 +#if MAX_FD == 4
  421 + FD_DOR_SELMASK = 0x03,
  422 +#else
420 FD_DOR_SELMASK = 0x01, 423 FD_DOR_SELMASK = 0x01,
  424 +#endif
421 FD_DOR_nRESET = 0x04, 425 FD_DOR_nRESET = 0x04,
422 FD_DOR_DMAEN = 0x08, 426 FD_DOR_DMAEN = 0x08,
423 FD_DOR_MOTEN0 = 0x10, 427 FD_DOR_MOTEN0 = 0x10,
@@ -427,7 +431,11 @@ enum { @@ -427,7 +431,11 @@ enum {
427 }; 431 };
428 432
429 enum { 433 enum {
  434 +#if MAX_FD == 4
430 FD_TDR_BOOTSEL = 0x0c, 435 FD_TDR_BOOTSEL = 0x0c,
  436 +#else
  437 + FD_TDR_BOOTSEL = 0x04,
  438 +#endif
431 }; 439 };
432 440
433 enum { 441 enum {
@@ -494,7 +502,7 @@ struct fdctrl_t { @@ -494,7 +502,7 @@ struct fdctrl_t {
494 /* Sun4m quirks? */ 502 /* Sun4m quirks? */
495 int sun4m; 503 int sun4m;
496 /* Floppy drives */ 504 /* Floppy drives */
497 - fdrive_t drives[2]; 505 + fdrive_t drives[MAX_FD];
498 }; 506 };
499 507
500 static uint32_t fdctrl_read (void *opaque, uint32_t reg) 508 static uint32_t fdctrl_read (void *opaque, uint32_t reg)
@@ -602,6 +610,8 @@ static void fd_save (QEMUFile *f, fdrive_t *fd) @@ -602,6 +610,8 @@ static void fd_save (QEMUFile *f, fdrive_t *fd)
602 static void fdc_save (QEMUFile *f, void *opaque) 610 static void fdc_save (QEMUFile *f, void *opaque)
603 { 611 {
604 fdctrl_t *s = opaque; 612 fdctrl_t *s = opaque;
  613 + uint8_t tmp;
  614 + int i;
605 615
606 /* Controller state */ 616 /* Controller state */
607 qemu_put_8s(f, &s->sra); 617 qemu_put_8s(f, &s->sra);
@@ -627,8 +637,11 @@ static void fdc_save (QEMUFile *f, void *opaque) @@ -627,8 +637,11 @@ static void fdc_save (QEMUFile *f, void *opaque)
627 qemu_put_8s(f, &s->config); 637 qemu_put_8s(f, &s->config);
628 qemu_put_8s(f, &s->lock); 638 qemu_put_8s(f, &s->lock);
629 qemu_put_8s(f, &s->pwrd); 639 qemu_put_8s(f, &s->pwrd);
630 - fd_save(f, &s->drives[0]);  
631 - fd_save(f, &s->drives[1]); 640 +
  641 + tmp = MAX_FD;
  642 + qemu_put_8s(f, &tmp);
  643 + for (i = 0; i < MAX_FD; i++)
  644 + fd_save(f, &s->drives[i]);
632 } 645 }
633 646
634 static int fd_load (QEMUFile *f, fdrive_t *fd) 647 static int fd_load (QEMUFile *f, fdrive_t *fd)
@@ -643,7 +656,8 @@ static int fd_load (QEMUFile *f, fdrive_t *fd) @@ -643,7 +656,8 @@ static int fd_load (QEMUFile *f, fdrive_t *fd)
643 static int fdc_load (QEMUFile *f, void *opaque, int version_id) 656 static int fdc_load (QEMUFile *f, void *opaque, int version_id)
644 { 657 {
645 fdctrl_t *s = opaque; 658 fdctrl_t *s = opaque;
646 - int ret; 659 + int i, ret = 0;
  660 + uint8_t n;
647 661
648 if (version_id != 2) 662 if (version_id != 2)
649 return -EINVAL; 663 return -EINVAL;
@@ -672,10 +686,16 @@ static int fdc_load (QEMUFile *f, void *opaque, int version_id) @@ -672,10 +686,16 @@ static int fdc_load (QEMUFile *f, void *opaque, int version_id)
672 qemu_get_8s(f, &s->config); 686 qemu_get_8s(f, &s->config);
673 qemu_get_8s(f, &s->lock); 687 qemu_get_8s(f, &s->lock);
674 qemu_get_8s(f, &s->pwrd); 688 qemu_get_8s(f, &s->pwrd);
  689 + qemu_get_8s(f, &n);
675 690
676 - ret = fd_load(f, &s->drives[0]);  
677 - if (ret == 0)  
678 - ret = fd_load(f, &s->drives[1]); 691 + if (n > MAX_FD)
  692 + return -EINVAL;
  693 +
  694 + for (i = 0; i < n; i++) {
  695 + ret = fd_load(f, &s->drives[i]);
  696 + if (ret != 0)
  697 + break;
  698 + }
679 699
680 return ret; 700 return ret;
681 } 701 }
@@ -773,9 +793,35 @@ static inline fdrive_t *drv1 (fdctrl_t *fdctrl) @@ -773,9 +793,35 @@ static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
773 return &fdctrl->drives[0]; 793 return &fdctrl->drives[0];
774 } 794 }
775 795
  796 +#if MAX_FD == 4
  797 +static inline fdrive_t *drv2 (fdctrl_t *fdctrl)
  798 +{
  799 + if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
  800 + return &fdctrl->drives[2];
  801 + else
  802 + return &fdctrl->drives[1];
  803 +}
  804 +
  805 +static inline fdrive_t *drv3 (fdctrl_t *fdctrl)
  806 +{
  807 + if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
  808 + return &fdctrl->drives[3];
  809 + else
  810 + return &fdctrl->drives[2];
  811 +}
  812 +#endif
  813 +
776 static fdrive_t *get_cur_drv (fdctrl_t *fdctrl) 814 static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
777 { 815 {
778 - return fdctrl->cur_drv == 0 ? drv0(fdctrl) : drv1(fdctrl); 816 + switch (fdctrl->cur_drv) {
  817 + case 0: return drv0(fdctrl);
  818 + case 1: return drv1(fdctrl);
  819 +#if MAX_FD == 4
  820 + case 2: return drv2(fdctrl);
  821 + case 3: return drv3(fdctrl);
  822 +#endif
  823 + default: return NULL;
  824 + }
779 } 825 }
780 826
781 /* Status A register : 0x00 (read-only) */ 827 /* Status A register : 0x00 (read-only) */
@@ -923,8 +969,13 @@ static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl) @@ -923,8 +969,13 @@ static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
923 { 969 {
924 uint32_t retval = 0; 970 uint32_t retval = 0;
925 971
926 - if (fdctrl_media_changed(drv0(fdctrl)) ||  
927 - fdctrl_media_changed(drv1(fdctrl))) 972 + if (fdctrl_media_changed(drv0(fdctrl))
  973 + || fdctrl_media_changed(drv1(fdctrl))
  974 +#if MAX_FD == 4
  975 + || fdctrl_media_changed(drv2(fdctrl))
  976 + || fdctrl_media_changed(drv3(fdctrl))
  977 +#endif
  978 + )
928 retval |= FD_DIR_DSKCHG; 979 retval |= FD_DIR_DSKCHG;
929 if (retval != 0) 980 if (retval != 0)
930 FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval); 981 FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
@@ -1367,8 +1418,13 @@ static void fdctrl_handle_dumpreg (fdctrl_t *fdctrl, int direction) @@ -1367,8 +1418,13 @@ static void fdctrl_handle_dumpreg (fdctrl_t *fdctrl, int direction)
1367 /* Drives position */ 1418 /* Drives position */
1368 fdctrl->fifo[0] = drv0(fdctrl)->track; 1419 fdctrl->fifo[0] = drv0(fdctrl)->track;
1369 fdctrl->fifo[1] = drv1(fdctrl)->track; 1420 fdctrl->fifo[1] = drv1(fdctrl)->track;
  1421 +#if MAX_FD == 4
  1422 + fdctrl->fifo[2] = drv2(fdctrl)->track;
  1423 + fdctrl->fifo[3] = drv3(fdctrl)->track;
  1424 +#else
1370 fdctrl->fifo[2] = 0; 1425 fdctrl->fifo[2] = 0;
1371 fdctrl->fifo[3] = 0; 1426 fdctrl->fifo[3] = 0;
  1427 +#endif
1372 /* timers */ 1428 /* timers */
1373 fdctrl->fifo[4] = fdctrl->timer0; 1429 fdctrl->fifo[4] = fdctrl->timer0;
1374 fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0); 1430 fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
@@ -1400,6 +1456,10 @@ static void fdctrl_handle_restore (fdctrl_t *fdctrl, int direction) @@ -1400,6 +1456,10 @@ static void fdctrl_handle_restore (fdctrl_t *fdctrl, int direction)
1400 /* Drives position */ 1456 /* Drives position */
1401 drv0(fdctrl)->track = fdctrl->fifo[3]; 1457 drv0(fdctrl)->track = fdctrl->fifo[3];
1402 drv1(fdctrl)->track = fdctrl->fifo[4]; 1458 drv1(fdctrl)->track = fdctrl->fifo[4];
  1459 +#if MAX_FD == 4
  1460 + drv2(fdctrl)->track = fdctrl->fifo[5];
  1461 + drv3(fdctrl)->track = fdctrl->fifo[6];
  1462 +#endif
1403 /* timers */ 1463 /* timers */
1404 fdctrl->timer0 = fdctrl->fifo[7]; 1464 fdctrl->timer0 = fdctrl->fifo[7];
1405 fdctrl->timer1 = fdctrl->fifo[8]; 1465 fdctrl->timer1 = fdctrl->fifo[8];
@@ -1421,8 +1481,13 @@ static void fdctrl_handle_save (fdctrl_t *fdctrl, int direction) @@ -1421,8 +1481,13 @@ static void fdctrl_handle_save (fdctrl_t *fdctrl, int direction)
1421 /* Drives position */ 1481 /* Drives position */
1422 fdctrl->fifo[2] = drv0(fdctrl)->track; 1482 fdctrl->fifo[2] = drv0(fdctrl)->track;
1423 fdctrl->fifo[3] = drv1(fdctrl)->track; 1483 fdctrl->fifo[3] = drv1(fdctrl)->track;
  1484 +#if MAX_FD == 4
  1485 + fdctrl->fifo[4] = drv2(fdctrl)->track;
  1486 + fdctrl->fifo[5] = drv3(fdctrl)->track;
  1487 +#else
1424 fdctrl->fifo[4] = 0; 1488 fdctrl->fifo[4] = 0;
1425 fdctrl->fifo[5] = 0; 1489 fdctrl->fifo[5] = 0;
  1490 +#endif
1426 /* timers */ 1491 /* timers */
1427 fdctrl->fifo[6] = fdctrl->timer0; 1492 fdctrl->fifo[6] = fdctrl->timer0;
1428 fdctrl->fifo[7] = fdctrl->timer1; 1493 fdctrl->fifo[7] = fdctrl->timer1;