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 417 };
418 418  
419 419 enum {
  420 +#if MAX_FD == 4
  421 + FD_DOR_SELMASK = 0x03,
  422 +#else
420 423 FD_DOR_SELMASK = 0x01,
  424 +#endif
421 425 FD_DOR_nRESET = 0x04,
422 426 FD_DOR_DMAEN = 0x08,
423 427 FD_DOR_MOTEN0 = 0x10,
... ... @@ -427,7 +431,11 @@ enum {
427 431 };
428 432  
429 433 enum {
  434 +#if MAX_FD == 4
430 435 FD_TDR_BOOTSEL = 0x0c,
  436 +#else
  437 + FD_TDR_BOOTSEL = 0x04,
  438 +#endif
431 439 };
432 440  
433 441 enum {
... ... @@ -494,7 +502,7 @@ struct fdctrl_t {
494 502 /* Sun4m quirks? */
495 503 int sun4m;
496 504 /* Floppy drives */
497   - fdrive_t drives[2];
  505 + fdrive_t drives[MAX_FD];
498 506 };
499 507  
500 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 610 static void fdc_save (QEMUFile *f, void *opaque)
603 611 {
604 612 fdctrl_t *s = opaque;
  613 + uint8_t tmp;
  614 + int i;
605 615  
606 616 /* Controller state */
607 617 qemu_put_8s(f, &s->sra);
... ... @@ -627,8 +637,11 @@ static void fdc_save (QEMUFile *f, void *opaque)
627 637 qemu_put_8s(f, &s->config);
628 638 qemu_put_8s(f, &s->lock);
629 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 647 static int fd_load (QEMUFile *f, fdrive_t *fd)
... ... @@ -643,7 +656,8 @@ static int fd_load (QEMUFile *f, fdrive_t *fd)
643 656 static int fdc_load (QEMUFile *f, void *opaque, int version_id)
644 657 {
645 658 fdctrl_t *s = opaque;
646   - int ret;
  659 + int i, ret = 0;
  660 + uint8_t n;
647 661  
648 662 if (version_id != 2)
649 663 return -EINVAL;
... ... @@ -672,10 +686,16 @@ static int fdc_load (QEMUFile *f, void *opaque, int version_id)
672 686 qemu_get_8s(f, &s->config);
673 687 qemu_get_8s(f, &s->lock);
674 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 700 return ret;
681 701 }
... ... @@ -773,9 +793,35 @@ static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
773 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 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 827 /* Status A register : 0x00 (read-only) */
... ... @@ -923,8 +969,13 @@ static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
923 969 {
924 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 979 retval |= FD_DIR_DSKCHG;
929 980 if (retval != 0)
930 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 1418 /* Drives position */
1368 1419 fdctrl->fifo[0] = drv0(fdctrl)->track;
1369 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 1425 fdctrl->fifo[2] = 0;
1371 1426 fdctrl->fifo[3] = 0;
  1427 +#endif
1372 1428 /* timers */
1373 1429 fdctrl->fifo[4] = fdctrl->timer0;
1374 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 1456 /* Drives position */
1401 1457 drv0(fdctrl)->track = fdctrl->fifo[3];
1402 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 1463 /* timers */
1404 1464 fdctrl->timer0 = fdctrl->fifo[7];
1405 1465 fdctrl->timer1 = fdctrl->fifo[8];
... ... @@ -1421,8 +1481,13 @@ static void fdctrl_handle_save (fdctrl_t *fdctrl, int direction)
1421 1481 /* Drives position */
1422 1482 fdctrl->fifo[2] = drv0(fdctrl)->track;
1423 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 1488 fdctrl->fifo[4] = 0;
1425 1489 fdctrl->fifo[5] = 0;
  1490 +#endif
1426 1491 /* timers */
1427 1492 fdctrl->fifo[6] = fdctrl->timer0;
1428 1493 fdctrl->fifo[7] = fdctrl->timer1;
... ...