Commit 746d6de7fef4c92f31c8e70c826ee63b2b6936b9

Authored by blueswir1
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,6 +974,40 @@ static void fdctrl_unimplemented (fdctrl_t *fdctrl, int direction)
974 #endif 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 /* Callback for transfer end (stop or abort) */ 1011 /* Callback for transfer end (stop or abort) */
978 static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, 1012 static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
979 uint8_t status1, uint8_t status2) 1013 uint8_t status1, uint8_t status2)
@@ -1196,35 +1230,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, @@ -1196,35 +1230,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
1196 rel_pos = fdctrl->data_pos % FD_SECTOR_LEN; 1230 rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
1197 if (rel_pos == 0) { 1231 if (rel_pos == 0) {
1198 /* Seek to next sector */ 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 end_transfer: 1237 end_transfer:
@@ -1250,7 +1257,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) @@ -1250,7 +1257,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
1250 { 1257 {
1251 fdrive_t *cur_drv; 1258 fdrive_t *cur_drv;
1252 uint32_t retval = 0; 1259 uint32_t retval = 0;
1253 - int pos, len; 1260 + int pos;
1254 1261
1255 cur_drv = get_cur_drv(fdctrl); 1262 cur_drv = get_cur_drv(fdctrl);
1256 fdctrl->state &= ~FD_CTRL_SLEEP; 1263 fdctrl->state &= ~FD_CTRL_SLEEP;
@@ -1262,9 +1269,12 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) @@ -1262,9 +1269,12 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
1262 if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) { 1269 if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
1263 pos %= FD_SECTOR_LEN; 1270 pos %= FD_SECTOR_LEN;
1264 if (pos == 0) { 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 bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1); 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,6 +1717,11 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
1707 if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || 1717 if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) ||
1708 fdctrl->data_pos == fdctrl->data_len) { 1718 fdctrl->data_pos == fdctrl->data_len) {
1709 bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1); 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 /* Switch from transfer mode to status mode 1726 /* Switch from transfer mode to status mode
1712 * then from status mode to command mode 1727 * then from status mode to command mode