Floppy: Properly handle Sense Interrupt Status after FDC Reset
Original text below. Attached is a patch that changes how the emulated floppy controller replies to Sense Interrupt Status commands immediately after a controller reset. The specs state that after a Reset the 82078 goes into polling mode which needs four Sense Interrupt Status commands to be issued afterwards to clear the status of each drive. Currently we always respond to Sense Interrupt Status with a SEEK END instead of POLLING. This causes a problem with the SCO Openserver installer which is expects a POLLING state after reset. This patch returns a POLLING status for four Sense Interrupt Status requests immediately after a controller reset. This approach mirrors the way Bochs handles this situation. With the attached patch applied Openserver gets further when trying to load storage drivers from the floppy disk (blocked by another issue, patch on its way). I have successfully tested the floppy drive on the following OSs after applying this patch: Windows 98, Windows XP SP2, Linux x86 (SysRescCD 1.1.3 and Ubuntu 8.10). Justin Changelog: Properly handle Sense Interrupt Status after FDC Reset Signed-off-by: Justin Chevrier <theburner1@yahoo.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6416 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
7373048ce6
commit
f2d81b3300
14
hw/fdc.c
14
hw/fdc.c
|
@ -55,6 +55,7 @@ do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ##args); } while (0)
|
|||
/* Will always be a fixed parameter for us */
|
||||
#define FD_SECTOR_LEN 512
|
||||
#define FD_SECTOR_SC 2 /* Sector size code */
|
||||
#define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */
|
||||
|
||||
/* Floppy disk drive emulation */
|
||||
typedef enum fdisk_type_t {
|
||||
|
@ -506,6 +507,7 @@ struct fdctrl_t {
|
|||
int sun4m;
|
||||
/* Floppy drives */
|
||||
fdrive_t drives[MAX_FD];
|
||||
int reset_sensei;
|
||||
};
|
||||
|
||||
static uint32_t fdctrl_read (void *opaque, uint32_t reg)
|
||||
|
@ -763,6 +765,7 @@ static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status0)
|
|||
qemu_set_irq(fdctrl->irq, 1);
|
||||
fdctrl->sra |= FD_SRA_INTPEND;
|
||||
}
|
||||
fdctrl->reset_sensei = 0;
|
||||
fdctrl->status0 = status0;
|
||||
FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
|
||||
}
|
||||
|
@ -793,6 +796,7 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
|
|||
fdctrl_reset_fifo(fdctrl);
|
||||
if (do_irq) {
|
||||
fdctrl_raise_irq(fdctrl, FD_SR0_RDYCHG);
|
||||
fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1601,16 +1605,18 @@ static void fdctrl_handle_sense_interrupt_status (fdctrl_t *fdctrl, int directio
|
|||
{
|
||||
fdrive_t *cur_drv = get_cur_drv(fdctrl);
|
||||
|
||||
#if 0
|
||||
if(fdctrl->reset_sensei > 0) {
|
||||
fdctrl->fifo[0] =
|
||||
fdctrl->status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
|
||||
#else
|
||||
FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
|
||||
fdctrl->reset_sensei--;
|
||||
} else {
|
||||
/* XXX: status0 handling is broken for read/write
|
||||
commands, so we do this hack. It should be suppressed
|
||||
ASAP */
|
||||
fdctrl->fifo[0] =
|
||||
FD_SR0_SEEK | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
|
||||
#endif
|
||||
}
|
||||
|
||||
fdctrl->fifo[1] = cur_drv->track;
|
||||
fdctrl_set_fifo(fdctrl, 2, 0);
|
||||
fdctrl_reset_irq(fdctrl);
|
||||
|
|
Loading…
Reference in a new issue