Commit 368df94d16c030482adeae6b9d18220d9ad5fae3

Authored by blueswir1
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,6 +494,8 @@ struct fdctrl_t {
494 QEMUTimer *result_timer; 494 QEMUTimer *result_timer;
495 uint8_t sra; 495 uint8_t sra;
496 uint8_t srb; 496 uint8_t srb;
  497 + uint8_t dor;
  498 + uint8_t msr;
497 uint8_t state; 499 uint8_t state;
498 uint8_t dma_en; 500 uint8_t dma_en;
499 uint8_t cur_drv; 501 uint8_t cur_drv;
@@ -771,6 +773,9 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq) @@ -771,6 +773,9 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
771 if (!fdctrl->drives[1].bs) 773 if (!fdctrl->drives[1].bs)
772 fdctrl->sra |= FD_SRA_nDRV2; 774 fdctrl->sra |= FD_SRA_nDRV2;
773 fdctrl->cur_drv = 0; 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 /* FIFO state */ 779 /* FIFO state */
775 fdctrl->data_pos = 0; 780 fdctrl->data_pos = 0;
776 fdctrl->data_len = 0; 781 fdctrl->data_len = 0;
@@ -829,7 +834,7 @@ static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl) @@ -829,7 +834,7 @@ static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl)
829 if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON) 834 if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON)
830 retval |= FD_DOR_MOTEN1; 835 retval |= FD_DOR_MOTEN1;
831 /* DMA enable */ 836 /* DMA enable */
832 - if (fdctrl->dma_en) 837 + if (fdctrl->dor & FD_DOR_DMAEN)
833 retval |= FD_DOR_DMAEN; 838 retval |= FD_DOR_DMAEN;
834 /* Reset indicator */ 839 /* Reset indicator */
835 if (!(fdctrl->state & FD_CTRL_RESET)) 840 if (!(fdctrl->state & FD_CTRL_RESET))
@@ -897,6 +902,8 @@ static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value) @@ -897,6 +902,8 @@ static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value)
897 } 902 }
898 /* Selected drive */ 903 /* Selected drive */
899 fdctrl->cur_drv = value & FD_DOR_SELMASK; 904 fdctrl->cur_drv = value & FD_DOR_SELMASK;
  905 +
  906 + fdctrl->dor = value;
900 } 907 }
901 908
902 /* Tape drive register : 0x03 */ 909 /* Tape drive register : 0x03 */
@@ -1085,10 +1092,11 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, @@ -1085,10 +1092,11 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
1085 fdctrl->fifo[5] = cur_drv->sect; 1092 fdctrl->fifo[5] = cur_drv->sect;
1086 fdctrl->fifo[6] = FD_SECTOR_SC; 1093 fdctrl->fifo[6] = FD_SECTOR_SC;
1087 fdctrl->data_dir = FD_DIR_READ; 1094 fdctrl->data_dir = FD_DIR_READ;
1088 - if (fdctrl->state & FD_CTRL_BUSY) { 1095 + if (!(fdctrl->msr & FD_MSR_NONDMA)) {
1089 DMA_release_DREQ(fdctrl->dma_chann); 1096 DMA_release_DREQ(fdctrl->dma_chann);
1090 fdctrl->state &= ~FD_CTRL_BUSY; 1097 fdctrl->state &= ~FD_CTRL_BUSY;
1091 } 1098 }
  1099 + fdctrl->msr &= ~FD_MSR_NONDMA;
1092 fdctrl_set_fifo(fdctrl, 7, 1); 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,7 +1167,7 @@ static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)
1159 fdctrl->data_len *= tmp; 1167 fdctrl->data_len *= tmp;
1160 } 1168 }
1161 fdctrl->eot = fdctrl->fifo[6]; 1169 fdctrl->eot = fdctrl->fifo[6];
1162 - if (fdctrl->dma_en) { 1170 + if (fdctrl->dor & FD_DOR_DMAEN) {
1163 int dma_mode; 1171 int dma_mode;
1164 /* DMA transfer are enabled. Check if DMA channel is well programmed */ 1172 /* DMA transfer are enabled. Check if DMA channel is well programmed */
1165 dma_mode = DMA_get_channel_mode(fdctrl->dma_chann); 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,6 +1193,7 @@ static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)
1185 } 1193 }
1186 } 1194 }
1187 FLOPPY_DPRINTF("start non-DMA transfer\n"); 1195 FLOPPY_DPRINTF("start non-DMA transfer\n");
  1196 + fdctrl->msr |= FD_MSR_NONDMA;
1188 /* IO based transfer: calculate len */ 1197 /* IO based transfer: calculate len */
1189 fdctrl_raise_irq(fdctrl, 0x00); 1198 fdctrl_raise_irq(fdctrl, 0x00);
1190 1199
@@ -1325,7 +1334,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) @@ -1325,7 +1334,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
1325 return 0; 1334 return 0;
1326 } 1335 }
1327 pos = fdctrl->data_pos; 1336 pos = fdctrl->data_pos;
1328 - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { 1337 + if (fdctrl->msr & FD_MSR_NONDMA) {
1329 pos %= FD_SECTOR_LEN; 1338 pos %= FD_SECTOR_LEN;
1330 if (pos == 0) { 1339 if (pos == 0) {
1331 if (fdctrl->data_pos != 0) 1340 if (fdctrl->data_pos != 0)
@@ -1343,7 +1352,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) @@ -1343,7 +1352,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
1343 /* Switch from transfer mode to status mode 1352 /* Switch from transfer mode to status mode
1344 * then from status mode to command mode 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 fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00); 1356 fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
1348 } else { 1357 } else {
1349 fdctrl_reset_fifo(fdctrl); 1358 fdctrl_reset_fifo(fdctrl);
@@ -1438,7 +1447,7 @@ static void fdctrl_handle_dumpreg (fdctrl_t *fdctrl, int direction) @@ -1438,7 +1447,7 @@ static void fdctrl_handle_dumpreg (fdctrl_t *fdctrl, int direction)
1438 fdctrl->fifo[3] = 0; 1447 fdctrl->fifo[3] = 0;
1439 /* timers */ 1448 /* timers */
1440 fdctrl->fifo[4] = fdctrl->timer0; 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 fdctrl->fifo[6] = cur_drv->last_sect; 1451 fdctrl->fifo[6] = cur_drv->last_sect;
1443 fdctrl->fifo[7] = (fdctrl->lock << 7) | 1452 fdctrl->fifo[7] = (fdctrl->lock << 7) |
1444 (cur_drv->perpendicular << 2); 1453 (cur_drv->perpendicular << 2);
@@ -1547,7 +1556,10 @@ static void fdctrl_handle_specify (fdctrl_t *fdctrl, int direction) @@ -1547,7 +1556,10 @@ static void fdctrl_handle_specify (fdctrl_t *fdctrl, int direction)
1547 { 1556 {
1548 fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF; 1557 fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
1549 fdctrl->timer1 = fdctrl->fifo[2] >> 1; 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 /* No result back */ 1563 /* No result back */
1552 fdctrl_reset_fifo(fdctrl); 1564 fdctrl_reset_fifo(fdctrl);
1553 } 1565 }
@@ -1770,7 +1782,7 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) @@ -1770,7 +1782,7 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
1770 return; 1782 return;
1771 } 1783 }
1772 /* Is it write command time ? */ 1784 /* Is it write command time ? */
1773 - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { 1785 + if (fdctrl->msr & FD_MSR_NONDMA) {
1774 /* FIFO data write */ 1786 /* FIFO data write */
1775 fdctrl->fifo[fdctrl->data_pos++] = value; 1787 fdctrl->fifo[fdctrl->data_pos++] = value;
1776 if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || 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,10 +1874,7 @@ static fdctrl_t *fdctrl_init_common (qemu_irq irq, int dma_chann,
1862 fdctrl->io_base = io_base; 1874 fdctrl->io_base = io_base;
1863 fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ 1875 fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
1864 if (fdctrl->dma_chann != -1) { 1876 if (fdctrl->dma_chann != -1) {
1865 - fdctrl->dma_en = 1;  
1866 DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); 1877 DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
1867 - } else {  
1868 - fdctrl->dma_en = 0;  
1869 } 1878 }
1870 for (i = 0; i < MAX_FD; i++) { 1879 for (i = 0; i < MAX_FD; i++) {
1871 fd_init(&fdctrl->drives[i], fds[i]); 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,7 +1924,7 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
1915 fdctrl_t *fdctrl; 1924 fdctrl_t *fdctrl;
1916 int io_mem; 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 fdctrl->sun4m = 1; 1928 fdctrl->sun4m = 1;
1920 io_mem = cpu_register_io_memory(0, fdctrl_mem_read_strict, 1929 io_mem = cpu_register_io_memory(0, fdctrl_mem_read_strict,
1921 fdctrl_mem_write_strict, 1930 fdctrl_mem_write_strict,