Commit ed5fd2cce48520e4c0d4eec016743017df93e43a
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 | 125 | |
126 | 126 | if (track > drv->max_track || |
127 | 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 | 132 | return 2; |
133 | 133 | } |
134 | 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 | 139 | return 3; |
140 | 140 | } |
141 | 141 | sector = _fd_sector(head, track, sect, drv->last_sect); |
... | ... | @@ -240,8 +240,8 @@ static void fd_revalidate (fdrive_t *drv) |
240 | 240 | ro = bdrv_is_read_only(drv->bs); |
241 | 241 | bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect); |
242 | 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 | 245 | } else { |
246 | 246 | bdrv_get_geometry(drv->bs, &nb_sectors); |
247 | 247 | match = -1; |
... | ... | @@ -273,8 +273,8 @@ static void fd_revalidate (fdrive_t *drv) |
273 | 273 | max_track = parse->max_track; |
274 | 274 | last_sect = parse->last_sect; |
275 | 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 | 279 | if (nb_heads == 1) { |
280 | 280 | drv->flags &= ~FDISK_DBL_SIDES; |
... | ... | @@ -285,7 +285,7 @@ static void fd_revalidate (fdrive_t *drv) |
285 | 285 | drv->last_sect = last_sect; |
286 | 286 | drv->ro = ro; |
287 | 287 | } else { |
288 | - printf("No disk in drive\n"); | |
288 | + FLOPPY_DPRINTF("No disk in drive\n"); | |
289 | 289 | drv->last_sect = 0; |
290 | 290 | drv->max_track = 0; |
291 | 291 | drv->flags &= ~FDISK_DBL_SIDES; |
... | ... | @@ -318,6 +318,7 @@ static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq); |
318 | 318 | static void fdctrl_reset_fifo (fdctrl_t *fdctrl); |
319 | 319 | static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size); |
320 | 320 | static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status); |
321 | +static void fdctrl_result_timer(void *opaque); | |
321 | 322 | |
322 | 323 | static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl); |
323 | 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 | 332 | static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl); |
332 | 333 | |
333 | 334 | enum { |
334 | - FD_CTRL_ACTIVE = 0x01, | |
335 | + FD_CTRL_ACTIVE = 0x01, /* XXX: suppress that */ | |
335 | 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 | 339 | FD_CTRL_INTR = 0x10, |
339 | 340 | }; |
340 | 341 | |
... | ... | @@ -372,6 +373,7 @@ struct fdctrl_t { |
372 | 373 | int dma_chann; |
373 | 374 | uint32_t io_base; |
374 | 375 | /* Controler state */ |
376 | + QEMUTimer *result_timer; | |
375 | 377 | uint8_t state; |
376 | 378 | uint8_t dma_en; |
377 | 379 | uint8_t cur_drv; |
... | ... | @@ -425,6 +427,7 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg) |
425 | 427 | retval = (uint32_t)(-1); |
426 | 428 | break; |
427 | 429 | } |
430 | + FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval); | |
428 | 431 | |
429 | 432 | return retval; |
430 | 433 | } |
... | ... | @@ -433,6 +436,8 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value) |
433 | 436 | { |
434 | 437 | fdctrl_t *fdctrl = opaque; |
435 | 438 | |
439 | + FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value); | |
440 | + | |
436 | 441 | switch (reg & 0x07) { |
437 | 442 | case 0x02: |
438 | 443 | fdctrl_write_dor(fdctrl, value); |
... | ... | @@ -476,6 +481,9 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, |
476 | 481 | fdctrl = qemu_mallocz(sizeof(fdctrl_t)); |
477 | 482 | if (!fdctrl) |
478 | 483 | return NULL; |
484 | + fdctrl->result_timer = qemu_new_timer(vm_clock, | |
485 | + fdctrl_result_timer, fdctrl); | |
486 | + | |
479 | 487 | fdctrl->version = 0x90; /* Intel 82078 controler */ |
480 | 488 | fdctrl->irq_lvl = irq_lvl; |
481 | 489 | fdctrl->dma_chann = dma_chann; |
... | ... | @@ -524,10 +532,9 @@ int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num) |
524 | 532 | /* Change IRQ state */ |
525 | 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 | 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 | 565 | fd_reset(&fdctrl->drives[i]); |
559 | 566 | fdctrl_reset_fifo(fdctrl); |
560 | 567 | if (do_irq) |
561 | - fdctrl_raise_irq(fdctrl, 0x20); | |
568 | + fdctrl_raise_irq(fdctrl, 0xc0); | |
562 | 569 | } |
563 | 570 | |
564 | 571 | static inline fdrive_t *drv0 (fdctrl_t *fdctrl) |
... | ... | @@ -579,9 +586,7 @@ static fdrive_t *get_cur_drv (fdctrl_t *fdctrl) |
579 | 586 | /* Status B register : 0x01 (read-only) */ |
580 | 587 | static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl) |
581 | 588 | { |
582 | - fdctrl_reset_irq(fdctrl); | |
583 | 589 | FLOPPY_DPRINTF("status register: 0x00\n"); |
584 | - | |
585 | 590 | return 0; |
586 | 591 | } |
587 | 592 | |
... | ... | @@ -608,7 +613,6 @@ static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl) |
608 | 613 | |
609 | 614 | static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value) |
610 | 615 | { |
611 | - fdctrl_reset_irq(fdctrl); | |
612 | 616 | /* Reset mode */ |
613 | 617 | if (fdctrl->state & FD_CTRL_RESET) { |
614 | 618 | if (!(value & 0x04)) { |
... | ... | @@ -653,7 +657,6 @@ static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl) |
653 | 657 | { |
654 | 658 | uint32_t retval = 0; |
655 | 659 | |
656 | - fdctrl_reset_irq(fdctrl); | |
657 | 660 | /* Disk boot selection indicator */ |
658 | 661 | retval |= fdctrl->bootsel << 2; |
659 | 662 | /* Tape indicators: never allowed */ |
... | ... | @@ -664,7 +667,6 @@ static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl) |
664 | 667 | |
665 | 668 | static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value) |
666 | 669 | { |
667 | - fdctrl_reset_irq(fdctrl); | |
668 | 670 | /* Reset mode */ |
669 | 671 | if (fdctrl->state & FD_CTRL_RESET) { |
670 | 672 | FLOPPY_DPRINTF("Floppy controler in RESET state !\n"); |
... | ... | @@ -681,7 +683,6 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl) |
681 | 683 | { |
682 | 684 | uint32_t retval = 0; |
683 | 685 | |
684 | - fdctrl_reset_irq(fdctrl); | |
685 | 686 | fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET); |
686 | 687 | if (!(fdctrl->state & FD_CTRL_BUSY)) { |
687 | 688 | /* Data transfer allowed */ |
... | ... | @@ -703,7 +704,6 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl) |
703 | 704 | /* Data select rate register : 0x04 (write) */ |
704 | 705 | static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value) |
705 | 706 | { |
706 | - fdctrl_reset_irq(fdctrl); | |
707 | 707 | /* Reset mode */ |
708 | 708 | if (fdctrl->state & FD_CTRL_RESET) { |
709 | 709 | FLOPPY_DPRINTF("Floppy controler in RESET state !\n"); |
... | ... | @@ -728,7 +728,6 @@ static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl) |
728 | 728 | { |
729 | 729 | uint32_t retval = 0; |
730 | 730 | |
731 | - fdctrl_reset_irq(fdctrl); | |
732 | 731 | if (drv0(fdctrl)->drflags & FDRIVE_REVALIDATE || |
733 | 732 | drv1(fdctrl)->drflags & FDRIVE_REVALIDATE) |
734 | 733 | retval |= 0x80; |
... | ... | @@ -795,8 +794,10 @@ static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0, |
795 | 794 | fdctrl->fifo[5] = cur_drv->sect; |
796 | 795 | fdctrl->fifo[6] = FD_SECTOR_SC; |
797 | 796 | fdctrl->data_dir = FD_DIR_READ; |
798 | - if (fdctrl->state & FD_CTRL_BUSY) | |
797 | + if (fdctrl->state & FD_CTRL_BUSY) { | |
799 | 798 | DMA_release_DREQ(fdctrl->dma_chann); |
799 | + fdctrl->state &= ~FD_CTRL_BUSY; | |
800 | + } | |
800 | 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 | 917 | uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00; |
917 | 918 | |
918 | 919 | fdctrl = opaque; |
919 | - fdctrl_reset_irq(fdctrl); | |
920 | 920 | if (!(fdctrl->state & FD_CTRL_BUSY)) { |
921 | 921 | FLOPPY_DPRINTF("Not in DMA transfer mode !\n"); |
922 | 922 | return 0; |
... | ... | @@ -1049,7 +1049,6 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) |
1049 | 1049 | uint32_t retval = 0; |
1050 | 1050 | int pos, len; |
1051 | 1051 | |
1052 | - fdctrl_reset_irq(fdctrl); | |
1053 | 1052 | cur_drv = get_cur_drv(fdctrl); |
1054 | 1053 | fdctrl->state &= ~FD_CTRL_SLEEP; |
1055 | 1054 | if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) { |
... | ... | @@ -1073,10 +1072,12 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) |
1073 | 1072 | /* Switch from transfert mode to status mode |
1074 | 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 | 1076 | fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00); |
1078 | - else | |
1077 | + } else { | |
1079 | 1078 | fdctrl_reset_fifo(fdctrl); |
1079 | + fdctrl_reset_irq(fdctrl); | |
1080 | + } | |
1080 | 1081 | } |
1081 | 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 | 1153 | { |
1153 | 1154 | fdrive_t *cur_drv; |
1154 | 1155 | |
1155 | - fdctrl_reset_irq(fdctrl); | |
1156 | 1156 | cur_drv = get_cur_drv(fdctrl); |
1157 | 1157 | /* Reset mode */ |
1158 | 1158 | if (fdctrl->state & FD_CTRL_RESET) { |
... | ... | @@ -1583,7 +1583,9 @@ enqueue: |
1583 | 1583 | case 0x4A: |
1584 | 1584 | /* READ_ID */ |
1585 | 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 | 1589 | break; |
1588 | 1590 | case 0x4C: |
1589 | 1591 | /* RESTORE */ |
... | ... | @@ -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 | +} | ... | ... |