Changeset 48081 in vbox for trunk/src/VBox
- Timestamp:
- Aug 27, 2013 1:03:34 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevFdc.cpp
r48059 r48081 177 177 uint8_t track; 178 178 uint8_t sect; 179 uint8_t ltrk; /* Logical track */ 179 180 /* Media */ 180 181 fdrive_flags_t flags; … … 287 288 drv->sect = sect; 288 289 } 290 drv->ltrk = drv->track; 289 291 290 292 return ret; … … 297 299 drv->head = 0; 298 300 drv->track = 0; 301 drv->ltrk = 0; 299 302 drv->sect = 1; 300 303 } … … 535 538 FD_DIR_SCANE = 2, 536 539 FD_DIR_SCANL = 3, 537 FD_DIR_SCANH = 4 540 FD_DIR_SCANH = 4, 541 FD_DIR_FORMAT = 5 538 542 }; 539 543 … … 1165 1169 } else { 1166 1170 cur_drv->head = 0; 1167 cur_drv-> track++;1171 cur_drv->ltrk++; 1168 1172 if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) 1169 1173 return 0; 1170 1174 } 1171 1175 } else { 1172 cur_drv-> track++;1176 cur_drv->ltrk++; 1173 1177 return 0; 1174 1178 } … … 1195 1199 fdctrl->fifo[1] = status1; 1196 1200 fdctrl->fifo[2] = status2; 1197 fdctrl->fifo[3] = cur_drv-> track;1201 fdctrl->fifo[3] = cur_drv->ltrk; 1198 1202 fdctrl->fifo[4] = cur_drv->head; 1199 1203 fdctrl->fifo[5] = cur_drv->sect; … … 1316 1320 direction == FD_DIR_SCANH) && dma_mode == 0) || 1317 1321 (direction == FD_DIR_WRITE && dma_mode == 2) || 1318 (direction == FD_DIR_READ && dma_mode == 1)) {1322 (direction == FD_DIR_READ && (dma_mode == 1 || dma_mode == 0))) { 1319 1323 /* No access is allowed until DMA transfer has completed */ 1320 1324 fdctrl->msr &= ~FD_MSR_RQM; … … 1344 1348 } 1345 1349 1350 /* Prepare a format data transfer (either DMA or FIFO) */ 1351 static void fdctrl_start_format(fdctrl_t *fdctrl) 1352 { 1353 fdrive_t *cur_drv; 1354 uint8_t ns, dp, kh, kt, ks; 1355 1356 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 1357 cur_drv = get_cur_drv(fdctrl); 1358 kt = cur_drv->track; 1359 kh = (fdctrl->fifo[1] & 0x04) >> 2; 1360 ns = fdctrl->fifo[3]; 1361 dp = fdctrl->fifo[5]; 1362 ks = 1; 1363 FLOPPY_DPRINTF("Start format at %d %d %02x, %d sect, pat %02x (%d)\n", 1364 GET_CUR_DRV(fdctrl), kh, kt, ns, dp, 1365 fd_sector_calc(kh, kt, ks, cur_drv->last_sect, NUM_SIDES(cur_drv))); 1366 switch (fd_seek(cur_drv, kh, kt, ks, false)) { 1367 case 2: 1368 /* sect too big */ 1369 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1370 fdctrl->fifo[3] = kt; 1371 fdctrl->fifo[4] = kh; 1372 fdctrl->fifo[5] = ks; 1373 return; 1374 case 3: 1375 /* track too big */ 1376 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00); 1377 fdctrl->fifo[3] = kt; 1378 fdctrl->fifo[4] = kh; 1379 fdctrl->fifo[5] = ks; 1380 return; 1381 case 4: 1382 /* No seek enabled */ 1383 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1384 fdctrl->fifo[3] = kt; 1385 fdctrl->fifo[4] = kh; 1386 fdctrl->fifo[5] = ks; 1387 return; 1388 case 1: 1389 break; 1390 default: 1391 break; 1392 } 1393 /* It's not clear what should happen if the data rate does not match. */ 1394 #if 0 1395 /* Check the data rate. If the programmed data rate does not match 1396 * the currently inserted medium, the operation has to fail. 1397 */ 1398 if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) { 1399 FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n", 1400 fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate); 1401 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, FD_SR2_MD); 1402 fdctrl->fifo[3] = kt; 1403 fdctrl->fifo[4] = kh; 1404 fdctrl->fifo[5] = ks; 1405 return; 1406 } 1407 #endif 1408 /* Set the FIFO state */ 1409 fdctrl->data_dir = FD_DIR_FORMAT; 1410 fdctrl->data_pos = 0; 1411 fdctrl->msr |= FD_MSR_CMDBUSY; 1412 fdctrl->data_state &= ~(FD_STATE_MULTI | FD_STATE_SEEK); 1413 fdctrl->data_len = ns * 4; 1414 fdctrl->eot = ns; 1415 if (fdctrl->dor & FD_DOR_DMAEN) { 1416 int dma_mode; 1417 /* DMA transfer are enabled. Check if DMA channel is well programmed */ 1418 #ifndef VBOX 1419 dma_mode = DMA_get_channel_mode(fdctrl->dma_chann); 1420 #else 1421 dma_mode = PDMDevHlpDMAGetChannelMode (fdctrl->pDevIns, fdctrl->dma_chann); 1422 #endif 1423 dma_mode = (dma_mode >> 2) & 3; 1424 FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n", 1425 dma_mode, fdctrl->data_dir, 1426 (128 << fdctrl->fifo[2]) * 1427 (cur_drv->last_sect + 1), fdctrl->data_len); 1428 if (fdctrl->data_dir == FD_DIR_FORMAT && dma_mode == 2) { 1429 /* No access is allowed until DMA transfer has completed */ 1430 fdctrl->msr &= ~FD_MSR_RQM; 1431 /* Now, we just have to wait for the DMA controller to 1432 * recall us... 1433 */ 1434 #ifndef VBOX 1435 DMA_hold_DREQ(fdctrl->dma_chann); 1436 DMA_schedule(fdctrl->dma_chann); 1437 #else 1438 PDMDevHlpDMASetDREQ (fdctrl->pDevIns, fdctrl->dma_chann, 1); 1439 PDMDevHlpDMASchedule (fdctrl->pDevIns); 1440 #endif 1441 return; 1442 } else { 1443 FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, fdctrl->data_dir); 1444 } 1445 } 1446 FLOPPY_DPRINTF("start non-DMA format\n"); 1447 fdctrl->msr |= FD_MSR_NONDMA; 1448 /* IO based transfer: calculate len */ 1449 fdctrl_raise_irq(fdctrl, 0x00); 1450 1451 return; 1452 } 1453 1346 1454 /* Prepare a transfer of deleted data */ 1347 1455 static void fdctrl_start_transfer_del(fdctrl_t *fdctrl, int direction) … … 1439 1547 goto transfer_error; 1440 1548 } 1549 1550 #ifdef VBOX 1551 if (cur_drv->ro) 1552 { 1553 if (fdctrl->data_dir == FD_DIR_WRITE || fdctrl->data_dir == FD_DIR_FORMAT) 1554 { 1555 /* Handle readonly medium early, no need to do DMA, touch the 1556 * LED or attempt any writes. A real floppy doesn't attempt 1557 * to write to readonly media either. */ 1558 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW, 1559 0x00); 1560 goto transfer_error; 1561 } 1562 } 1563 #endif 1564 1565 1441 1566 rel_pos = fdctrl->data_pos % FD_SECTOR_LEN; 1442 1567 for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) { … … 1449 1574 cur_drv->track, cur_drv->sect, fd_sector(cur_drv), 1450 1575 fd_sector(cur_drv) * FD_SECTOR_LEN); 1451 if (fdctrl->data_dir != FD_DIR_WRITE || 1452 len < FD_SECTOR_LEN || rel_pos != 0) { 1576 if (fdctrl->data_dir != FD_DIR_FORMAT && 1577 (fdctrl->data_dir != FD_DIR_WRITE || 1578 len < FD_SECTOR_LEN || rel_pos != 0)) { 1453 1579 /* READ & SCAN commands and realign to a sector for WRITE */ 1454 1580 #ifdef VBOX … … 1488 1614 /* WRITE commands */ 1489 1615 #ifdef VBOX 1490 if (cur_drv->ro)1491 {1492 /* Handle readonly medium early, no need to do DMA, touch the1493 * LED or attempt any writes. A real floppy doesn't attempt1494 * to write to readonly media either. */1495 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,1496 0x00);1497 goto transfer_error;1498 }1499 1500 1616 { 1501 1617 uint32_t written; … … 1521 1637 } 1522 1638 break; 1639 #ifdef VBOX 1640 case FD_DIR_FORMAT: 1641 /* FORMAT command */ 1642 { 1643 uint8_t eot = fdctrl->fifo[3]; 1644 uint8_t filler = fdctrl->fifo[5]; 1645 uint32_t written; 1646 int sct; 1647 int rc2 = PDMDevHlpDMAReadMemory(fdctrl->pDevIns, nchan, 1648 fdctrl->fifo + rel_pos, 1649 fdctrl->data_pos, 1650 len, &written); 1651 AssertMsgRC (rc2, ("DMAReadMemory -> %Rrc\n", rc2)); 1652 1653 /* Fill the entire track with desired data pattern. */ 1654 FLOPPY_DPRINTF("formatting track: %d sectors, pattern %02x\n", 1655 eot, filler); 1656 memset(fdctrl->fifo, filler, FD_SECTOR_LEN); 1657 for (sct = 0; sct < eot; ++sct) 1658 { 1659 rc = blk_write(cur_drv, fd_sector(cur_drv), fdctrl->fifo, 1); 1660 if (RT_FAILURE(rc)) 1661 { 1662 FLOPPY_ERROR("formatting sector %d\n", fd_sector(cur_drv)); 1663 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); 1664 goto transfer_error; 1665 } 1666 fdctrl_seek_to_next_sect(fdctrl, cur_drv); 1667 } 1668 } 1669 break; 1670 #endif 1523 1671 default: 1524 1672 /* SCAN commands */ … … 1826 1974 fdrive_t *cur_drv; 1827 1975 uint8_t ns, dp; 1828 int did_seek = 0;1829 1976 1830 1977 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 1831 1978 cur_drv = get_cur_drv(fdctrl); 1979 fdctrl->data_state &= ~(FD_STATE_MULTI | FD_STATE_SEEK); 1832 1980 ns = fdctrl->fifo[3]; 1833 1981 dp = fdctrl->fifo[5]; … … 1839 1987 fdctrl->fifo[3], fdctrl->fifo[4], fdctrl->fifo[5]); 1840 1988 1841 fdctrl->data_state |= FD_STATE_FORMAT; 1842 if (fdctrl->fifo[0] & 0x80) 1843 fdctrl->data_state |= FD_STATE_MULTI; 1989 /* Since we cannot actually format anything, we have to make sure that 1990 * whatever new format the guest is trying to establish matches the 1991 * existing format of the medium. 1992 */ 1993 if (cur_drv->last_sect != ns || fdctrl->fifo[2] != 2) 1994 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_NW, 0); 1844 1995 else 1845 fdctrl->data_state &= ~FD_STATE_MULTI; 1846 fdctrl->data_state &= ~FD_STATE_SEEK; 1847 cur_drv->bps = 1848 fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2]; 1849 #if 0 1850 cur_drv->last_sect = 1851 cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] : 1852 fdctrl->fifo[3] / 2; 1853 #else 1854 cur_drv->last_sect = fdctrl->fifo[3]; 1855 #endif 1856 /* TODO: implement format using DMA expected by the Bochs BIOS 1857 * and Linux fdformat (read 3 bytes per sector via DMA and fill 1858 * the sector with the specified fill byte 1859 */ 1860 fdctrl->data_state &= ~FD_STATE_FORMAT; 1861 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 1996 { 1997 cur_drv->bps = fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2]; 1998 cur_drv->last_sect = ns; 1999 2000 fdctrl_start_format(fdctrl); 2001 } 1862 2002 } 1863 2003 … … 1948 2088 */ 1949 2089 cur_drv->track = fdctrl->fifo[2]; 2090 cur_drv->ltrk = cur_drv->track; 1950 2091 /* Raise Interrupt */ 1951 2092 fdctrl_raise_irq(fdctrl, FD_SR0_SEEK | GET_CUR_DRV(fdctrl)); … … 2174 2315 FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n", 2175 2316 fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate); 2317 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD); 2318 } else if (cur_drv->track >= cur_drv->max_track) { 2319 FLOPPY_DPRINTF("read id past last track (%d >= %d)\n", 2320 cur_drv->track, cur_drv->max_track); 2321 cur_drv->ltrk = 0; 2176 2322 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA | FD_SR1_ND, FD_SR2_MD); 2177 2323 }
Note:
See TracChangeset
for help on using the changeset viewer.