VirtualBox

Changeset 36705 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 18, 2011 11:44:22 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71221
Message:

fdc: Improved floppy emulation.

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r36339 r36705  
    37663766                    ataSetSignature(s);
    37673767                ataCmdError(s, ABRT_ERR);
     3768                ataUnsetStatus(s, ATA_STAT_READY);
    37683769                ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
    37693770            }
    37703771            break;
     3772        case ATA_RECALIBRATE:
     3773            if (s->fATAPI)
     3774                goto abort_cmd;
    37713775        case ATA_INITIALIZE_DEVICE_PARAMETERS:
    3772         case ATA_RECALIBRATE:
    37733776            ataCmdOK(s, ATA_STAT_SEEK);
    37743777            ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
     
    39873990        abort_cmd:
    39883991            ataCmdError(s, ABRT_ERR);
     3992            if (s->fATAPI)
     3993                ataUnsetStatus(s, ATA_STAT_READY);
    39893994            ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
    39903995            break;
  • trunk/src/VBox/Devices/Storage/fdc.c

    r35353 r36705  
    134134} fdrive_flags_t;
    135135
     136typedef enum fdrive_rate_t {
     137    FDRIVE_RATE_500K = 0x00,  /* 500 Kbps               */
     138    FDRIVE_RATE_300K = 0x01,  /* 300 Kbps               */
     139    FDRIVE_RATE_250K = 0x02,  /* 250 Kbps               */
     140    FDRIVE_RATE_1M   = 0x03   /* 1 Mbps                 */
     141} fdrive_rate_t;
     142
    136143/**
    137144 * The status for one drive.
     
    164171    /** The LED for this LUN. */
    165172    PDMLED                          Led;
    166     /** Media change flag. */
    167     bool                            fMediaChanged;
    168173#endif
    169174    /* Drive status */
     
    181186    uint16_t bps;             /* Bytes per sector       */
    182187    uint8_t ro;               /* Is read-only           */
     188    uint8_t media_rate;       /* Data rate of medium    */
    183189} fdrive_t;
    184190
     
    191197    drv->last_sect = 0;
    192198    drv->max_track = 0;
    193     drv->fMediaChanged = true;
    194199}
    195200
     
    270275    uint8_t max_track;
    271276    uint8_t max_head;
     277    fdrive_rate_t rate;
    272278    const char *str;
    273279} fd_format_t;
    274280
    275 static const fd_format_t fd_formats[] = {
     281static fd_format_t fd_formats[] = {
    276282    /* First entry is default format */
    277283    /* 1.44 MB 3"1/2 floppy disks */
    278     { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
    279     { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, "1.6 MB 3\"1/2", },
    280     { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
    281     { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
    282     { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
    283     { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
    284     { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
    285     { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
     284    { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, FDRIVE_RATE_500K, "1.44 MB 3\"1/2", },
     285    { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, FDRIVE_RATE_500K, "1.6 MB 3\"1/2", },
     286    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, FDRIVE_RATE_500K, "1.68 MB 3\"1/2", },
     287    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, FDRIVE_RATE_500K, "1.72 MB 3\"1/2", },
     288    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, FDRIVE_RATE_500K, "1.74 MB 3\"1/2", },
     289    { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, FDRIVE_RATE_500K, "1.76 MB 3\"1/2", },
     290    { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, FDRIVE_RATE_500K, "1.84 MB 3\"1/2", },
     291    { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, FDRIVE_RATE_500K, "1.92 MB 3\"1/2", },
    286292    /* 2.88 MB 3"1/2 floppy disks */
    287     { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
    288     { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
    289     { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, "3.2 MB 3\"1/2", },
    290     { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
    291     { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
     293    { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, FDRIVE_RATE_1M,   "2.88 MB 3\"1/2", },
     294    { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, FDRIVE_RATE_1M,   "3.12 MB 3\"1/2", },
     295    { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, FDRIVE_RATE_1M,    "3.2 MB 3\"1/2", },
     296    { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, FDRIVE_RATE_1M,   "3.52 MB 3\"1/2", },
     297    { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, FDRIVE_RATE_1M,   "3.84 MB 3\"1/2", },
    292298    /* 720 kB 3"1/2 floppy disks */
    293     { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 1, "720 kB 3\"1/2", },
    294     { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, "800 kB 3\"1/2", },
    295     { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, "820 kB 3\"1/2", },
    296     { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, "830 kB 3\"1/2", },
    297     { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
    298     { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
     299    { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 1, FDRIVE_RATE_250K, "720 kB 3\"1/2", },
     300    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, FDRIVE_RATE_250K, "800 kB 3\"1/2", },
     301    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, FDRIVE_RATE_250K, "820 kB 3\"1/2", },
     302    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, FDRIVE_RATE_250K, "830 kB 3\"1/2", },
     303    { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, FDRIVE_RATE_250K, "1.04 MB 3\"1/2", },
     304    { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, FDRIVE_RATE_250K, "1.12 MB 3\"1/2", },
    299305    /* 1.2 MB 5"1/4 floppy disks */
    300     { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1,  "1.2 kB 5\"1/4", },
    301     { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
    302     { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
    303     { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
    304     { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, "1.6 MB 5\"1/4", },
     306    { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, FDRIVE_RATE_500K,  "1.2 MB 5\"1/4", },
     307    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, FDRIVE_RATE_500K, "1.44 MB 5\"1/4", },
     308    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, FDRIVE_RATE_500K, "1.48 MB 5\"1/4", },
     309    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, FDRIVE_RATE_500K, "1.49 MB 5\"1/4", },
     310    { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, FDRIVE_RATE_500K, "1.6 MB 5\"1/4", },
    305311    /* 720 kB 5"1/4 floppy disks */
    306     { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 80, 1, "720 kB 5\"1/4", },
    307     { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, "880 kB 5\"1/4", },
     312    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 80, 1, FDRIVE_RATE_250K, "720 kB 5\"1/4", },
     313    { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, FDRIVE_RATE_250K, "880 kB 5\"1/4", },
    308314    /* 360 kB 5"1/4 floppy disks */
    309     { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 1, "360 kB 5\"1/4", },
    310     { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 0, "180 kB 5\"1/4", },
    311     { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", },
    312     { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", },
     315    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 1, FDRIVE_RATE_300K, "360 kB 5\"1/4", },
     316    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 0, FDRIVE_RATE_300K, "180 kB 5\"1/4", },
     317    { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, FDRIVE_RATE_300K, "410 kB 5\"1/4", },
     318    { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, FDRIVE_RATE_300K, "420 kB 5\"1/4", },
    313319    /* 320 kB 5"1/4 floppy disks */
    314     { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 1, "320 kB 5\"1/4", },
    315     { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 0, "160 kB 5\"1/4", },
     320    { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 1, FDRIVE_RATE_250K, "320 kB 5\"1/4", },
     321    { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 0, FDRIVE_RATE_250K, "160 kB 5\"1/4", },
    316322    /* 360 kB must match 5"1/4 better than 3"1/2... */
    317     { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 0, "360 kB 3\"1/2", },
     323    { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 0, FDRIVE_RATE_250K, "360 kB 3\"1/2", },
    318324    /* end */
    319     { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
     325    { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, 0, NULL, },
    320326};
    321327
     
    381387            last_sect = parse->last_sect;
    382388            drv->drive = parse->drive;
     389#ifdef VBOX
     390            drv->media_rate = parse->rate;
     391#endif
    383392            FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
    384393                           nb_heads, max_track, last_sect, ro ? "ro" : "rw");
     394            LogRel(("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
     395                    nb_heads, max_track, last_sect, ro ? "ro" : "rw"));
    385396        }
    386397        if (nb_heads == 1) {
     
    397408        drv->max_track = 0;
    398409        drv->flags &= ~FDISK_DBL_SIDES;
     410        drv->dsk_chg = true;    /* Disk change line active. */
    399411    }
    400412}
     
    416428#endif /* VBOX */
    417429static void fdctrl_raise_irq(fdctrl_t *fdctrl, uint8_t status0);
     430static fdrive_t *get_cur_drv(fdctrl_t *fdctrl);
    418431
    419432static void fdctrl_result_timer(void *opaque);
     
    429442static void fdctrl_write_data(fdctrl_t *fdctrl, uint32_t value);
    430443static uint32_t fdctrl_read_dir(fdctrl_t *fdctrl);
     444static void fdctrl_write_ccr(fdctrl_t *fdctrl, uint32_t value);
    431445
    432446enum {
     
    452466    FD_REG_DSR = 0x04,
    453467    FD_REG_FIFO = 0x05,
    454     FD_REG_DIR = 0x07
     468    FD_REG_DIR = 0x07,
     469    FD_REG_CCR = 0x07
    455470};
    456471
     
    505520
    506521enum {
     522    FD_SR1_MA       = 0x01, /* Missing address mark */
     523    FD_SR1_NW       = 0x02, /* Not writable */
    507524    FD_SR1_EC       = 0x80  /* End of cylinder */
    508525};
     
    703720        fdctrl_write_data(fdctrl, value);
    704721        break;
     722    case FD_REG_CCR:
     723        fdctrl_write_ccr(fdctrl, value);
     724        break;
    705725    default:
    706726        break;
     
    719739    fdrive_t *drv = PDMIMOUNTNOTIFY_2_FDRIVE (pInterface);
    720740    LogFlow(("fdMountNotify:\n"));
    721     drv->fMediaChanged = true;
     741    fd_revalidate(drv);
    722742}
    723743
     
    731751    fdrive_t *drv = PDMIMOUNTNOTIFY_2_FDRIVE (pInterface);
    732752    LogFlow(("fdUnmountNotify:\n"));
    733     drv->fMediaChanged = true;
     753    fd_revalidate(drv);
    734754}
    735755#endif
     
    759779        fdctrl->sra |= FD_SRA_INTPEND;
    760780    }
     781    if (status0 & FD_SR0_SEEK) {
     782        fdrive_t    *cur_drv;
     783
     784        /* A seek clears the disk change line (if a disk is inserted). */
     785        cur_drv = get_cur_drv(fdctrl);
     786        if (cur_drv->max_track)
     787            cur_drv->dsk_chg = false;
     788    }
     789
    761790    fdctrl->reset_sensei = 0;
    762791    fdctrl->status0 = status0;
     
    969998}
    970999
     1000/* Configuration control register : 0x07 (write) */
     1001static void fdctrl_write_ccr(fdctrl_t *fdctrl, uint32_t value)
     1002{
     1003    /* Reset mode */
     1004    if (!(fdctrl->dor & FD_DOR_nRESET)) {
     1005        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
     1006        return;
     1007    }
     1008    FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
     1009
     1010    /* Only the rate selection bits used in AT mode, and we
     1011     * store those in the DSR.
     1012     */
     1013    fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) | (value & FD_DSR_DRATEMASK);
     1014}
     1015
    9711016static int fdctrl_media_changed(fdrive_t *drv)
    9721017{
     1018#ifdef VBOX
     1019    return drv->dsk_chg;
     1020#else
    9731021    int ret;
    9741022
    975 #ifdef VBOX
    976     if (!drv->pDrvBlock)
    977         return 0;
    978     ret = drv->fMediaChanged;
    979     drv->fMediaChanged = false;
    980 #else
    9811023    if (!drv->bs)
    9821024        return 0;
    9831025    ret = bdrv_media_changed(drv->bs);
    984 #endif
    9851026    if (ret) {
    9861027        fd_revalidate(drv);
    9871028    }
    9881029    return ret;
     1030#endif
    9891031}
    9901032
     
    9941036    uint32_t retval = 0;
    9951037
     1038#ifdef VBOX
     1039    if (fdctrl_media_changed(get_cur_drv(fdctrl)))
     1040#else
    9961041    if (fdctrl_media_changed(drv0(fdctrl))
    9971042     || fdctrl_media_changed(drv1(fdctrl))
     
    10011046#endif
    10021047        )
     1048#endif
    10031049        retval |= FD_DIR_DSKCHG;
    10041050    if (retval != 0)
     
    11421188        break;
    11431189    }
    1144 
     1190    /* Check the data rate. If the programmed data rate does not match
     1191     * the currently inserted medium, the operation has to fail.
     1192     */
     1193#ifdef VBOX
     1194    if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
     1195        FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n",
     1196                       fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
     1197        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
     1198        fdctrl->fifo[3] = kt;
     1199        fdctrl->fifo[4] = kh;
     1200        fdctrl->fifo[5] = ks;
     1201        return;
     1202    }
     1203#endif
    11451204    /* Set the FIFO state */
    11461205    fdctrl->data_dir = direction;
     
    13591418                 * LED or attempt any writes. A real floppy doesn't attempt
    13601419                 * to write to readonly media either. */
    1361                 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, cur_drv->ro << 1,
     1420                fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
    13621421                                     0x00);
    13631422                goto transfer_error;
     
    17841843    cur_drv = get_cur_drv(fdctrl);
    17851844    fdctrl_reset_fifo(fdctrl);
    1786     if (cur_drv->max_track && fdctrl->fifo[2] > cur_drv->max_track) {
     1845#ifdef VBOX
     1846    /* The seek command just sends step pulses to the drive and doesn't care if
     1847     * there's a medium inserted or if it's banging the head against the drive.
     1848     */
     1849    cur_drv->track = fdctrl->fifo[2];
     1850    /* Raise Interrupt */
     1851    fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
     1852#else
     1853    if (fdctrl->fifo[2] > cur_drv->max_track) {
    17871854        fdctrl_raise_irq(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK);
    17881855    } else {
     
    17911858        fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
    17921859    }
     1860#endif
    17931861}
    17941862
     
    19962064        cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
    19972065    }
    1998     fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
     2066    /* READ_ID can't automatically succeed! */
     2067#ifdef VBOX
     2068    if (//!cur_drv->fMediaPresent ||
     2069        ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate)) {
     2070        FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n",
     2071                       fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
     2072        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
     2073    }
     2074    else
     2075#endif
     2076        fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
    19992077}
    20002078
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette