Revision 1c346df2 hw/fdc.c

b/hw/fdc.c
69 69
    FDRIVE_DRV_NONE = 0x03,   /* No drive connected     */
70 70
} fdrive_type_t;
71 71

  
72
typedef enum fdrive_flags_t {
73
    FDRIVE_MOTOR_ON   = 0x01, /* motor on/off           */
74
} fdrive_flags_t;
75

  
76 72
typedef enum fdisk_flags_t {
77 73
    FDISK_DBL_SIDES  = 0x01,
78 74
} fdisk_flags_t;
......
81 77
    BlockDriverState *bs;
82 78
    /* Drive status */
83 79
    fdrive_type_t drive;
84
    fdrive_flags_t drflags;
85 80
    uint8_t perpendicular;    /* 2.88 MB access mode    */
86 81
    /* Position */
87 82
    uint8_t head;
......
103 98
    /* Drive */
104 99
    drv->bs = bs;
105 100
    drv->drive = FDRIVE_DRV_NONE;
106
    drv->drflags = 0;
107 101
    drv->perpendicular = 0;
108 102
    /* Disk */
109 103
    drv->last_sect = 0;
......
296 290
    }
297 291
}
298 292

  
299
/* Motor control */
300
static void fd_start (fdrive_t *drv)
301
{
302
    drv->drflags |= FDRIVE_MOTOR_ON;
303
}
304

  
305
static void fd_stop (fdrive_t *drv)
306
{
307
    drv->drflags &= ~FDRIVE_MOTOR_ON;
308
}
309

  
310
/* Re-initialise a drives (motor off, repositioned) */
311
static void fd_reset (fdrive_t *drv)
312
{
313
    fd_stop(drv);
314
    fd_recalibrate(drv);
315
}
316

  
317 293
/********************************************************/
318 294
/* Intel 82078 floppy disk controller emulation          */
319 295

  
......
337 313

  
338 314
enum {
339 315
    FD_CTRL_ACTIVE = 0x01, /* XXX: suppress that */
340
    FD_CTRL_RESET  = 0x02,
341 316
    FD_CTRL_SLEEP  = 0x04, /* XXX: suppress that */
342 317
    FD_CTRL_BUSY   = 0x08, /* dma transfer in progress */
343 318
};
......
621 596

  
622 597
static void fd_save (QEMUFile *f, fdrive_t *fd)
623 598
{
624
    uint8_t tmp;
625

  
626
    tmp = fd->drflags;
627
    qemu_put_8s(f, &tmp);
628 599
    qemu_put_8s(f, &fd->head);
629 600
    qemu_put_8s(f, &fd->track);
630 601
    qemu_put_8s(f, &fd->sect);
......
662 633

  
663 634
static int fd_load (QEMUFile *f, fdrive_t *fd)
664 635
{
665
    uint8_t tmp;
666

  
667
    qemu_get_8s(f, &tmp);
668
    fd->drflags = tmp;
669 636
    qemu_get_8s(f, &fd->head);
670 637
    qemu_get_8s(f, &fd->track);
671 638
    qemu_get_8s(f, &fd->sect);
......
773 740
    if (!fdctrl->drives[1].bs)
774 741
        fdctrl->sra |= FD_SRA_nDRV2;
775 742
    fdctrl->cur_drv = 0;
776
    fdctrl->dor = 0;
743
    fdctrl->dor = FD_DOR_nRESET;
777 744
    fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
778 745
    fdctrl->msr = 0;
779 746
    /* FIFO state */
......
782 749
    fdctrl->data_state = FD_STATE_CMD;
783 750
    fdctrl->data_dir = FD_DIR_WRITE;
784 751
    for (i = 0; i < MAX_FD; i++)
785
        fd_reset(&fdctrl->drives[i]);
752
        fd_recalibrate(&fdctrl->drives[i]);
786 753
    fdctrl_reset_fifo(fdctrl);
787 754
    if (do_irq)
788 755
        fdctrl_raise_irq(fdctrl, FD_SR0_RDYCHG);
......
826 793
/* Digital output register : 0x02 */
827 794
static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl)
828 795
{
829
    uint32_t retval = 0;
796
    uint32_t retval = fdctrl->dor;
830 797

  
831
    /* Drive motors state indicators */
832
    if (drv0(fdctrl)->drflags & FDRIVE_MOTOR_ON)
833
        retval |= FD_DOR_MOTEN0;
834
    if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON)
835
        retval |= FD_DOR_MOTEN1;
836
    /* DMA enable */
837
    if (fdctrl->dor & FD_DOR_DMAEN)
838
        retval |= FD_DOR_DMAEN;
839
    /* Reset indicator */
840
    if (!(fdctrl->state & FD_CTRL_RESET))
841
        retval |= FD_DOR_nRESET;
842 798
    /* Selected drive */
843 799
    retval |= fdctrl->cur_drv;
844 800
    FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
......
848 804

  
849 805
static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value)
850 806
{
851
    /* Reset mode */
852
    if (fdctrl->state & FD_CTRL_RESET) {
853
        if (!(value & FD_DOR_nRESET)) {
854
            FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
855
            return;
856
        }
857
    }
858 807
    FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
859 808

  
860 809
    /* Motors */
......
873 822
    else
874 823
        fdctrl->srb &= ~FD_SRB_DR0;
875 824

  
876
    /* Drive motors state indicators */
877
    if (value & FD_DOR_MOTEN1)
878
        fd_start(drv1(fdctrl));
879
    else
880
        fd_stop(drv1(fdctrl));
881
    if (value & FD_DOR_MOTEN0)
882
        fd_start(drv0(fdctrl));
883
    else
884
        fd_stop(drv0(fdctrl));
885
    /* DMA enable */
886
#if 0
887
    if (fdctrl->dma_chann != -1)
888
        fdctrl->dma_en = value & FD_DOR_DMAEN ? 1 : 0;
889
#endif
890 825
    /* Reset */
891 826
    if (!(value & FD_DOR_nRESET)) {
892
        if (!(fdctrl->state & FD_CTRL_RESET)) {
827
        if (fdctrl->dor & FD_DOR_nRESET) {
893 828
            FLOPPY_DPRINTF("controller enter RESET state\n");
894
            fdctrl->state |= FD_CTRL_RESET;
895 829
        }
896 830
    } else {
897
        if (fdctrl->state & FD_CTRL_RESET) {
831
        if (!(fdctrl->dor & FD_DOR_nRESET)) {
898 832
            FLOPPY_DPRINTF("controller out of RESET state\n");
899 833
            fdctrl_reset(fdctrl, 1);
900
            fdctrl->state &= ~(FD_CTRL_RESET | FD_CTRL_SLEEP);
834
            fdctrl->state &= ~FD_CTRL_SLEEP;
901 835
        }
902 836
    }
903 837
    /* Selected drive */
......
922 856
static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value)
923 857
{
924 858
    /* Reset mode */
925
    if (fdctrl->state & FD_CTRL_RESET) {
859
    if (!(fdctrl->dor & FD_DOR_nRESET)) {
926 860
        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
927 861
        return;
928 862
    }
......
937 871
{
938 872
    uint32_t retval = 0;
939 873

  
940
    fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET);
874
    fdctrl->dor |= FD_DOR_nRESET;
875
    fdctrl->state &= ~FD_CTRL_SLEEP;
941 876
    if (!(fdctrl->state & FD_CTRL_BUSY)) {
942 877
        /* Data transfer allowed */
943 878
        retval |= FD_MSR_RQM;
......
959 894
static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value)
960 895
{
961 896
    /* Reset mode */
962
    if (fdctrl->state & FD_CTRL_RESET) {
897
    if (!(fdctrl->dor & FD_DOR_nRESET)) {
963 898
        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
964 899
        return;
965 900
    }
966 901
    FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
967 902
    /* Reset: autoclear */
968 903
    if (value & FD_DSR_SWRESET) {
969
        fdctrl->state |= FD_CTRL_RESET;
904
        fdctrl->dor &= ~FD_DOR_nRESET;
970 905
        fdctrl_reset(fdctrl, 1);
971
        fdctrl->state &= ~FD_CTRL_RESET;
906
        fdctrl->dor |= FD_DOR_nRESET;
972 907
    }
973 908
    if (value & FD_DSR_PWRDOWN) {
974 909
        fdctrl->state |= FD_CTRL_SLEEP;
......
1618 1553

  
1619 1554
    fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK;
1620 1555
    cur_drv = get_cur_drv(fdctrl);
1621
    fd_start(cur_drv);
1622 1556
    if (fdctrl->fifo[2] <= cur_drv->track)
1623 1557
        cur_drv->dir = 1;
1624 1558
    else
......
1640 1574
    if (fdctrl->fifo[1] & 0x80)
1641 1575
        cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
1642 1576
    /* No result back */
1643
           fdctrl_reset_fifo(fdctrl);
1577
    fdctrl_reset_fifo(fdctrl);
1644 1578
}
1645 1579

  
1646 1580
static void fdctrl_handle_configure (fdctrl_t *fdctrl, int direction)
......
1692 1626

  
1693 1627
    fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK;
1694 1628
    cur_drv = get_cur_drv(fdctrl);
1695
    fd_start(cur_drv);
1696 1629
    cur_drv->dir = 0;
1697 1630
    if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
1698 1631
        cur_drv->track = cur_drv->max_track - 1;
......
1709 1642

  
1710 1643
    fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK;
1711 1644
    cur_drv = get_cur_drv(fdctrl);
1712
    fd_start(cur_drv);
1713 1645
    cur_drv->dir = 1;
1714 1646
    if (fdctrl->fifo[2] > cur_drv->track) {
1715 1647
        cur_drv->track = 0;
......
1772 1704

  
1773 1705
    cur_drv = get_cur_drv(fdctrl);
1774 1706
    /* Reset mode */
1775
    if (fdctrl->state & FD_CTRL_RESET) {
1707
    if (!(fdctrl->dor & FD_DOR_nRESET)) {
1776 1708
        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1777 1709
        return;
1778 1710
    }

Also available in: Unified diff