Changeset 82025 in vbox
- Timestamp:
- Nov 20, 2019 1:48:06 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevFdc.cpp
r82024 r82025 465 465 static void fdctrl_reset(fdctrl_t *fdctrl, int do_irq); 466 466 static void fdctrl_reset_fifo(fdctrl_t *fdctrl); 467 static void fdctrl_raise_irq(fdctrl_t *fdctrl, uint8_t status0); 467 468 static fdrive_t *get_cur_drv(fdctrl_t *fdctrl); 468 469 … … 650 651 /* Controller state */ 651 652 TMTIMERHANDLE hResultTimer; 652 653 /* Interrupt delay timers. */654 TMTIMERHANDLE hXferDelayTimer;655 TMTIMERHANDLE hIrqDelayTimer;656 uint16_t uIrqDelayMsec;657 uint8_t st0;658 uint8_t st1;659 uint8_t st2;660 661 653 uint8_t sra; 662 654 uint8_t srb; … … 778 770 } 779 771 780 static void fdctrl_raise_irq _now(fdctrl_t *fdctrl, uint8_t status0)772 static void fdctrl_raise_irq(fdctrl_t *fdctrl, uint8_t status0) 781 773 { 782 774 if (!(fdctrl->sra & FD_SRA_INTPEND)) { … … 797 789 fdctrl->status0 = status0; 798 790 FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0); 799 }800 801 static void fdctrl_raise_irq(fdctrl_t *fdctrl, uint8_t status0)802 {803 if (!fdctrl->uIrqDelayMsec)804 {805 /* If not IRQ delay needed, trigger the interrupt now. */806 fdctrl_raise_irq_now(fdctrl, status0);807 }808 else809 {810 /* Otherwise schedule completion after a short while. */811 fdctrl->st0 = status0;812 PDMDevHlpTimerSetMillies(fdctrl->pDevIns, fdctrl->hIrqDelayTimer, fdctrl->uIrqDelayMsec);813 }814 791 } 815 792 … … 1117 1094 1118 1095 /* Callback for transfer end (stop or abort) */ 1119 static void fdctrl_stop_transfer _now(fdctrl_t *fdctrl, uint8_t status0,1120 1096 static void fdctrl_stop_transfer(fdctrl_t *fdctrl, uint8_t status0, 1097 uint8_t status1, uint8_t status2) 1121 1098 { 1122 1099 fdrive_t *cur_drv; … … 1144 1121 fdctrl->msr &= ~FD_MSR_NONDMA; 1145 1122 fdctrl_set_fifo(fdctrl, 7, 1); 1146 }1147 1148 static void fdctrl_stop_transfer(fdctrl_t *fdctrl, uint8_t status0,1149 uint8_t status1, uint8_t status2)1150 {1151 if (!fdctrl->uIrqDelayMsec)1152 {1153 /* If not IRQ delay needed, just stop the transfer and trigger IRQ now. */1154 fdctrl_stop_transfer_now(fdctrl, status0, status1, status2);1155 }1156 else1157 {1158 /* Otherwise schedule completion after a short while. */1159 fdctrl->st0 = status0;1160 fdctrl->st1 = status1;1161 fdctrl->st2 = status2;1162 PDMDevHlpTimerSetMillies(fdctrl->pDevIns, fdctrl->hXferDelayTimer, fdctrl->uIrqDelayMsec);1163 }1164 1123 } 1165 1124 … … 1283 1242 if (direction != FD_DIR_WRITE) 1284 1243 fdctrl->msr |= FD_MSR_DIO; 1285 1286 1244 /* IO based transfer: calculate len */ 1287 1245 fdctrl_raise_irq(fdctrl, 0x00); 1246 1288 1247 return; 1289 1248 } … … 2209 2168 FLOPPY_DPRINTF("read id when no disk in drive\n"); 2210 2169 /// @todo This is wrong! Command should not complete. 2211 fdctrl_stop_transfer _now(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD);2170 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD); 2212 2171 } else if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) { 2213 2172 FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n", 2214 2173 fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate); 2215 fdctrl_stop_transfer _now(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD);2174 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD); 2216 2175 } else if (cur_drv->track >= cur_drv->max_track) { 2217 2176 FLOPPY_DPRINTF("read id past last track (%d >= %d)\n", 2218 2177 cur_drv->track, cur_drv->max_track); 2219 2178 cur_drv->ltrk = 0; 2220 fdctrl_stop_transfer _now(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD);2179 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD); 2221 2180 } 2222 2181 else 2223 fdctrl_stop_transfer _now(fdctrl, 0x00, 0x00, 0x00);2182 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 2224 2183 } 2225 2184 … … 2274 2233 2275 2234 /** 2276 * @callback_method_impl{FNTMTIMERDEV}2277 */2278 static DECLCALLBACK(void) fdcTransferDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)2279 {2280 RT_NOREF(pDevIns, pTimer);2281 fdctrl_t *fdctrl = (fdctrl_t *)pvUser;2282 fdctrl_stop_transfer_now(fdctrl, fdctrl->st0, fdctrl->st1, fdctrl->st2);2283 }2284 2285 /**2286 * @callback_method_impl{FNTMTIMERDEV}2287 */2288 static DECLCALLBACK(void) fdcIrqDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)2289 {2290 RT_NOREF(pDevIns, pTimer);2291 fdctrl_t *fdctrl = (fdctrl_t *)pvUser;2292 fdctrl_raise_irq_now(fdctrl, fdctrl->st0);2293 }2294 2295 2296 2297 /* -=-=-=-=-=-=-=-=- I/O Port Access Handlers -=-=-=-=-=-=-=-=- */2298 /**2299 2235 * @callback_method_impl{FNIOMIOPORTNEWIN, Handling 0x3f1..0x3f5 accesses.} 2300 2236 */ … … 2355 2291 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 2356 2292 unsigned int i; 2357 int rc;2358 2293 2359 2294 /* Save the FDC I/O registers... */ … … 2403 2338 pHlp->pfnSSMPutU8(pSSM, d->sect); 2404 2339 } 2405 rc = pHlp->pfnTimerSave(pDevIns, pThis->hXferDelayTimer, pSSM);2406 if (RT_FAILURE(rc))2407 return rc;2408 2409 rc = pHlp->pfnTimerSave(pDevIns, pThis->hIrqDelayTimer, pSSM);2410 if (RT_FAILURE(rc))2411 return rc;2412 2413 2340 return pHlp->pfnTimerSave(pDevIns, pThis->hResultTimer, pSSM); 2414 2341 } … … 2831 2758 * Validate configuration. 2832 2759 */ 2833 PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "IRQ|DMA|MemMapped|IOBase|StatusA |IRQDelay", "");2760 PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "IRQ|DMA|MemMapped|IOBase|StatusA", ""); 2834 2761 2835 2762 /* … … 2848 2775 rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "MemMapped", &fMemMapped, false); 2849 2776 AssertMsgRCReturn(rc, ("Configuration error: Failed to read bool value MemMapped rc=%Rrc\n", rc), rc); 2850 2851 uint16_t uIrqDelay;2852 rc = CFGMR3QueryU16Def(pCfg, "IRQDelay", &uIrqDelay, 0);2853 AssertMsgRCReturn(rc, ("Configuration error: Failed to read U16 IRQDelay, rc=%Rrc\n", rc), rc);2854 2777 2855 2778 bool fStatusA; … … 2899 2822 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Timer", &pThis->hResultTimer); 2900 2823 AssertRCReturn(rc, rc); 2901 2902 /*2903 * Create the transfer delay timer.2904 */2905 rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, fdcTransferDelayTimer, pThis,2906 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Transfer Delay Timer", &pThis->hXferDelayTimer);2907 if (RT_FAILURE(rc))2908 return rc;2909 2910 /*2911 * Create the IRQ delay timer.2912 */2913 rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, fdcIrqDelayTimer, pThis,2914 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC IRQ Delay Timer", &pThis->hIrqDelayTimer);2915 if (RT_FAILURE(rc))2916 return rc;2917 2918 pThis->uIrqDelayMsec = uIrqDelay;2919 2824 2920 2825 /*
Note:
See TracChangeset
for help on using the changeset viewer.