1*5a5d2f3dSPhilippe Mathieu-Daudé /* 2*5a5d2f3dSPhilippe Mathieu-Daudé * QEMU Floppy disk emulator (Intel 82078) 3*5a5d2f3dSPhilippe Mathieu-Daudé * 4*5a5d2f3dSPhilippe Mathieu-Daudé * Copyright (c) 2003, 2007 Jocelyn Mayer 5*5a5d2f3dSPhilippe Mathieu-Daudé * Copyright (c) 2008 Hervé Poussineau 6*5a5d2f3dSPhilippe Mathieu-Daudé * 7*5a5d2f3dSPhilippe Mathieu-Daudé * Permission is hereby granted, free of charge, to any person obtaining a copy 8*5a5d2f3dSPhilippe Mathieu-Daudé * of this software and associated documentation files (the "Software"), to deal 9*5a5d2f3dSPhilippe Mathieu-Daudé * in the Software without restriction, including without limitation the rights 10*5a5d2f3dSPhilippe Mathieu-Daudé * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11*5a5d2f3dSPhilippe Mathieu-Daudé * copies of the Software, and to permit persons to whom the Software is 12*5a5d2f3dSPhilippe Mathieu-Daudé * furnished to do so, subject to the following conditions: 13*5a5d2f3dSPhilippe Mathieu-Daudé * 14*5a5d2f3dSPhilippe Mathieu-Daudé * The above copyright notice and this permission notice shall be included in 15*5a5d2f3dSPhilippe Mathieu-Daudé * all copies or substantial portions of the Software. 16*5a5d2f3dSPhilippe Mathieu-Daudé * 17*5a5d2f3dSPhilippe Mathieu-Daudé * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18*5a5d2f3dSPhilippe Mathieu-Daudé * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19*5a5d2f3dSPhilippe Mathieu-Daudé * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20*5a5d2f3dSPhilippe Mathieu-Daudé * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21*5a5d2f3dSPhilippe Mathieu-Daudé * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22*5a5d2f3dSPhilippe Mathieu-Daudé * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23*5a5d2f3dSPhilippe Mathieu-Daudé * THE SOFTWARE. 24*5a5d2f3dSPhilippe Mathieu-Daudé */ 25*5a5d2f3dSPhilippe Mathieu-Daudé #ifndef HW_BLOCK_FDC_INTERNAL_H 26*5a5d2f3dSPhilippe Mathieu-Daudé #define HW_BLOCK_FDC_INTERNAL_H 27*5a5d2f3dSPhilippe Mathieu-Daudé 28*5a5d2f3dSPhilippe Mathieu-Daudé #include "hw/block/block.h" 29*5a5d2f3dSPhilippe Mathieu-Daudé #include "hw/block/fdc.h" 30*5a5d2f3dSPhilippe Mathieu-Daudé #include "qapi/qapi-types-block.h" 31*5a5d2f3dSPhilippe Mathieu-Daudé 32*5a5d2f3dSPhilippe Mathieu-Daudé typedef struct FDCtrl FDCtrl; 33*5a5d2f3dSPhilippe Mathieu-Daudé 34*5a5d2f3dSPhilippe Mathieu-Daudé /* Floppy bus emulation */ 35*5a5d2f3dSPhilippe Mathieu-Daudé 36*5a5d2f3dSPhilippe Mathieu-Daudé typedef struct FloppyBus { 37*5a5d2f3dSPhilippe Mathieu-Daudé BusState bus; 38*5a5d2f3dSPhilippe Mathieu-Daudé FDCtrl *fdc; 39*5a5d2f3dSPhilippe Mathieu-Daudé } FloppyBus; 40*5a5d2f3dSPhilippe Mathieu-Daudé 41*5a5d2f3dSPhilippe Mathieu-Daudé /* Floppy disk drive emulation */ 42*5a5d2f3dSPhilippe Mathieu-Daudé 43*5a5d2f3dSPhilippe Mathieu-Daudé typedef enum FDriveRate { 44*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_RATE_500K = 0x00, /* 500 Kbps */ 45*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_RATE_300K = 0x01, /* 300 Kbps */ 46*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_RATE_250K = 0x02, /* 250 Kbps */ 47*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_RATE_1M = 0x03, /* 1 Mbps */ 48*5a5d2f3dSPhilippe Mathieu-Daudé } FDriveRate; 49*5a5d2f3dSPhilippe Mathieu-Daudé 50*5a5d2f3dSPhilippe Mathieu-Daudé typedef enum FDriveSize { 51*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_SIZE_UNKNOWN, 52*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_SIZE_350, 53*5a5d2f3dSPhilippe Mathieu-Daudé FDRIVE_SIZE_525, 54*5a5d2f3dSPhilippe Mathieu-Daudé } FDriveSize; 55*5a5d2f3dSPhilippe Mathieu-Daudé 56*5a5d2f3dSPhilippe Mathieu-Daudé typedef struct FDFormat { 57*5a5d2f3dSPhilippe Mathieu-Daudé FloppyDriveType drive; 58*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t last_sect; 59*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t max_track; 60*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t max_head; 61*5a5d2f3dSPhilippe Mathieu-Daudé FDriveRate rate; 62*5a5d2f3dSPhilippe Mathieu-Daudé } FDFormat; 63*5a5d2f3dSPhilippe Mathieu-Daudé 64*5a5d2f3dSPhilippe Mathieu-Daudé typedef enum FDiskFlags { 65*5a5d2f3dSPhilippe Mathieu-Daudé FDISK_DBL_SIDES = 0x01, 66*5a5d2f3dSPhilippe Mathieu-Daudé } FDiskFlags; 67*5a5d2f3dSPhilippe Mathieu-Daudé 68*5a5d2f3dSPhilippe Mathieu-Daudé typedef struct FDrive { 69*5a5d2f3dSPhilippe Mathieu-Daudé FDCtrl *fdctrl; 70*5a5d2f3dSPhilippe Mathieu-Daudé BlockBackend *blk; 71*5a5d2f3dSPhilippe Mathieu-Daudé BlockConf *conf; 72*5a5d2f3dSPhilippe Mathieu-Daudé /* Drive status */ 73*5a5d2f3dSPhilippe Mathieu-Daudé FloppyDriveType drive; /* CMOS drive type */ 74*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t perpendicular; /* 2.88 MB access mode */ 75*5a5d2f3dSPhilippe Mathieu-Daudé /* Position */ 76*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t head; 77*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t track; 78*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t sect; 79*5a5d2f3dSPhilippe Mathieu-Daudé /* Media */ 80*5a5d2f3dSPhilippe Mathieu-Daudé FloppyDriveType disk; /* Current disk type */ 81*5a5d2f3dSPhilippe Mathieu-Daudé FDiskFlags flags; 82*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t last_sect; /* Nb sector per track */ 83*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t max_track; /* Nb of tracks */ 84*5a5d2f3dSPhilippe Mathieu-Daudé uint16_t bps; /* Bytes per sector */ 85*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t ro; /* Is read-only */ 86*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t media_changed; /* Is media changed */ 87*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t media_rate; /* Data rate of medium */ 88*5a5d2f3dSPhilippe Mathieu-Daudé 89*5a5d2f3dSPhilippe Mathieu-Daudé bool media_validated; /* Have we validated the media? */ 90*5a5d2f3dSPhilippe Mathieu-Daudé } FDrive; 91*5a5d2f3dSPhilippe Mathieu-Daudé 92*5a5d2f3dSPhilippe Mathieu-Daudé struct FDCtrl { 93*5a5d2f3dSPhilippe Mathieu-Daudé qemu_irq irq; 94*5a5d2f3dSPhilippe Mathieu-Daudé /* Controller state */ 95*5a5d2f3dSPhilippe Mathieu-Daudé QEMUTimer *result_timer; 96*5a5d2f3dSPhilippe Mathieu-Daudé int dma_chann; 97*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t phase; 98*5a5d2f3dSPhilippe Mathieu-Daudé IsaDma *dma; 99*5a5d2f3dSPhilippe Mathieu-Daudé /* Controller's identification */ 100*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t version; 101*5a5d2f3dSPhilippe Mathieu-Daudé /* HW */ 102*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t sra; 103*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t srb; 104*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t dor; 105*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t dor_vmstate; /* only used as temp during vmstate */ 106*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t tdr; 107*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t dsr; 108*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t msr; 109*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t cur_drv; 110*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t status0; 111*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t status1; 112*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t status2; 113*5a5d2f3dSPhilippe Mathieu-Daudé /* Command FIFO */ 114*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t *fifo; 115*5a5d2f3dSPhilippe Mathieu-Daudé int32_t fifo_size; 116*5a5d2f3dSPhilippe Mathieu-Daudé uint32_t data_pos; 117*5a5d2f3dSPhilippe Mathieu-Daudé uint32_t data_len; 118*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t data_state; 119*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t data_dir; 120*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t eot; /* last wanted sector */ 121*5a5d2f3dSPhilippe Mathieu-Daudé /* States kept only to be returned back */ 122*5a5d2f3dSPhilippe Mathieu-Daudé /* precompensation */ 123*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t precomp_trk; 124*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t config; 125*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t lock; 126*5a5d2f3dSPhilippe Mathieu-Daudé /* Power down config (also with status regB access mode */ 127*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t pwrd; 128*5a5d2f3dSPhilippe Mathieu-Daudé /* Floppy drives */ 129*5a5d2f3dSPhilippe Mathieu-Daudé FloppyBus bus; 130*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t num_floppies; 131*5a5d2f3dSPhilippe Mathieu-Daudé FDrive drives[MAX_FD]; 132*5a5d2f3dSPhilippe Mathieu-Daudé struct { 133*5a5d2f3dSPhilippe Mathieu-Daudé FloppyDriveType type; 134*5a5d2f3dSPhilippe Mathieu-Daudé } qdev_for_drives[MAX_FD]; 135*5a5d2f3dSPhilippe Mathieu-Daudé int reset_sensei; 136*5a5d2f3dSPhilippe Mathieu-Daudé FloppyDriveType fallback; /* type=auto failure fallback */ 137*5a5d2f3dSPhilippe Mathieu-Daudé /* Timers state */ 138*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t timer0; 139*5a5d2f3dSPhilippe Mathieu-Daudé uint8_t timer1; 140*5a5d2f3dSPhilippe Mathieu-Daudé }; 141*5a5d2f3dSPhilippe Mathieu-Daudé 142*5a5d2f3dSPhilippe Mathieu-Daudé extern const FDFormat fd_formats[]; 143*5a5d2f3dSPhilippe Mathieu-Daudé extern const VMStateDescription vmstate_fdc; 144*5a5d2f3dSPhilippe Mathieu-Daudé 145*5a5d2f3dSPhilippe Mathieu-Daudé uint32_t fdctrl_read(void *opaque, uint32_t reg); 146*5a5d2f3dSPhilippe Mathieu-Daudé void fdctrl_write(void *opaque, uint32_t reg, uint32_t value); 147*5a5d2f3dSPhilippe Mathieu-Daudé void fdctrl_reset(FDCtrl *fdctrl, int do_irq); 148*5a5d2f3dSPhilippe Mathieu-Daudé void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp); 149*5a5d2f3dSPhilippe Mathieu-Daudé 150*5a5d2f3dSPhilippe Mathieu-Daudé int fdctrl_transfer_handler(void *opaque, int nchan, int dma_pos, int dma_len); 151*5a5d2f3dSPhilippe Mathieu-Daudé 152*5a5d2f3dSPhilippe Mathieu-Daudé void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds); 153*5a5d2f3dSPhilippe Mathieu-Daudé 154*5a5d2f3dSPhilippe Mathieu-Daudé #endif 155