Commit ed5fd2cce48520e4c0d4eec016743017df93e43a

Authored by bellard
1 parent bee32909

timer for READ_ID (win98 floppy fix) - simpler irq handling


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@787 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 44 additions and 36 deletions
hw/fdc.c
@@ -125,17 +125,17 @@ static int fd_seek (fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect, @@ -125,17 +125,17 @@ static int fd_seek (fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect,
125 125
126 if (track > drv->max_track || 126 if (track > drv->max_track ||
127 (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) { 127 (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
128 - FLOPPY_ERROR("try to read %d %02x %02x (max=%d %d %02x %02x)\n",  
129 - head, track, sect, 1,  
130 - (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,  
131 - drv->max_track, drv->last_sect); 128 + FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
  129 + head, track, sect, 1,
  130 + (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
  131 + drv->max_track, drv->last_sect);
132 return 2; 132 return 2;
133 } 133 }
134 if (sect > drv->last_sect) { 134 if (sect > drv->last_sect) {
135 - FLOPPY_ERROR("try to read %d %02x %02x (max=%d %d %02x %02x)\n",  
136 - head, track, sect, 1,  
137 - (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,  
138 - drv->max_track, drv->last_sect); 135 + FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
  136 + head, track, sect, 1,
  137 + (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
  138 + drv->max_track, drv->last_sect);
139 return 3; 139 return 3;
140 } 140 }
141 sector = _fd_sector(head, track, sect, drv->last_sect); 141 sector = _fd_sector(head, track, sect, drv->last_sect);
@@ -240,8 +240,8 @@ static void fd_revalidate (fdrive_t *drv) @@ -240,8 +240,8 @@ static void fd_revalidate (fdrive_t *drv)
240 ro = bdrv_is_read_only(drv->bs); 240 ro = bdrv_is_read_only(drv->bs);
241 bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect); 241 bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
242 if (nb_heads != 0 && max_track != 0 && last_sect != 0) { 242 if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
243 - printf("User defined disk (%d %d %d)",  
244 - nb_heads - 1, max_track, last_sect); 243 + FLOPPY_DPRINTF("User defined disk (%d %d %d)",
  244 + nb_heads - 1, max_track, last_sect);
245 } else { 245 } else {
246 bdrv_get_geometry(drv->bs, &nb_sectors); 246 bdrv_get_geometry(drv->bs, &nb_sectors);
247 match = -1; 247 match = -1;
@@ -273,8 +273,8 @@ static void fd_revalidate (fdrive_t *drv) @@ -273,8 +273,8 @@ static void fd_revalidate (fdrive_t *drv)
273 max_track = parse->max_track; 273 max_track = parse->max_track;
274 last_sect = parse->last_sect; 274 last_sect = parse->last_sect;
275 drv->drive = parse->drive; 275 drv->drive = parse->drive;
276 - printf("%s floppy disk (%d h %d t %d s) %s\n", parse->str,  
277 - nb_heads, max_track, last_sect, ro ? "ro" : "rw"); 276 + FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
  277 + nb_heads, max_track, last_sect, ro ? "ro" : "rw");
278 } 278 }
279 if (nb_heads == 1) { 279 if (nb_heads == 1) {
280 drv->flags &= ~FDISK_DBL_SIDES; 280 drv->flags &= ~FDISK_DBL_SIDES;
@@ -285,7 +285,7 @@ static void fd_revalidate (fdrive_t *drv) @@ -285,7 +285,7 @@ static void fd_revalidate (fdrive_t *drv)
285 drv->last_sect = last_sect; 285 drv->last_sect = last_sect;
286 drv->ro = ro; 286 drv->ro = ro;
287 } else { 287 } else {
288 - printf("No disk in drive\n"); 288 + FLOPPY_DPRINTF("No disk in drive\n");
289 drv->last_sect = 0; 289 drv->last_sect = 0;
290 drv->max_track = 0; 290 drv->max_track = 0;
291 drv->flags &= ~FDISK_DBL_SIDES; 291 drv->flags &= ~FDISK_DBL_SIDES;
@@ -318,6 +318,7 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq); @@ -318,6 +318,7 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq);
318 static void fdctrl_reset_fifo (fdctrl_t *fdctrl); 318 static void fdctrl_reset_fifo (fdctrl_t *fdctrl);
319 static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size); 319 static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size);
320 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status); 320 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status);
  321 +static void fdctrl_result_timer(void *opaque);
321 322
322 static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl); 323 static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl);
323 static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl); 324 static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl);
@@ -331,10 +332,10 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value); @@ -331,10 +332,10 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value);
331 static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl); 332 static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl);
332 333
333 enum { 334 enum {
334 - FD_CTRL_ACTIVE = 0x01, 335 + FD_CTRL_ACTIVE = 0x01, /* XXX: suppress that */
335 FD_CTRL_RESET = 0x02, 336 FD_CTRL_RESET = 0x02,
336 - FD_CTRL_SLEEP = 0x04,  
337 - FD_CTRL_BUSY = 0x08, 337 + FD_CTRL_SLEEP = 0x04, /* XXX: suppress that */
  338 + FD_CTRL_BUSY = 0x08, /* dma transfer in progress */
338 FD_CTRL_INTR = 0x10, 339 FD_CTRL_INTR = 0x10,
339 }; 340 };
340 341
@@ -372,6 +373,7 @@ struct fdctrl_t { @@ -372,6 +373,7 @@ struct fdctrl_t {
372 int dma_chann; 373 int dma_chann;
373 uint32_t io_base; 374 uint32_t io_base;
374 /* Controler state */ 375 /* Controler state */
  376 + QEMUTimer *result_timer;
375 uint8_t state; 377 uint8_t state;
376 uint8_t dma_en; 378 uint8_t dma_en;
377 uint8_t cur_drv; 379 uint8_t cur_drv;
@@ -425,6 +427,7 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg) @@ -425,6 +427,7 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg)
425 retval = (uint32_t)(-1); 427 retval = (uint32_t)(-1);
426 break; 428 break;
427 } 429 }
  430 + FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
428 431
429 return retval; 432 return retval;
430 } 433 }
@@ -433,6 +436,8 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value) @@ -433,6 +436,8 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
433 { 436 {
434 fdctrl_t *fdctrl = opaque; 437 fdctrl_t *fdctrl = opaque;
435 438
  439 + FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
  440 +
436 switch (reg & 0x07) { 441 switch (reg & 0x07) {
437 case 0x02: 442 case 0x02:
438 fdctrl_write_dor(fdctrl, value); 443 fdctrl_write_dor(fdctrl, value);
@@ -476,6 +481,9 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, @@ -476,6 +481,9 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
476 fdctrl = qemu_mallocz(sizeof(fdctrl_t)); 481 fdctrl = qemu_mallocz(sizeof(fdctrl_t));
477 if (!fdctrl) 482 if (!fdctrl)
478 return NULL; 483 return NULL;
  484 + fdctrl->result_timer = qemu_new_timer(vm_clock,
  485 + fdctrl_result_timer, fdctrl);
  486 +
479 fdctrl->version = 0x90; /* Intel 82078 controler */ 487 fdctrl->version = 0x90; /* Intel 82078 controler */
480 fdctrl->irq_lvl = irq_lvl; 488 fdctrl->irq_lvl = irq_lvl;
481 fdctrl->dma_chann = dma_chann; 489 fdctrl->dma_chann = dma_chann;
@@ -524,10 +532,9 @@ int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num) @@ -524,10 +532,9 @@ int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num)
524 /* Change IRQ state */ 532 /* Change IRQ state */
525 static void fdctrl_reset_irq (fdctrl_t *fdctrl) 533 static void fdctrl_reset_irq (fdctrl_t *fdctrl)
526 { 534 {
527 - if (fdctrl->state & FD_CTRL_INTR) {  
528 - pic_set_irq(fdctrl->irq_lvl, 0);  
529 - fdctrl->state &= ~(FD_CTRL_INTR | FD_CTRL_SLEEP | FD_CTRL_BUSY);  
530 - } 535 + FLOPPY_DPRINTF("Reset interrupt\n");
  536 + pic_set_irq(fdctrl->irq_lvl, 0);
  537 + fdctrl->state &= ~FD_CTRL_INTR;
531 } 538 }
532 539
533 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status) 540 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
@@ -558,7 +565,7 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq) @@ -558,7 +565,7 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
558 fd_reset(&fdctrl->drives[i]); 565 fd_reset(&fdctrl->drives[i]);
559 fdctrl_reset_fifo(fdctrl); 566 fdctrl_reset_fifo(fdctrl);
560 if (do_irq) 567 if (do_irq)
561 - fdctrl_raise_irq(fdctrl, 0x20); 568 + fdctrl_raise_irq(fdctrl, 0xc0);
562 } 569 }
563 570
564 static inline fdrive_t *drv0 (fdctrl_t *fdctrl) 571 static inline fdrive_t *drv0 (fdctrl_t *fdctrl)
@@ -579,9 +586,7 @@ static fdrive_t *get_cur_drv (fdctrl_t *fdctrl) @@ -579,9 +586,7 @@ static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
579 /* Status B register : 0x01 (read-only) */ 586 /* Status B register : 0x01 (read-only) */
580 static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl) 587 static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl)
581 { 588 {
582 - fdctrl_reset_irq(fdctrl);  
583 FLOPPY_DPRINTF("status register: 0x00\n"); 589 FLOPPY_DPRINTF("status register: 0x00\n");
584 -  
585 return 0; 590 return 0;
586 } 591 }
587 592
@@ -608,7 +613,6 @@ static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl) @@ -608,7 +613,6 @@ static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl)
608 613
609 static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value) 614 static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value)
610 { 615 {
611 - fdctrl_reset_irq(fdctrl);  
612 /* Reset mode */ 616 /* Reset mode */
613 if (fdctrl->state & FD_CTRL_RESET) { 617 if (fdctrl->state & FD_CTRL_RESET) {
614 if (!(value & 0x04)) { 618 if (!(value & 0x04)) {
@@ -653,7 +657,6 @@ static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl) @@ -653,7 +657,6 @@ static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl)
653 { 657 {
654 uint32_t retval = 0; 658 uint32_t retval = 0;
655 659
656 - fdctrl_reset_irq(fdctrl);  
657 /* Disk boot selection indicator */ 660 /* Disk boot selection indicator */
658 retval |= fdctrl->bootsel << 2; 661 retval |= fdctrl->bootsel << 2;
659 /* Tape indicators: never allowed */ 662 /* Tape indicators: never allowed */
@@ -664,7 +667,6 @@ static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl) @@ -664,7 +667,6 @@ static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl)
664 667
665 static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value) 668 static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value)
666 { 669 {
667 - fdctrl_reset_irq(fdctrl);  
668 /* Reset mode */ 670 /* Reset mode */
669 if (fdctrl->state & FD_CTRL_RESET) { 671 if (fdctrl->state & FD_CTRL_RESET) {
670 FLOPPY_DPRINTF("Floppy controler in RESET state !\n"); 672 FLOPPY_DPRINTF("Floppy controler in RESET state !\n");
@@ -681,7 +683,6 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl) @@ -681,7 +683,6 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
681 { 683 {
682 uint32_t retval = 0; 684 uint32_t retval = 0;
683 685
684 - fdctrl_reset_irq(fdctrl);  
685 fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET); 686 fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET);
686 if (!(fdctrl->state & FD_CTRL_BUSY)) { 687 if (!(fdctrl->state & FD_CTRL_BUSY)) {
687 /* Data transfer allowed */ 688 /* Data transfer allowed */
@@ -703,7 +704,6 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl) @@ -703,7 +704,6 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
703 /* Data select rate register : 0x04 (write) */ 704 /* Data select rate register : 0x04 (write) */
704 static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value) 705 static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value)
705 { 706 {
706 - fdctrl_reset_irq(fdctrl);  
707 /* Reset mode */ 707 /* Reset mode */
708 if (fdctrl->state & FD_CTRL_RESET) { 708 if (fdctrl->state & FD_CTRL_RESET) {
709 FLOPPY_DPRINTF("Floppy controler in RESET state !\n"); 709 FLOPPY_DPRINTF("Floppy controler in RESET state !\n");
@@ -728,7 +728,6 @@ static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl) @@ -728,7 +728,6 @@ static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
728 { 728 {
729 uint32_t retval = 0; 729 uint32_t retval = 0;
730 730
731 - fdctrl_reset_irq(fdctrl);  
732 if (drv0(fdctrl)->drflags & FDRIVE_REVALIDATE || 731 if (drv0(fdctrl)->drflags & FDRIVE_REVALIDATE ||
733 drv1(fdctrl)->drflags & FDRIVE_REVALIDATE) 732 drv1(fdctrl)->drflags & FDRIVE_REVALIDATE)
734 retval |= 0x80; 733 retval |= 0x80;
@@ -795,8 +794,10 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, @@ -795,8 +794,10 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
795 fdctrl->fifo[5] = cur_drv->sect; 794 fdctrl->fifo[5] = cur_drv->sect;
796 fdctrl->fifo[6] = FD_SECTOR_SC; 795 fdctrl->fifo[6] = FD_SECTOR_SC;
797 fdctrl->data_dir = FD_DIR_READ; 796 fdctrl->data_dir = FD_DIR_READ;
798 - if (fdctrl->state & FD_CTRL_BUSY) 797 + if (fdctrl->state & FD_CTRL_BUSY) {
799 DMA_release_DREQ(fdctrl->dma_chann); 798 DMA_release_DREQ(fdctrl->dma_chann);
  799 + fdctrl->state &= ~FD_CTRL_BUSY;
  800 + }
800 fdctrl_set_fifo(fdctrl, 7, 1); 801 fdctrl_set_fifo(fdctrl, 7, 1);
801 } 802 }
802 803
@@ -916,7 +917,6 @@ static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size) @@ -916,7 +917,6 @@ static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size)
916 uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00; 917 uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
917 918
918 fdctrl = opaque; 919 fdctrl = opaque;
919 - fdctrl_reset_irq(fdctrl);  
920 if (!(fdctrl->state & FD_CTRL_BUSY)) { 920 if (!(fdctrl->state & FD_CTRL_BUSY)) {
921 FLOPPY_DPRINTF("Not in DMA transfer mode !\n"); 921 FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
922 return 0; 922 return 0;
@@ -1049,7 +1049,6 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) @@ -1049,7 +1049,6 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
1049 uint32_t retval = 0; 1049 uint32_t retval = 0;
1050 int pos, len; 1050 int pos, len;
1051 1051
1052 - fdctrl_reset_irq(fdctrl);  
1053 cur_drv = get_cur_drv(fdctrl); 1052 cur_drv = get_cur_drv(fdctrl);
1054 fdctrl->state &= ~FD_CTRL_SLEEP; 1053 fdctrl->state &= ~FD_CTRL_SLEEP;
1055 if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) { 1054 if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) {
@@ -1073,10 +1072,12 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) @@ -1073,10 +1072,12 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
1073 /* Switch from transfert mode to status mode 1072 /* Switch from transfert mode to status mode
1074 * then from status mode to command mode 1073 * then from status mode to command mode
1075 */ 1074 */
1076 - if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) 1075 + if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
1077 fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00); 1076 fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
1078 - else 1077 + } else {
1079 fdctrl_reset_fifo(fdctrl); 1078 fdctrl_reset_fifo(fdctrl);
  1079 + fdctrl_reset_irq(fdctrl);
  1080 + }
1080 } 1081 }
1081 FLOPPY_DPRINTF("data register: 0x%02x\n", retval); 1082 FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
1082 1083
@@ -1152,7 +1153,6 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) @@ -1152,7 +1153,6 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
1152 { 1153 {
1153 fdrive_t *cur_drv; 1154 fdrive_t *cur_drv;
1154 1155
1155 - fdctrl_reset_irq(fdctrl);  
1156 cur_drv = get_cur_drv(fdctrl); 1156 cur_drv = get_cur_drv(fdctrl);
1157 /* Reset mode */ 1157 /* Reset mode */
1158 if (fdctrl->state & FD_CTRL_RESET) { 1158 if (fdctrl->state & FD_CTRL_RESET) {
@@ -1583,7 +1583,9 @@ enqueue: @@ -1583,7 +1583,9 @@ enqueue:
1583 case 0x4A: 1583 case 0x4A:
1584 /* READ_ID */ 1584 /* READ_ID */
1585 FLOPPY_DPRINTF("treat READ_ID command\n"); 1585 FLOPPY_DPRINTF("treat READ_ID command\n");
1586 - fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 1586 + /* XXX: should set main status register to busy */
  1587 + qemu_mod_timer(fdctrl->result_timer,
  1588 + qemu_get_clock(vm_clock) + (ticks_per_sec / 50));
1587 break; 1589 break;
1588 case 0x4C: 1590 case 0x4C:
1589 /* RESTORE */ 1591 /* RESTORE */
@@ -1688,3 +1690,9 @@ enqueue: @@ -1688,3 +1690,9 @@ enqueue:
1688 } 1690 }
1689 } 1691 }
1690 } 1692 }
  1693 +
  1694 +static void fdctrl_result_timer(void *opaque)
  1695 +{
  1696 + fdctrl_t *fdctrl = opaque;
  1697 + fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1698 +}