[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] FDC: rework status0, status1, status2 handling
From: |
Hervé Poussineau |
Subject: |
[Qemu-devel] [PATCH] FDC: rework status0, status1, status2 handling |
Date: |
Wed, 25 Jun 2008 23:25:31 +0200 |
User-agent: |
Thunderbird 2.0.0.14 (Windows/20080421) |
Hi,
Attached patch fixes status0, status1 and status2 handling, which were
broken in read/write commands and in some subtle ways. Status values are
now calculated during command execution and not at the very end.
This allows removing of one hack in fdctrl_handle_sense_interrupt_status().
This also removes the FD_STATE_SEEK/FD_DID_SEEK stuff.
Hervé
Index: fdc.c
===================================================================
--- fdc.c (revision 4789)
+++ fdc.c (working copy)
@@ -116,54 +116,6 @@
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)
-{
- uint32_t sector;
- int ret;
-
- if (track > drv->max_track ||
- (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
- FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
- head, track, sect, 1,
- (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
- drv->max_track, drv->last_sect);
- return 2;
- }
- if (sect > drv->last_sect) {
- FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
- head, track, sect, 1,
- (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
- drv->max_track, drv->last_sect);
- return 3;
- }
- sector = _fd_sector(head, track, sect, drv->last_sect);
- ret = 0;
- if (sector != fd_sector(drv)) {
-#if 0
- if (!enable_seek) {
- FLOPPY_ERROR("no implicit seek %d %02x %02x (max=%d %02x %02x)\n",
- head, track, sect, 1, drv->max_track, drv->last_sect);
- return 4;
- }
-#endif
- drv->head = head;
- if (drv->track != track)
- ret = 1;
- drv->track = track;
- drv->sect = sect;
- }
-
- return ret;
-}
-
/* Set drive back to track 0 */
static void fd_recalibrate (fdrive_t *drv)
{
@@ -302,7 +254,7 @@
static void fdctrl_reset_fifo (fdctrl_t *fdctrl);
static int fdctrl_transfer_handler (void *opaque, int nchan,
int dma_pos, int dma_len);
-static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status0);
+static void fdctrl_raise_irq (fdctrl_t *fdctrl);
static uint32_t fdctrl_read_statusA (fdctrl_t *fdctrl);
static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl);
@@ -327,7 +279,6 @@
enum {
FD_STATE_MULTI = 0x01, /* multi track flag */
FD_STATE_FORMAT = 0x02, /* format flag */
- FD_STATE_SEEK = 0x04, /* seek flag */
};
enum {
@@ -463,7 +414,6 @@
};
#define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
-#define FD_DID_SEEK(state) ((state) & FD_STATE_SEEK)
#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
struct fdctrl_t {
@@ -508,6 +458,61 @@
fdrive_t drives[MAX_FD];
};
+/* 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 (fdctrl_t *fdctrl, fdrive_t *drv,
+ uint8_t head, uint8_t track, uint8_t sect)
+{
+ uint32_t sector;
+ int ret;
+
+ if (track > drv->max_track ||
+ (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
+ FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
+ head, track, sect, 1,
+ (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
+ drv->max_track, drv->last_sect);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ return 2;
+ }
+ if (sect > drv->last_sect) {
+ FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
+ head, track, sect, 1,
+ (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
+ drv->max_track, drv->last_sect);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ fdctrl->status1 |= FD_SR1_EC;
+ return 3;
+ }
+ sector = _fd_sector(head, track, sect, drv->last_sect);
+ ret = 0;
+#if 0
+ if (!(fdctrl->config & FD_CONFIG_EIS) && (head != drv->head || track !=
drv->track)) {
+ FLOPPY_ERROR("no implicit seek %d %02x %02x (current=%d %02x %02x,
max=%d %02x %02x)\n",
+ head, track, sect,
+ drv->head, drv->track, drv->sect,
+ 1, drv->max_track, drv->last_sect);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ return 4;
+ }
+#endif
+ if (sector != fd_sector(drv)) {
+ drv->head = head;
+ if (drv->track != track)
+ ret = 1;
+ drv->track = track;
+ drv->sect = sect;
+ }
+
+ fdctrl->status0 |= FD_SR0_SEEK;
+ return ret;
+}
+
static uint32_t fdctrl_read (void *opaque, uint32_t reg)
{
fdctrl_t *fdctrl = opaque;
@@ -739,21 +744,19 @@
fdctrl->sra &= ~FD_SRA_INTPEND;
}
-static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status0)
+static void fdctrl_raise_irq (fdctrl_t *fdctrl)
{
/* Sparc mutation */
if (fdctrl->sun4m && (fdctrl->msr & FD_MSR_CMDBUSY)) {
/* XXX: not sure */
fdctrl->msr &= ~FD_MSR_CMDBUSY;
fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
- fdctrl->status0 = status0;
return;
}
if (!(fdctrl->sra & FD_SRA_INTPEND)) {
qemu_set_irq(fdctrl->irq, 1);
fdctrl->sra |= FD_SRA_INTPEND;
}
- fdctrl->status0 = status0;
FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
}
@@ -782,7 +785,8 @@
fd_recalibrate(&fdctrl->drives[i]);
fdctrl_reset_fifo(fdctrl);
if (do_irq) {
- fdctrl_raise_irq(fdctrl, FD_SR0_RDYCHG);
+ fdctrl->status0 |= FD_SR0_RDYCHG;
+ fdctrl_raise_irq(fdctrl);
}
}
@@ -819,7 +823,7 @@
static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
{
- switch (fdctrl->cur_drv) {
+ switch (GET_CUR_DRV(fdctrl)) {
case 0: return drv0(fdctrl);
case 1: return drv1(fdctrl);
#if MAX_FD == 4
@@ -1005,7 +1009,7 @@
fdctrl->data_pos = 0;
fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
if (do_irq)
- fdctrl_raise_irq(fdctrl, 0x00);
+ fdctrl_raise_irq(fdctrl);
}
/* Set an error: unimplemented/unknown command */
@@ -1034,11 +1038,13 @@
} else {
cur_drv->head = 0;
cur_drv->track++;
+ fdctrl->status0 |= FD_SR0_SEEK;
if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
return 0;
}
} else {
cur_drv->track++;
+ fdctrl->status0 |= FD_SR0_SEEK;
return 0;
}
FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
@@ -1051,18 +1057,21 @@
}
/* Callback for transfer end (stop or abort) */
-static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
- uint8_t status1, uint8_t status2)
+static void fdctrl_stop_transfer (fdctrl_t *fdctrl)
{
fdrive_t *cur_drv;
+ uint8_t status0 = fdctrl->status0;
cur_drv = get_cur_drv(fdctrl);
+ /* Add head and drive to status0 */
+ status0 |= (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
+
FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
- status0, status1, status2,
- status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl));
- fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
- fdctrl->fifo[1] = status1;
- fdctrl->fifo[2] = status2;
+ fdctrl->status0, fdctrl->status1, fdctrl->status2,
+ status0);
+ fdctrl->fifo[0] = status0;
+ fdctrl->fifo[1] = fdctrl->status1;
+ fdctrl->fifo[2] = fdctrl->status2;
fdctrl->fifo[3] = cur_drv->track;
fdctrl->fifo[4] = cur_drv->head;
fdctrl->fifo[5] = cur_drv->sect;
@@ -1081,7 +1090,6 @@
{
fdrive_t *cur_drv;
uint8_t kh, kt, ks;
- int did_seek = 0;
SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
cur_drv = get_cur_drv(fdctrl);
@@ -1091,31 +1099,20 @@
FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
GET_CUR_DRV(fdctrl), kh, kt, ks,
_fd_sector(kh, kt, ks, cur_drv->last_sect));
- switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
+ switch (fd_seek(fdctrl, cur_drv, kh, kt, ks)) {
+ case 0:
+ case 1:
+ /* success */
+ break;
case 2:
- /* sect too big */
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
case 3:
- /* track too big */
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
case 4:
- /* No seek enabled */
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
+ /* error */
+ fdctrl_stop_transfer(fdctrl);
fdctrl->fifo[3] = kt;
fdctrl->fifo[4] = kh;
fdctrl->fifo[5] = ks;
return;
- case 1:
- did_seek = 1;
- break;
default:
break;
}
@@ -1128,10 +1125,6 @@
fdctrl->data_state |= FD_STATE_MULTI;
else
fdctrl->data_state &= ~FD_STATE_MULTI;
- if (did_seek)
- fdctrl->data_state |= FD_STATE_SEEK;
- else
- fdctrl->data_state &= ~FD_STATE_SEEK;
if (fdctrl->fifo[5] == 00) {
fdctrl->data_len = fdctrl->fifo[8];
} else {
@@ -1173,7 +1166,7 @@
if (direction != FD_DIR_WRITE)
fdctrl->msr |= FD_MSR_DIO;
/* IO based transfer: calculate len */
- fdctrl_raise_irq(fdctrl, 0x00);
+ fdctrl_raise_irq(fdctrl);
return;
}
@@ -1186,7 +1179,8 @@
/* We don't handle deleted data,
* so we don't return *ANYTHING*
*/
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ fdctrl_stop_transfer(fdctrl);
}
/* handlers for DMA transfers */
@@ -1196,7 +1190,6 @@
fdctrl_t *fdctrl;
fdrive_t *cur_drv;
int len, start_pos, rel_pos;
- uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
fdctrl = opaque;
if (fdctrl->msr & FD_MSR_RQM) {
@@ -1204,16 +1197,11 @@
return 0;
}
cur_drv = get_cur_drv(fdctrl);
- if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
- fdctrl->data_dir == FD_DIR_SCANH)
- status2 = FD_SR2_SNS;
if (dma_len > fdctrl->data_len)
dma_len = fdctrl->data_len;
if (cur_drv->bs == NULL) {
- if (fdctrl->data_dir == FD_DIR_WRITE)
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00,
0x00);
- else
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ fdctrl_stop_transfer(fdctrl);
len = 0;
goto transfer_error;
}
@@ -1251,7 +1239,8 @@
if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
fdctrl->fifo, 1) < 0) {
FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv));
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK,
0x00, 0x00);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ fdctrl_stop_transfer(fdctrl);
goto transfer_error;
}
break;
@@ -1263,14 +1252,16 @@
DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
if (ret == 0) {
- status2 = FD_SR2_SEH;
+ fdctrl->status2 |= FD_SR2_SEH;
+ fdctrl->status2 &= ~FD_SR2_SNS;
goto end_transfer;
}
if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
(ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
- status2 = 0x00;
+ fdctrl->status2 &= ~FD_SR2_SNS;
goto end_transfer;
}
+ fdctrl->status2 |= FD_SR2_SNS;
}
break;
}
@@ -1286,14 +1277,8 @@
len = fdctrl->data_pos - start_pos;
FLOPPY_DPRINTF("end transfer %d %d %d\n",
fdctrl->data_pos, len, fdctrl->data_len);
- if (fdctrl->data_dir == FD_DIR_SCANE ||
- fdctrl->data_dir == FD_DIR_SCANL ||
- fdctrl->data_dir == FD_DIR_SCANH)
- status2 = FD_SR2_SEH;
- if (FD_DID_SEEK(fdctrl->data_state))
- status0 |= FD_SR0_SEEK;
fdctrl->data_len -= len;
- fdctrl_stop_transfer(fdctrl, status0, status1, status2);
+ fdctrl_stop_transfer(fdctrl);
transfer_error:
return len;
@@ -1322,7 +1307,8 @@
fd_sector(cur_drv));
return 0;
}
- if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) <
0) {
+ if (cur_drv->bs == NULL ||
+ 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... */
@@ -1337,7 +1323,7 @@
* then from status mode to command mode
*/
if (fdctrl->msr & FD_MSR_NONDMA) {
- fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
+ fdctrl_stop_transfer(fdctrl);
} else {
fdctrl_reset_fifo(fdctrl);
fdctrl_reset_irq(fdctrl);
@@ -1361,31 +1347,20 @@
FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
GET_CUR_DRV(fdctrl), kh, kt, ks,
_fd_sector(kh, kt, ks, cur_drv->last_sect));
- switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
+ switch (fd_seek(fdctrl, cur_drv, kh, kt, ks)) {
+ case 0:
+ case 1:
+ /* success */
+ break;
case 2:
- /* sect too big */
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
case 3:
- /* track too big */
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
case 4:
- /* No seek enabled */
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
+ /* error */
+ fdctrl_stop_transfer(fdctrl);
fdctrl->fifo[3] = kt;
fdctrl->fifo[4] = kh;
fdctrl->fifo[5] = ks;
return;
- case 1:
- fdctrl->data_state |= FD_STATE_SEEK;
- break;
default:
break;
}
@@ -1393,15 +1368,13 @@
if (cur_drv->bs == NULL ||
bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
FLOPPY_ERROR("formatting sector %d\n", fd_sector(cur_drv));
- fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ fdctrl_stop_transfer(fdctrl);
} else {
if (cur_drv->sect == cur_drv->last_sect) {
fdctrl->data_state &= ~FD_STATE_FORMAT;
/* Last sector done */
- if (FD_DID_SEEK(fdctrl->data_state))
- fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
- else
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+ fdctrl_stop_transfer(fdctrl);
} else {
/* More to do */
fdctrl->data_pos = 0;
@@ -1512,7 +1485,9 @@
{
fdrive_t *cur_drv = get_cur_drv(fdctrl);
- /* XXX: should set main status register to busy */
+ /* 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,7 +1504,6 @@
fdctrl->data_state |= FD_STATE_MULTI;
else
fdctrl->data_state &= ~FD_STATE_MULTI;
- fdctrl->data_state &= ~FD_STATE_SEEK;
cur_drv->bps =
fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
#if 0
@@ -1544,7 +1518,7 @@
* the sector with the specified fill byte
*/
fdctrl->data_state &= ~FD_STATE_FORMAT;
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+ fdctrl_stop_transfer(fdctrl);
}
static void fdctrl_handle_specify (fdctrl_t *fdctrl, int direction)
@@ -1584,23 +1558,16 @@
fd_recalibrate(cur_drv);
fdctrl_reset_fifo(fdctrl);
/* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
+ fdctrl->status0 |= FD_SR0_SEEK;
+ fdctrl_raise_irq(fdctrl);
}
static void fdctrl_handle_sense_interrupt_status (fdctrl_t *fdctrl, int
direction)
{
fdrive_t *cur_drv = get_cur_drv(fdctrl);
-#if 0
fdctrl->fifo[0] =
fdctrl->status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
-#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);
@@ -1614,13 +1581,13 @@
SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
cur_drv = get_cur_drv(fdctrl);
fdctrl_reset_fifo(fdctrl);
- if (fdctrl->fifo[2] > cur_drv->max_track) {
- fdctrl_raise_irq(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK);
- } else {
+ fdctrl->status0 |= FD_SR0_SEEK;
+ if (fdctrl->fifo[2] > cur_drv->max_track)
+ fdctrl->status0 |= FD_SR0_ABNTERM;
+ else
cur_drv->track = fdctrl->fifo[2];
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
- }
+ /* Raise Interrupt */
+ fdctrl_raise_irq(fdctrl);
}
static void fdctrl_handle_perpendicular_mode (fdctrl_t *fdctrl, int direction)
@@ -1689,7 +1656,8 @@
}
fdctrl_reset_fifo(fdctrl);
/* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
+ fdctrl->status0 |= FD_SR0_SEEK;
+ fdctrl_raise_irq(fdctrl);
}
static void fdctrl_handle_relative_seek_in (fdctrl_t *fdctrl, int direction)
@@ -1705,7 +1673,8 @@
}
fdctrl_reset_fifo(fdctrl);
/* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
+ fdctrl->status0 |= FD_SR0_SEEK;
+ fdctrl_raise_irq(fdctrl);
}
static const struct {
@@ -1776,7 +1745,8 @@
if (pos == FD_SECTOR_LEN - 1 ||
fdctrl->data_pos == fdctrl->data_len) {
cur_drv = get_cur_drv(fdctrl);
- if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) <
0) {
+ if (cur_drv->bs == NULL ||
+ bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) <
0) {
FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv));
return;
}
@@ -1790,7 +1760,7 @@
* then from status mode to command mode
*/
if (fdctrl->data_pos == fdctrl->data_len)
- fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
+ fdctrl_stop_transfer(fdctrl);
return;
}
if (fdctrl->data_pos == 0) {
@@ -1811,6 +1781,15 @@
return;
}
+ if (fdctrl->fifo[0] != FD_CMD_SENSE_INTERRUPT_STATUS)
+ {
+ /* Reset status0, except for SENSE_INTERRUPT_STATUS
+ * which returns it */
+ fdctrl->status0 = 0;
+ }
+ fdctrl->status1 = 0;
+ fdctrl->status2 = 0;
+
pos = command_to_handler[fdctrl->fifo[0] & 0xff];
FLOPPY_DPRINTF("treat %s command\n", handlers[pos].name);
(*handlers[pos].handler)(fdctrl, handlers[pos].direction);
@@ -1829,7 +1808,7 @@
if (cur_drv->last_sect != 0) {
cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
}
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+ fdctrl_stop_transfer(fdctrl);
}
/* Init functions */
- [Qemu-devel] [PATCH] FDC: rework status0, status1, status2 handling,
Hervé Poussineau <=