Index: hw/fdc.c =================================================================== RCS file: /sources/qemu/qemu/hw/fdc.c,v retrieving revision 1.33 diff -u -d -d -p -r1.33 fdc.c --- hw/fdc.c 17 Nov 2007 17:14:41 -0000 1.33 +++ hw/fdc.c 17 Dec 2007 14:17:10 -0000 @@ -399,6 +399,8 @@ struct fdctrl_t { uint8_t lock; /* Power down config (also with status regB access mode */ uint8_t pwrd; + /* Drive status change emulation */ + uint8_t drstch; /* Sun4m quirks? */ int sun4m; /* Floppy drives */ @@ -674,7 +676,7 @@ static void fdctrl_raise_irq (fdctrl_t * fdctrl->int_status = status; return; } - if (~(fdctrl->state & FD_CTRL_INTR)) { + if (!(fdctrl->state & FD_CTRL_INTR)) { qemu_set_irq(fdctrl->irq, 1); fdctrl->state |= FD_CTRL_INTR; } @@ -698,6 +700,8 @@ static void fdctrl_reset (fdctrl_t *fdct fdctrl->data_dir = FD_DIR_WRITE; for (i = 0; i < MAX_FD; i++) fd_reset(&fdctrl->drives[i]); + /* Initialize the emulated drive status change register */ + fdctrl->drstch = 0xF; fdctrl_reset_fifo(fdctrl); if (do_irq) fdctrl_raise_irq(fdctrl, 0xc0); @@ -1410,17 +1414,36 @@ static void fdctrl_write_data (fdctrl_t /* SENSE_INTERRUPT_STATUS */ FLOPPY_DPRINTF("SENSE_INTERRUPT_STATUS command (%02x)\n", fdctrl->int_status); - /* No parameters cmd: returns status if no interrupt */ + /* No parameters cmd: returns interrupt status */ + if (!(fdctrl->config & 0x10) && fdctrl->drstch != 0x00) { + /* If emulated polling mode is active... */ + int i; + for (i = 0; i < 4; i++) { + if (fdctrl->drstch & (1 << i)) { + /* Emulate 8" drive 'i' status change */ + fdctrl->fifo[0] = 0xC0 | i; + fdctrl->drstch &= ~(1 << i); + break; + } + } + } else if (fdctrl->state & FD_CTRL_INTR) { #if 0 - fdctrl->fifo[0] = - fdctrl->int_status | (cur_drv->head << 2) | fdctrl->cur_drv; + fdctrl->fifo[0] = + fdctrl->int_status | (cur_drv->head << 2) | fdctrl->cur_drv; #else - /* XXX: int_status handling is broken for read/write - commands, so we do this hack. It should be suppressed - ASAP */ - fdctrl->fifo[0] = - 0x20 | (cur_drv->head << 2) | fdctrl->cur_drv; + /* XXX: int_status handling is broken for read/write + commands, so we do this hack. It should be suppressed + ASAP */ + fdctrl->fifo[0] = + 0x20 | (cur_drv->head << 2) | fdctrl->cur_drv; #endif + } else { + /* When no interrupt is pending, the command is invalid */ + fdctrl->fifo[0] = 0x80; + fdctrl_set_fifo(fdctrl, 1, 0); + fdctrl->int_status = 0xC0; + return; + } fdctrl->fifo[1] = cur_drv->track; fdctrl_set_fifo(fdctrl, 2, 0); fdctrl_reset_irq(fdctrl);