Index: hw/fdc.c =================================================================== --- hw/fdc.c (revision 4215) +++ hw/fdc.c (working copy) @@ -79,9 +79,6 @@ uint8_t head; uint8_t track; uint8_t sect; - /* Last operation status */ - uint8_t dir; /* Direction */ - uint8_t rw; /* Read/write */ /* Media */ fdisk_flags_t flags; uint8_t last_sect; /* Nb sector per track */ @@ -113,6 +110,13 @@ return _fd_sector(drv->head, drv->track, drv->sect, drv->last_sect); } +/* Seek to a new position: + * returns 0 if already on right track + * returns 1 if track changed + * returns 2 if track is invalid + * returns 3 if sector is invalid + * returns 4 if seek is disabled + */ static int fd_seek (fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect, int enable_seek) { @@ -161,8 +165,6 @@ drv->head = 0; drv->track = 0; drv->sect = 1; - drv->dir = 1; - drv->rw = 0; } /* Recognize floppy formats */ @@ -449,9 +451,6 @@ #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT) struct fdctrl_t { - fdctrl_t *fdctrl; - /* Controller's identification */ - uint8_t version; /* HW */ qemu_irq irq; int dma_chann; @@ -463,7 +462,6 @@ uint8_t dor; uint8_t dsr; uint8_t msr; - uint8_t state; uint8_t cur_drv; uint8_t bootsel; uint8_t status0; @@ -590,8 +588,6 @@ qemu_put_8s(f, &fd->head); qemu_put_8s(f, &fd->track); qemu_put_8s(f, &fd->sect); - qemu_put_8s(f, &fd->dir); - qemu_put_8s(f, &fd->rw); } static void fdc_save (QEMUFile *f, void *opaque) @@ -632,8 +628,6 @@ qemu_get_8s(f, &fd->head); qemu_get_8s(f, &fd->track); qemu_get_8s(f, &fd->sect); - qemu_get_8s(f, &fd->dir); - qemu_get_8s(f, &fd->rw); return 0; } @@ -943,19 +937,9 @@ /* Set an error: unimplemented/unknown command */ static void fdctrl_unimplemented (fdctrl_t *fdctrl, int direction) { -#if 0 - fdrive_t *cur_drv; - - cur_drv = get_cur_drv(fdctrl); - fdctrl->fifo[0] = FD_SR0_ABNTERM | FD_SR0_SEEK | (cur_drv->head << 2) | fdctrl->cur_drv; - fdctrl->fifo[1] = 0x00; - fdctrl->fifo[2] = 0x00; - fdctrl_set_fifo(fdctrl, 3, 1); -#else - // fdctrl_reset_fifo(fdctrl); + FLOPPY_ERROR("unimplemented command 0x%02x\n", fdctrl->fifo[0]); fdctrl->fifo[0] = FD_SR0_INVCMD; fdctrl_set_fifo(fdctrl, 1, 0); -#endif } /* Seek to next sector */ @@ -1260,7 +1244,12 @@ fd_sector(cur_drv)); return 0; } - bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1); + if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { + FLOPPY_DPRINTF("error getting sector %d\n", + fd_sector(cur_drv)); + /* Sure, image size is too small... */ + memset(fdctrl->fifo, 0, FD_SECTOR_LEN); + } } } retval = fdctrl->fifo[pos]; @@ -1375,8 +1364,7 @@ static void fdctrl_handle_version (fdctrl_t *fdctrl, int direction) { - /* Controller's version */ - fdctrl->fifo[0] = fdctrl->version; + fdctrl->fifo[0] = 0x90; /* Intel 82078 controller */ fdctrl_set_fifo(fdctrl, 1, 1); } @@ -1436,7 +1424,7 @@ /* Set main status register to busy */ fdctrl->msr &= ~FD_MSR_RQM; - + cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; qemu_mod_timer(fdctrl->result_timer, qemu_get_clock(vm_clock) + (ticks_per_sec / 50)); @@ -1529,10 +1517,6 @@ fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; cur_drv = get_cur_drv(fdctrl); - if (fdctrl->fifo[2] <= cur_drv->track) - cur_drv->dir = 1; - else - cur_drv->dir = 0; fdctrl_reset_fifo(fdctrl); fdctrl->status0 |= FD_SR0_SEEK; if (fdctrl->fifo[2] > cur_drv->max_track) @@ -1602,7 +1586,6 @@ fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; cur_drv = get_cur_drv(fdctrl); - cur_drv->dir = 0; if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) { cur_drv->track = cur_drv->max_track - 1; } else { @@ -1619,7 +1602,6 @@ fdctrl->cur_drv = fdctrl->fifo[1] & FD_DOR_SELMASK; cur_drv = get_cur_drv(fdctrl); - cur_drv->dir = 1; if (fdctrl->fifo[2] > cur_drv->track) { cur_drv->track = 0; } else { @@ -1680,7 +1662,6 @@ fdrive_t *cur_drv; int pos; - cur_drv = get_cur_drv(fdctrl); /* Reset mode */ if (!(fdctrl->dor & FD_DOR_nRESET)) { FLOPPY_DPRINTF("Floppy controller in RESET state !\n"); @@ -1697,7 +1678,11 @@ fdctrl->fifo[fdctrl->data_pos++] = value; if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || fdctrl->data_pos == fdctrl->data_len) { - bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1); + cur_drv = get_cur_drv(fdctrl); + if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { + FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv)); + return; + } if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { FLOPPY_DPRINTF("error seeking to next sector %d\n", fd_sector(cur_drv)); @@ -1787,7 +1772,6 @@ fdctrl->result_timer = qemu_new_timer(vm_clock, fdctrl_result_timer, fdctrl); - fdctrl->version = 0x90; /* Intel 82078 controller */ fdctrl->irq = irq; fdctrl->dma_chann = dma_chann; fdctrl->io_base = io_base; @@ -1798,7 +1782,7 @@ for (i = 0; i < MAX_FD; i++) { fd_init(&fdctrl->drives[i], fds[i]); } - fdctrl_reset(fdctrl, 0); + fdctrl_external_reset(fdctrl); register_savevm("fdc", io_base, 1, fdc_save, fdc_load, fdctrl); qemu_register_reset(fdctrl_external_reset, fdctrl); for (i = 0; i < MAX_FD; i++) {