Commit 368df94d16c030482adeae6b9d18220d9ad5fae3
1 parent
8c6a4d77
FDC fix 4/10 (Hervé Poussineau):
- Handles correctly FD_MSR_NONDMA/FD_DOR_NONDMA flags, and uses them when possible. Fixes a problem with SPECIFY command. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4284 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
21 additions
and
12 deletions
hw/fdc.c
... | ... | @@ -494,6 +494,8 @@ struct fdctrl_t { |
494 | 494 | QEMUTimer *result_timer; |
495 | 495 | uint8_t sra; |
496 | 496 | uint8_t srb; |
497 | + uint8_t dor; | |
498 | + uint8_t msr; | |
497 | 499 | uint8_t state; |
498 | 500 | uint8_t dma_en; |
499 | 501 | uint8_t cur_drv; |
... | ... | @@ -771,6 +773,9 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq) |
771 | 773 | if (!fdctrl->drives[1].bs) |
772 | 774 | fdctrl->sra |= FD_SRA_nDRV2; |
773 | 775 | fdctrl->cur_drv = 0; |
776 | + fdctrl->dor = 0; | |
777 | + fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0; | |
778 | + fdctrl->msr = 0; | |
774 | 779 | /* FIFO state */ |
775 | 780 | fdctrl->data_pos = 0; |
776 | 781 | fdctrl->data_len = 0; |
... | ... | @@ -829,7 +834,7 @@ static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl) |
829 | 834 | if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON) |
830 | 835 | retval |= FD_DOR_MOTEN1; |
831 | 836 | /* DMA enable */ |
832 | - if (fdctrl->dma_en) | |
837 | + if (fdctrl->dor & FD_DOR_DMAEN) | |
833 | 838 | retval |= FD_DOR_DMAEN; |
834 | 839 | /* Reset indicator */ |
835 | 840 | if (!(fdctrl->state & FD_CTRL_RESET)) |
... | ... | @@ -897,6 +902,8 @@ static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value) |
897 | 902 | } |
898 | 903 | /* Selected drive */ |
899 | 904 | fdctrl->cur_drv = value & FD_DOR_SELMASK; |
905 | + | |
906 | + fdctrl->dor = value; | |
900 | 907 | } |
901 | 908 | |
902 | 909 | /* Tape drive register : 0x03 */ |
... | ... | @@ -1085,10 +1092,11 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, |
1085 | 1092 | fdctrl->fifo[5] = cur_drv->sect; |
1086 | 1093 | fdctrl->fifo[6] = FD_SECTOR_SC; |
1087 | 1094 | fdctrl->data_dir = FD_DIR_READ; |
1088 | - if (fdctrl->state & FD_CTRL_BUSY) { | |
1095 | + if (!(fdctrl->msr & FD_MSR_NONDMA)) { | |
1089 | 1096 | DMA_release_DREQ(fdctrl->dma_chann); |
1090 | 1097 | fdctrl->state &= ~FD_CTRL_BUSY; |
1091 | 1098 | } |
1099 | + fdctrl->msr &= ~FD_MSR_NONDMA; | |
1092 | 1100 | fdctrl_set_fifo(fdctrl, 7, 1); |
1093 | 1101 | } |
1094 | 1102 | |
... | ... | @@ -1159,7 +1167,7 @@ static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction) |
1159 | 1167 | fdctrl->data_len *= tmp; |
1160 | 1168 | } |
1161 | 1169 | fdctrl->eot = fdctrl->fifo[6]; |
1162 | - if (fdctrl->dma_en) { | |
1170 | + if (fdctrl->dor & FD_DOR_DMAEN) { | |
1163 | 1171 | int dma_mode; |
1164 | 1172 | /* DMA transfer are enabled. Check if DMA channel is well programmed */ |
1165 | 1173 | dma_mode = DMA_get_channel_mode(fdctrl->dma_chann); |
... | ... | @@ -1185,6 +1193,7 @@ static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction) |
1185 | 1193 | } |
1186 | 1194 | } |
1187 | 1195 | FLOPPY_DPRINTF("start non-DMA transfer\n"); |
1196 | + fdctrl->msr |= FD_MSR_NONDMA; | |
1188 | 1197 | /* IO based transfer: calculate len */ |
1189 | 1198 | fdctrl_raise_irq(fdctrl, 0x00); |
1190 | 1199 | |
... | ... | @@ -1325,7 +1334,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) |
1325 | 1334 | return 0; |
1326 | 1335 | } |
1327 | 1336 | pos = fdctrl->data_pos; |
1328 | - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { | |
1337 | + if (fdctrl->msr & FD_MSR_NONDMA) { | |
1329 | 1338 | pos %= FD_SECTOR_LEN; |
1330 | 1339 | if (pos == 0) { |
1331 | 1340 | if (fdctrl->data_pos != 0) |
... | ... | @@ -1343,7 +1352,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) |
1343 | 1352 | /* Switch from transfer mode to status mode |
1344 | 1353 | * then from status mode to command mode |
1345 | 1354 | */ |
1346 | - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { | |
1355 | + if (fdctrl->msr & FD_MSR_NONDMA) { | |
1347 | 1356 | fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00); |
1348 | 1357 | } else { |
1349 | 1358 | fdctrl_reset_fifo(fdctrl); |
... | ... | @@ -1438,7 +1447,7 @@ static void fdctrl_handle_dumpreg (fdctrl_t *fdctrl, int direction) |
1438 | 1447 | fdctrl->fifo[3] = 0; |
1439 | 1448 | /* timers */ |
1440 | 1449 | fdctrl->fifo[4] = fdctrl->timer0; |
1441 | - fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en; | |
1450 | + fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0); | |
1442 | 1451 | fdctrl->fifo[6] = cur_drv->last_sect; |
1443 | 1452 | fdctrl->fifo[7] = (fdctrl->lock << 7) | |
1444 | 1453 | (cur_drv->perpendicular << 2); |
... | ... | @@ -1547,7 +1556,10 @@ static void fdctrl_handle_specify (fdctrl_t *fdctrl, int direction) |
1547 | 1556 | { |
1548 | 1557 | fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF; |
1549 | 1558 | fdctrl->timer1 = fdctrl->fifo[2] >> 1; |
1550 | - fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ; | |
1559 | + if (fdctrl->fifo[2] & 1) | |
1560 | + fdctrl->dor &= ~FD_DOR_DMAEN; | |
1561 | + else | |
1562 | + fdctrl->dor |= FD_DOR_DMAEN; | |
1551 | 1563 | /* No result back */ |
1552 | 1564 | fdctrl_reset_fifo(fdctrl); |
1553 | 1565 | } |
... | ... | @@ -1770,7 +1782,7 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) |
1770 | 1782 | return; |
1771 | 1783 | } |
1772 | 1784 | /* Is it write command time ? */ |
1773 | - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { | |
1785 | + if (fdctrl->msr & FD_MSR_NONDMA) { | |
1774 | 1786 | /* FIFO data write */ |
1775 | 1787 | fdctrl->fifo[fdctrl->data_pos++] = value; |
1776 | 1788 | if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || |
... | ... | @@ -1862,10 +1874,7 @@ static fdctrl_t *fdctrl_init_common (qemu_irq irq, int dma_chann, |
1862 | 1874 | fdctrl->io_base = io_base; |
1863 | 1875 | fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ |
1864 | 1876 | if (fdctrl->dma_chann != -1) { |
1865 | - fdctrl->dma_en = 1; | |
1866 | 1877 | DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); |
1867 | - } else { | |
1868 | - fdctrl->dma_en = 0; | |
1869 | 1878 | } |
1870 | 1879 | for (i = 0; i < MAX_FD; i++) { |
1871 | 1880 | fd_init(&fdctrl->drives[i], fds[i]); |
... | ... | @@ -1915,7 +1924,7 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, |
1915 | 1924 | fdctrl_t *fdctrl; |
1916 | 1925 | int io_mem; |
1917 | 1926 | |
1918 | - fdctrl = fdctrl_init_common(irq, 0, io_base, fds); | |
1927 | + fdctrl = fdctrl_init_common(irq, -1, io_base, fds); | |
1919 | 1928 | fdctrl->sun4m = 1; |
1920 | 1929 | io_mem = cpu_register_io_memory(0, fdctrl_mem_read_strict, |
1921 | 1930 | fdctrl_mem_write_strict, | ... | ... |