Revision 78ae820c hw/fdc.c

b/hw/fdc.c
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 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 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 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 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 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 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 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 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 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 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 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;

Also available in: Unified diff