Il 12/06/2012 13:19, Pavel Hrdina ha scritto: > This bit is cleared on every successful seek to a different track (cylinder). > The seek is also called on revalidate or on read/write/format commands which > also clear the DSKCHG bit. > > Signed-off-by: Pavel Hrdina <phrd...@redhat.com> > --- > hw/fdc.c | 66 ++++++++++++++++++++++++++++++------------------------------- > 1 files changed, 32 insertions(+), 34 deletions(-) > > diff --git a/hw/fdc.c b/hw/fdc.c > index 096aefc..b658504 100644 > --- a/hw/fdc.c > +++ b/hw/fdc.c > @@ -153,8 +153,11 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t > track, uint8_t sect, > } > #endif > drv->head = head; > - if (drv->track != track) > + if (drv->track != track) { > ret = 1; > + if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) > + drv->media_changed = 0;
Coding style... Otherwise looks good. Paolo > + } > drv->track = track; > drv->sect = sect; > } > @@ -169,9 +172,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t > track, uint8_t sect, > static void fd_recalibrate(FDrive *drv) > { > FLOPPY_DPRINTF("recalibrate\n"); > - drv->head = 0; > - drv->track = 0; > - drv->sect = 1; > + fd_seek(drv, 0, 0, 1, 1); > } > > /* Revalidate a disk drive after a disk change */ > @@ -710,14 +711,6 @@ static void fdctrl_raise_irq(FDCtrl *fdctrl, uint8_t > status0) > qemu_set_irq(fdctrl->irq, 1); > fdctrl->sra |= FD_SRA_INTPEND; > } > - if (status0 & FD_SR0_SEEK) { > - FDrive *cur_drv; > - /* A seek clears the disk change line (if a disk is inserted) */ > - cur_drv = get_cur_drv(fdctrl); > - if (cur_drv->bs != NULL && bdrv_is_inserted(cur_drv->bs)) { > - cur_drv->media_changed = 0; > - } > - } > > fdctrl->reset_sensei = 0; > fdctrl->status0 = status0; > @@ -1003,30 +996,39 @@ static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, > FDrive *cur_drv) > fd_sector(cur_drv)); > /* XXX: cur_drv->sect >= cur_drv->last_sect should be an > error in fact */ > - if (cur_drv->sect >= cur_drv->last_sect || > - cur_drv->sect == fdctrl->eot) { > - cur_drv->sect = 1; > + uint8_t new_head = cur_drv->head; > + uint8_t new_track = cur_drv->track; > + uint8_t new_sect = cur_drv->sect; > + > + int ret = 1; > + > + if (new_sect >= cur_drv->last_sect || > + new_sect == fdctrl->eot) { > + new_sect = 1; > if (FD_MULTI_TRACK(fdctrl->data_state)) { > - if (cur_drv->head == 0 && > + if (new_head == 0 && > (cur_drv->flags & FDISK_DBL_SIDES) != 0) { > - cur_drv->head = 1; > + new_head = 1; > } else { > - cur_drv->head = 0; > - cur_drv->track++; > + new_head = 0; > + new_track++; > if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) > - return 0; > + ret = 0; > } > } else { > - cur_drv->track++; > - return 0; > + new_track++; > + ret = 0; > } > - FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n", > + if (ret == 1) { > + FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n", > cur_drv->head, cur_drv->track, > cur_drv->sect, fd_sector(cur_drv)); > + } > } else { > - cur_drv->sect++; > + new_sect++; > } > - return 1; > + fd_seek(cur_drv, new_head, new_track, new_sect, 1); > + return ret; > } > > /* Callback for transfer end (stop or abort) */ > @@ -1622,11 +1624,7 @@ static void fdctrl_handle_seek(FDCtrl *fdctrl, int > direction) > /* The seek command just sends step pulses to the drive and doesn't care > if > * there is a medium inserted of if it's banging the head against the > drive. > */ > - if (fdctrl->fifo[2] > cur_drv->max_track) { > - cur_drv->track = cur_drv->max_track; > - } else { > - cur_drv->track = fdctrl->fifo[2]; > - } > + fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1); > /* Raise Interrupt */ > fdctrl_raise_irq(fdctrl, FD_SR0_SEEK); > } > @@ -1691,9 +1689,9 @@ static void fdctrl_handle_relative_seek_out(FDCtrl > *fdctrl, int direction) > SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); > cur_drv = get_cur_drv(fdctrl); > if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) { > - cur_drv->track = cur_drv->max_track - 1; > + fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1, > cur_drv->sect, 1); > } else { > - cur_drv->track += fdctrl->fifo[2]; > + fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1); > } > fdctrl_reset_fifo(fdctrl); > /* Raise Interrupt */ > @@ -1707,9 +1705,9 @@ static void fdctrl_handle_relative_seek_in(FDCtrl > *fdctrl, int direction) > SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); > cur_drv = get_cur_drv(fdctrl); > if (fdctrl->fifo[2] > cur_drv->track) { > - cur_drv->track = 0; > + fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1); > } else { > - cur_drv->track -= fdctrl->fifo[2]; > + fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1); > } > fdctrl_reset_fifo(fdctrl); > /* Raise Interrupt */ >