Index: hw/fdc.c =================================================================== --- hw/fdc.c (revision 4215) +++ hw/fdc.c (working copy) @@ -22,10 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -/* - * The controller is used in Sun4m systems in a slightly different - * way. There are changes in DOR register and DMA is not available. - */ + #include "hw.h" #include "fdc.h" #include "block.h" @@ -501,8 +498,9 @@ QEMUTimer *result_timer; uint8_t sra; uint8_t srb; + uint8_t dor; + uint8_t msr; uint8_t state; - uint8_t dma_en; uint8_t cur_drv; uint8_t bootsel; uint8_t status0; @@ -525,8 +523,6 @@ uint8_t lock; /* Power down config (also with status regB access mode */ uint8_t pwrd; - /* Sun4m quirks? */ - int sun4m; /* Floppy drives */ fdrive_t drives[2]; }; @@ -646,8 +642,9 @@ /* Controller state */ qemu_put_8s(f, &s->sra); qemu_put_8s(f, &s->srb); + qemu_put_8s(f, &s->dor); + qemu_put_8s(f, &s->msr); qemu_put_8s(f, &s->state); - qemu_put_8s(f, &s->dma_en); qemu_put_8s(f, &s->cur_drv); qemu_put_8s(f, &s->bootsel); qemu_put_8s(f, &s->status0); @@ -697,8 +694,9 @@ /* Controller state */ qemu_get_8s(f, &s->sra); qemu_get_8s(f, &s->srb); + qemu_get_8s(f, &s->dor); + qemu_get_8s(f, &s->msr); qemu_get_8s(f, &s->state); - qemu_get_8s(f, &s->dma_en); qemu_get_8s(f, &s->cur_drv); qemu_get_8s(f, &s->bootsel); qemu_get_8s(f, &s->status0); @@ -761,11 +759,6 @@ static void fdctrl_raise_irq (fdctrl_t *fdctrl) { - // Sparc mutation - if (fdctrl->sun4m && !fdctrl->dma_en) { - fdctrl->state &= ~FD_CTRL_BUSY; - return; - } if (!(fdctrl->sra & FD_SRA_INTPEND)) { qemu_set_irq(fdctrl->irq, 1); fdctrl->sra |= FD_SRA_INTPEND; @@ -786,6 +779,8 @@ if (!fdctrl->drives[1].bs) fdctrl->sra |= FD_SRA_nDRV2; fdctrl->cur_drv = 0; + fdctrl->dor = 0; + fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0; /* FIFO state */ fdctrl->data_pos = 0; fdctrl->data_len = 0; @@ -846,7 +841,7 @@ if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON) retval |= FD_DOR_MOTEN1; /* DMA enable */ - if (fdctrl->dma_en) + if (fdctrl->dor & FD_DOR_DMAEN) retval |= FD_DOR_DMAEN; /* Reset indicator */ if (!(fdctrl->state & FD_CTRL_RESET)) @@ -894,11 +889,6 @@ fd_start(drv0(fdctrl)); else fd_stop(drv0(fdctrl)); - /* DMA enable */ -#if 0 - if (fdctrl->dma_chann != -1) - fdctrl->dma_en = value & FD_DOR_DMAEN ? 1 : 0; -#endif /* Reset */ if (!(value & FD_DOR_nRESET)) { if (!(fdctrl->state & FD_CTRL_RESET)) { @@ -914,6 +904,8 @@ } /* Selected drive */ fdctrl->cur_drv = value & FD_DOR_SELMASK; + + fdctrl->dor = value; } /* Tape drive register : 0x03 */ @@ -954,8 +946,10 @@ /* Data transfer direction indicator */ if (fdctrl->data_dir == FD_DIR_READ) retval |= FD_MSR_DIO; - } - /* Should handle FD_MSR_NONDMA for SPECIFY command */ + } + /* Non DMA indicator */ + if (fdctrl->msr & FD_MSR_NONDMA) + retval |= FD_MSR_NONDMA; /* Command busy indicator */ if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA || FD_STATE(fdctrl->data_state) == FD_STATE_STATUS) @@ -1106,10 +1100,11 @@ fdctrl->fifo[5] = cur_drv->sect; fdctrl->fifo[6] = FD_SECTOR_SC; fdctrl->data_dir = FD_DIR_READ; - if (fdctrl->state & FD_CTRL_BUSY) { + if (!(fdctrl->msr & FD_MSR_NONDMA)) { DMA_release_DREQ(fdctrl->dma_chann); fdctrl->state &= ~FD_CTRL_BUSY; } + fdctrl->msr &= ~FD_MSR_NONDMA; fdctrl_set_fifo(fdctrl, 7, 1); } @@ -1179,7 +1174,7 @@ fdctrl->data_len *= tmp; } fdctrl->eot = fdctrl->fifo[6]; - if (fdctrl->dma_en) { + if (fdctrl->dor & FD_DOR_DMAEN) { int dma_mode; /* DMA transfer are enabled. Check if DMA channel is well programmed */ dma_mode = DMA_get_channel_mode(fdctrl->dma_chann); @@ -1205,6 +1200,7 @@ } } FLOPPY_DPRINTF("start non-DMA transfer\n"); + fdctrl->msr |= FD_MSR_NONDMA; /* IO based transfer: calculate len */ fdctrl_raise_irq(fdctrl); @@ -1338,7 +1334,7 @@ return 0; } pos = fdctrl->data_pos; - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { + if (fdctrl->msr & FD_MSR_NONDMA) { pos %= FD_SECTOR_LEN; if (pos == 0) { if (fdctrl->data_pos != 0) @@ -1356,7 +1352,7 @@ /* Switch from transfer mode to status mode * then from status mode to command mode */ - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { + if (fdctrl->msr & FD_MSR_NONDMA) { fdctrl_stop_transfer(fdctrl); } else { fdctrl_reset_fifo(fdctrl); @@ -1451,7 +1447,7 @@ fdctrl->fifo[3] = 0; /* timers */ fdctrl->fifo[4] = fdctrl->timer0; - fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en; + fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0); fdctrl->fifo[6] = cur_drv->last_sect; fdctrl->fifo[7] = (fdctrl->lock << 7) | (cur_drv->perpendicular << 2); @@ -1559,7 +1555,10 @@ { fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF; fdctrl->timer1 = fdctrl->fifo[2] >> 1; - fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ; + if (fdctrl->fifo[2] & 1) + fdctrl->dor &= ~FD_DOR_DMAEN; + else + fdctrl->dor |= FD_DOR_DMAEN; /* No result back */ fdctrl_reset_fifo(fdctrl); } @@ -1633,7 +1632,7 @@ if (fdctrl->fifo[1] & 0x80) cur_drv->perpendicular = fdctrl->fifo[1] & 0x7; /* No result back */ - fdctrl_reset_fifo(fdctrl); + fdctrl_reset_fifo(fdctrl); } static void fdctrl_handle_configure (fdctrl_t *fdctrl, int direction) @@ -1777,7 +1776,7 @@ return; } /* Is it write command time ? */ - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { + if (fdctrl->msr & FD_MSR_NONDMA) { /* FIFO data write */ fdctrl->fifo[fdctrl->data_pos++] = value; if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || @@ -1878,10 +1877,7 @@ fdctrl->io_base = io_base; fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ if (fdctrl->dma_chann != -1) { - fdctrl->dma_en = 1; DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); - } else { - fdctrl->dma_en = 0; } for (i = 0; i < MAX_FD; i++) { fd_init(&fdctrl->drives[i], fds[i]); @@ -1906,7 +1902,6 @@ fdctrl = fdctrl_init_common(irq, dma_chann, io_base, fds); - fdctrl->sun4m = 0; if (mem_mapped) { io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write, fdctrl); @@ -1931,8 +1926,7 @@ fdctrl_t *fdctrl; int io_mem; - fdctrl = fdctrl_init_common(irq, 0, io_base, fds); - fdctrl->sun4m = 1; + fdctrl = fdctrl_init_common(irq, -1, io_base, fds); io_mem = cpu_register_io_memory(0, fdctrl_mem_read_strict, fdctrl_mem_write_strict, fdctrl);