Commit cefec4f5dc137427a92d927cb1d3347980f28d07
1 parent
78ae820c
FDC fix 10/10 (Hervé Poussineau):
- Replaces access to cur_drv field by macros. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4290 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
25 additions
and
19 deletions
hw/fdc.c
| ... | ... | @@ -49,6 +49,9 @@ do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ##args); } while (0) |
| 49 | 49 | /********************************************************/ |
| 50 | 50 | /* Floppy drive emulation */ |
| 51 | 51 | |
| 52 | +#define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv) | |
| 53 | +#define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive)) | |
| 54 | + | |
| 52 | 55 | /* Will always be a fixed parameter for us */ |
| 53 | 56 | #define FD_SECTOR_LEN 512 |
| 54 | 57 | #define FD_SECTOR_SC 2 /* Sector size code */ |
| ... | ... | @@ -612,17 +615,18 @@ static void fdc_save (QEMUFile *f, void *opaque) |
| 612 | 615 | fdctrl_t *s = opaque; |
| 613 | 616 | uint8_t tmp; |
| 614 | 617 | int i; |
| 618 | + uint8_t dor = s->dor | GET_CUR_DRV(s); | |
| 615 | 619 | |
| 616 | 620 | /* Controller state */ |
| 617 | 621 | qemu_put_8s(f, &s->sra); |
| 618 | 622 | qemu_put_8s(f, &s->srb); |
| 623 | + qemu_put_8s(f, &dor); | |
| 619 | 624 | qemu_put_8s(f, &s->tdr); |
| 620 | 625 | qemu_put_8s(f, &s->dsr); |
| 621 | 626 | qemu_put_8s(f, &s->msr); |
| 622 | 627 | qemu_put_8s(f, &s->status0); |
| 623 | 628 | qemu_put_8s(f, &s->status1); |
| 624 | 629 | qemu_put_8s(f, &s->status2); |
| 625 | - qemu_put_8s(f, &s->cur_drv); | |
| 626 | 630 | /* Command FIFO */ |
| 627 | 631 | qemu_put_buffer(f, s->fifo, FD_SECTOR_LEN); |
| 628 | 632 | qemu_put_be32s(f, &s->data_pos); |
| ... | ... | @@ -665,13 +669,15 @@ static int fdc_load (QEMUFile *f, void *opaque, int version_id) |
| 665 | 669 | /* Controller state */ |
| 666 | 670 | qemu_get_8s(f, &s->sra); |
| 667 | 671 | qemu_get_8s(f, &s->srb); |
| 672 | + qemu_get_8s(f, &s->dor); | |
| 673 | + SET_CUR_DRV(s, s->dor & FD_DOR_SELMASK); | |
| 674 | + s->dor &= ~FD_DOR_SELMASK; | |
| 668 | 675 | qemu_get_8s(f, &s->tdr); |
| 669 | 676 | qemu_get_8s(f, &s->dsr); |
| 670 | 677 | qemu_get_8s(f, &s->msr); |
| 671 | 678 | qemu_get_8s(f, &s->status0); |
| 672 | 679 | qemu_get_8s(f, &s->status1); |
| 673 | 680 | qemu_get_8s(f, &s->status2); |
| 674 | - qemu_get_8s(f, &s->cur_drv); | |
| 675 | 681 | /* Command FIFO */ |
| 676 | 682 | qemu_get_buffer(f, s->fifo, FD_SECTOR_LEN); |
| 677 | 683 | qemu_get_be32s(f, &s->data_pos); |
| ... | ... | @@ -1053,8 +1059,8 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, |
| 1053 | 1059 | cur_drv = get_cur_drv(fdctrl); |
| 1054 | 1060 | FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n", |
| 1055 | 1061 | status0, status1, status2, |
| 1056 | - status0 | (cur_drv->head << 2) | fdctrl->cur_drv); | |
| 1057 | - fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | fdctrl->cur_drv; | |
| 1062 | + status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl)); | |
| 1063 | + fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl); | |
| 1058 | 1064 | fdctrl->fifo[1] = status1; |
| 1059 | 1065 | fdctrl->fifo[2] = status2; |
| 1060 | 1066 | fdctrl->fifo[3] = cur_drv->track; |
| ... | ... | @@ -1077,13 +1083,13 @@ static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction) |
| 1077 | 1083 | uint8_t kh, kt, ks; |
| 1078 | 1084 | int did_seek = 0; |
| 1079 | 1085 | |
| 1080 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1086 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1081 | 1087 | cur_drv = get_cur_drv(fdctrl); |
| 1082 | 1088 | kt = fdctrl->fifo[2]; |
| 1083 | 1089 | kh = fdctrl->fifo[3]; |
| 1084 | 1090 | ks = fdctrl->fifo[4]; |
| 1085 | 1091 | FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n", |
| 1086 | - fdctrl->cur_drv, kh, kt, ks, | |
| 1092 | + GET_CUR_DRV(fdctrl), kh, kt, ks, | |
| 1087 | 1093 | _fd_sector(kh, kt, ks, cur_drv->last_sect)); |
| 1088 | 1094 | switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) { |
| 1089 | 1095 | case 2: |
| ... | ... | @@ -1218,7 +1224,7 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, |
| 1218 | 1224 | len = FD_SECTOR_LEN - rel_pos; |
| 1219 | 1225 | FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x " |
| 1220 | 1226 | "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos, |
| 1221 | - fdctrl->data_len, fdctrl->cur_drv, cur_drv->head, | |
| 1227 | + fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head, | |
| 1222 | 1228 | cur_drv->track, cur_drv->sect, fd_sector(cur_drv), |
| 1223 | 1229 | fd_sector(cur_drv) * FD_SECTOR_LEN); |
| 1224 | 1230 | if (fdctrl->data_dir != FD_DIR_WRITE || |
| ... | ... | @@ -1347,13 +1353,13 @@ static void fdctrl_format_sector (fdctrl_t *fdctrl) |
| 1347 | 1353 | fdrive_t *cur_drv; |
| 1348 | 1354 | uint8_t kh, kt, ks; |
| 1349 | 1355 | |
| 1350 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1356 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1351 | 1357 | cur_drv = get_cur_drv(fdctrl); |
| 1352 | 1358 | kt = fdctrl->fifo[6]; |
| 1353 | 1359 | kh = fdctrl->fifo[7]; |
| 1354 | 1360 | ks = fdctrl->fifo[8]; |
| 1355 | 1361 | FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n", |
| 1356 | - fdctrl->cur_drv, kh, kt, ks, | |
| 1362 | + GET_CUR_DRV(fdctrl), kh, kt, ks, | |
| 1357 | 1363 | _fd_sector(kh, kt, ks, cur_drv->last_sect)); |
| 1358 | 1364 | switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) { |
| 1359 | 1365 | case 2: |
| ... | ... | @@ -1516,7 +1522,7 @@ static void fdctrl_handle_format_track (fdctrl_t *fdctrl, int direction) |
| 1516 | 1522 | { |
| 1517 | 1523 | fdrive_t *cur_drv; |
| 1518 | 1524 | |
| 1519 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1525 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1520 | 1526 | cur_drv = get_cur_drv(fdctrl); |
| 1521 | 1527 | fdctrl->data_state |= FD_STATE_FORMAT; |
| 1522 | 1528 | if (fdctrl->fifo[0] & 0x80) |
| ... | ... | @@ -1557,14 +1563,14 @@ static void fdctrl_handle_sense_drive_status (fdctrl_t *fdctrl, int direction) |
| 1557 | 1563 | { |
| 1558 | 1564 | fdrive_t *cur_drv; |
| 1559 | 1565 | |
| 1560 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1566 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1561 | 1567 | cur_drv = get_cur_drv(fdctrl); |
| 1562 | 1568 | cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; |
| 1563 | 1569 | /* 1 Byte status back */ |
| 1564 | 1570 | fdctrl->fifo[0] = (cur_drv->ro << 6) | |
| 1565 | 1571 | (cur_drv->track == 0 ? 0x10 : 0x00) | |
| 1566 | 1572 | (cur_drv->head << 2) | |
| 1567 | - fdctrl->cur_drv | | |
| 1573 | + GET_CUR_DRV(fdctrl) | | |
| 1568 | 1574 | 0x28; |
| 1569 | 1575 | fdctrl_set_fifo(fdctrl, 1, 0); |
| 1570 | 1576 | } |
| ... | ... | @@ -1573,7 +1579,7 @@ static void fdctrl_handle_recalibrate (fdctrl_t *fdctrl, int direction) |
| 1573 | 1579 | { |
| 1574 | 1580 | fdrive_t *cur_drv; |
| 1575 | 1581 | |
| 1576 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1582 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1577 | 1583 | cur_drv = get_cur_drv(fdctrl); |
| 1578 | 1584 | fd_recalibrate(cur_drv); |
| 1579 | 1585 | fdctrl_reset_fifo(fdctrl); |
| ... | ... | @@ -1587,13 +1593,13 @@ static void fdctrl_handle_sense_interrupt_status (fdctrl_t *fdctrl, int directio |
| 1587 | 1593 | |
| 1588 | 1594 | #if 0 |
| 1589 | 1595 | fdctrl->fifo[0] = |
| 1590 | - fdctrl->status0 | (cur_drv->head << 2) | fdctrl->cur_drv; | |
| 1596 | + fdctrl->status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl); | |
| 1591 | 1597 | #else |
| 1592 | 1598 | /* XXX: status0 handling is broken for read/write |
| 1593 | 1599 | commands, so we do this hack. It should be suppressed |
| 1594 | 1600 | ASAP */ |
| 1595 | 1601 | fdctrl->fifo[0] = |
| 1596 | - FD_SR0_SEEK | (cur_drv->head << 2) | fdctrl->cur_drv; | |
| 1602 | + FD_SR0_SEEK | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl); | |
| 1597 | 1603 | #endif |
| 1598 | 1604 | fdctrl->fifo[1] = cur_drv->track; |
| 1599 | 1605 | fdctrl_set_fifo(fdctrl, 2, 0); |
| ... | ... | @@ -1605,7 +1611,7 @@ static void fdctrl_handle_seek (fdctrl_t *fdctrl, int direction) |
| 1605 | 1611 | { |
| 1606 | 1612 | fdrive_t *cur_drv; |
| 1607 | 1613 | |
| 1608 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1614 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1609 | 1615 | cur_drv = get_cur_drv(fdctrl); |
| 1610 | 1616 | fdctrl_reset_fifo(fdctrl); |
| 1611 | 1617 | if (fdctrl->fifo[2] > cur_drv->max_track) { |
| ... | ... | @@ -1665,7 +1671,7 @@ static void fdctrl_handle_drive_specification_command (fdctrl_t *fdctrl, int dir |
| 1665 | 1671 | } else if (fdctrl->data_len > 7) { |
| 1666 | 1672 | /* ERROR */ |
| 1667 | 1673 | fdctrl->fifo[0] = 0x80 | |
| 1668 | - (cur_drv->head << 2) | fdctrl->cur_drv; | |
| 1674 | + (cur_drv->head << 2) | GET_CUR_DRV(fdctrl); | |
| 1669 | 1675 | fdctrl_set_fifo(fdctrl, 1, 1); |
| 1670 | 1676 | } |
| 1671 | 1677 | } |
| ... | ... | @@ -1674,7 +1680,7 @@ static void fdctrl_handle_relative_seek_out (fdctrl_t *fdctrl, int direction) |
| 1674 | 1680 | { |
| 1675 | 1681 | fdrive_t *cur_drv; |
| 1676 | 1682 | |
| 1677 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1683 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1678 | 1684 | cur_drv = get_cur_drv(fdctrl); |
| 1679 | 1685 | if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) { |
| 1680 | 1686 | cur_drv->track = cur_drv->max_track - 1; |
| ... | ... | @@ -1690,7 +1696,7 @@ static void fdctrl_handle_relative_seek_in (fdctrl_t *fdctrl, int direction) |
| 1690 | 1696 | { |
| 1691 | 1697 | fdrive_t *cur_drv; |
| 1692 | 1698 | |
| 1693 | - fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; | |
| 1699 | + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); | |
| 1694 | 1700 | cur_drv = get_cur_drv(fdctrl); |
| 1695 | 1701 | if (fdctrl->fifo[2] > cur_drv->track) { |
| 1696 | 1702 | cur_drv->track = 0; | ... | ... |