Commit 746d6de7fef4c92f31c8e70c826ee63b2b6936b9
1 parent
678803ab
FDC fix 2/10 (Hervé Poussineau):
- Extract seeking to next sector handling in a function. Add a sector seek in PIO read and write modes git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4282 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
48 additions
and
33 deletions
hw/fdc.c
... | ... | @@ -974,6 +974,40 @@ static void fdctrl_unimplemented (fdctrl_t *fdctrl, int direction) |
974 | 974 | #endif |
975 | 975 | } |
976 | 976 | |
977 | +/* Seek to next sector */ | |
978 | +static int fdctrl_seek_to_next_sect (fdctrl_t *fdctrl, fdrive_t *cur_drv) | |
979 | +{ | |
980 | + FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n", | |
981 | + cur_drv->head, cur_drv->track, cur_drv->sect, | |
982 | + fd_sector(cur_drv)); | |
983 | + /* XXX: cur_drv->sect >= cur_drv->last_sect should be an | |
984 | + error in fact */ | |
985 | + if (cur_drv->sect >= cur_drv->last_sect || | |
986 | + cur_drv->sect == fdctrl->eot) { | |
987 | + cur_drv->sect = 1; | |
988 | + if (FD_MULTI_TRACK(fdctrl->data_state)) { | |
989 | + if (cur_drv->head == 0 && | |
990 | + (cur_drv->flags & FDISK_DBL_SIDES) != 0) { | |
991 | + cur_drv->head = 1; | |
992 | + } else { | |
993 | + cur_drv->head = 0; | |
994 | + cur_drv->track++; | |
995 | + if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) | |
996 | + return 0; | |
997 | + } | |
998 | + } else { | |
999 | + cur_drv->track++; | |
1000 | + return 0; | |
1001 | + } | |
1002 | + FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n", | |
1003 | + cur_drv->head, cur_drv->track, | |
1004 | + cur_drv->sect, fd_sector(cur_drv)); | |
1005 | + } else { | |
1006 | + cur_drv->sect++; | |
1007 | + } | |
1008 | + return 1; | |
1009 | +} | |
1010 | + | |
977 | 1011 | /* Callback for transfer end (stop or abort) */ |
978 | 1012 | static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, |
979 | 1013 | uint8_t status1, uint8_t status2) |
... | ... | @@ -1196,35 +1230,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, |
1196 | 1230 | rel_pos = fdctrl->data_pos % FD_SECTOR_LEN; |
1197 | 1231 | if (rel_pos == 0) { |
1198 | 1232 | /* Seek to next sector */ |
1199 | - FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n", | |
1200 | - cur_drv->head, cur_drv->track, cur_drv->sect, | |
1201 | - fd_sector(cur_drv), | |
1202 | - fdctrl->data_pos - len); | |
1203 | - /* XXX: cur_drv->sect >= cur_drv->last_sect should be an | |
1204 | - error in fact */ | |
1205 | - if (cur_drv->sect >= cur_drv->last_sect || | |
1206 | - cur_drv->sect == fdctrl->eot) { | |
1207 | - cur_drv->sect = 1; | |
1208 | - if (FD_MULTI_TRACK(fdctrl->data_state)) { | |
1209 | - if (cur_drv->head == 0 && | |
1210 | - (cur_drv->flags & FDISK_DBL_SIDES) != 0) { | |
1211 | - cur_drv->head = 1; | |
1212 | - } else { | |
1213 | - cur_drv->head = 0; | |
1214 | - cur_drv->track++; | |
1215 | - if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) | |
1216 | - break; | |
1217 | - } | |
1218 | - } else { | |
1219 | - cur_drv->track++; | |
1220 | - break; | |
1221 | - } | |
1222 | - FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n", | |
1223 | - cur_drv->head, cur_drv->track, | |
1224 | - cur_drv->sect, fd_sector(cur_drv)); | |
1225 | - } else { | |
1226 | - cur_drv->sect++; | |
1227 | - } | |
1233 | + if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) | |
1234 | + break; | |
1228 | 1235 | } |
1229 | 1236 | } |
1230 | 1237 | end_transfer: |
... | ... | @@ -1250,7 +1257,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) |
1250 | 1257 | { |
1251 | 1258 | fdrive_t *cur_drv; |
1252 | 1259 | uint32_t retval = 0; |
1253 | - int pos, len; | |
1260 | + int pos; | |
1254 | 1261 | |
1255 | 1262 | cur_drv = get_cur_drv(fdctrl); |
1256 | 1263 | fdctrl->state &= ~FD_CTRL_SLEEP; |
... | ... | @@ -1262,9 +1269,12 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) |
1262 | 1269 | if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { |
1263 | 1270 | pos %= FD_SECTOR_LEN; |
1264 | 1271 | if (pos == 0) { |
1265 | - len = fdctrl->data_len - fdctrl->data_pos; | |
1266 | - if (len > FD_SECTOR_LEN) | |
1267 | - len = FD_SECTOR_LEN; | |
1272 | + if (fdctrl->data_pos != 0) | |
1273 | + if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { | |
1274 | + FLOPPY_DPRINTF("error seeking to next sector %d\n", | |
1275 | + fd_sector(cur_drv)); | |
1276 | + return 0; | |
1277 | + } | |
1268 | 1278 | bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1); |
1269 | 1279 | } |
1270 | 1280 | } |
... | ... | @@ -1707,6 +1717,11 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) |
1707 | 1717 | if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || |
1708 | 1718 | fdctrl->data_pos == fdctrl->data_len) { |
1709 | 1719 | bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1); |
1720 | + if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { | |
1721 | + FLOPPY_DPRINTF("error seeking to next sector %d\n", | |
1722 | + fd_sector(cur_drv)); | |
1723 | + return; | |
1724 | + } | |
1710 | 1725 | } |
1711 | 1726 | /* Switch from transfer mode to status mode |
1712 | 1727 | * then from status mode to command mode | ... | ... |