Revision 78ae820c
b/hw/fdc.c | ||
---|---|---|
417 | 417 |
}; |
418 | 418 |
|
419 | 419 |
enum { |
420 |
#if MAX_FD == 4 |
|
421 |
FD_DOR_SELMASK = 0x03, |
|
422 |
#else |
|
420 | 423 |
FD_DOR_SELMASK = 0x01, |
424 |
#endif |
|
421 | 425 |
FD_DOR_nRESET = 0x04, |
422 | 426 |
FD_DOR_DMAEN = 0x08, |
423 | 427 |
FD_DOR_MOTEN0 = 0x10, |
... | ... | |
427 | 431 |
}; |
428 | 432 |
|
429 | 433 |
enum { |
434 |
#if MAX_FD == 4 |
|
430 | 435 |
FD_TDR_BOOTSEL = 0x0c, |
436 |
#else |
|
437 |
FD_TDR_BOOTSEL = 0x04, |
|
438 |
#endif |
|
431 | 439 |
}; |
432 | 440 |
|
433 | 441 |
enum { |
... | ... | |
494 | 502 |
/* Sun4m quirks? */ |
495 | 503 |
int sun4m; |
496 | 504 |
/* Floppy drives */ |
497 |
fdrive_t drives[2];
|
|
505 |
fdrive_t drives[MAX_FD];
|
|
498 | 506 |
}; |
499 | 507 |
|
500 | 508 |
static uint32_t fdctrl_read (void *opaque, uint32_t reg) |
... | ... | |
602 | 610 |
static void fdc_save (QEMUFile *f, void *opaque) |
603 | 611 |
{ |
604 | 612 |
fdctrl_t *s = opaque; |
613 |
uint8_t tmp; |
|
614 |
int i; |
|
605 | 615 |
|
606 | 616 |
/* Controller state */ |
607 | 617 |
qemu_put_8s(f, &s->sra); |
... | ... | |
627 | 637 |
qemu_put_8s(f, &s->config); |
628 | 638 |
qemu_put_8s(f, &s->lock); |
629 | 639 |
qemu_put_8s(f, &s->pwrd); |
630 |
fd_save(f, &s->drives[0]); |
|
631 |
fd_save(f, &s->drives[1]); |
|
640 |
|
|
641 |
tmp = MAX_FD; |
|
642 |
qemu_put_8s(f, &tmp); |
|
643 |
for (i = 0; i < MAX_FD; i++) |
|
644 |
fd_save(f, &s->drives[i]); |
|
632 | 645 |
} |
633 | 646 |
|
634 | 647 |
static int fd_load (QEMUFile *f, fdrive_t *fd) |
... | ... | |
643 | 656 |
static int fdc_load (QEMUFile *f, void *opaque, int version_id) |
644 | 657 |
{ |
645 | 658 |
fdctrl_t *s = opaque; |
646 |
int ret; |
|
659 |
int i, ret = 0; |
|
660 |
uint8_t n; |
|
647 | 661 |
|
648 | 662 |
if (version_id != 2) |
649 | 663 |
return -EINVAL; |
... | ... | |
672 | 686 |
qemu_get_8s(f, &s->config); |
673 | 687 |
qemu_get_8s(f, &s->lock); |
674 | 688 |
qemu_get_8s(f, &s->pwrd); |
689 |
qemu_get_8s(f, &n); |
|
675 | 690 |
|
676 |
ret = fd_load(f, &s->drives[0]); |
|
677 |
if (ret == 0) |
|
678 |
ret = fd_load(f, &s->drives[1]); |
|
691 |
if (n > MAX_FD) |
|
692 |
return -EINVAL; |
|
693 |
|
|
694 |
for (i = 0; i < n; i++) { |
|
695 |
ret = fd_load(f, &s->drives[i]); |
|
696 |
if (ret != 0) |
|
697 |
break; |
|
698 |
} |
|
679 | 699 |
|
680 | 700 |
return ret; |
681 | 701 |
} |
... | ... | |
773 | 793 |
return &fdctrl->drives[0]; |
774 | 794 |
} |
775 | 795 |
|
796 |
#if MAX_FD == 4 |
|
797 |
static inline fdrive_t *drv2 (fdctrl_t *fdctrl) |
|
798 |
{ |
|
799 |
if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2)) |
|
800 |
return &fdctrl->drives[2]; |
|
801 |
else |
|
802 |
return &fdctrl->drives[1]; |
|
803 |
} |
|
804 |
|
|
805 |
static inline fdrive_t *drv3 (fdctrl_t *fdctrl) |
|
806 |
{ |
|
807 |
if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2)) |
|
808 |
return &fdctrl->drives[3]; |
|
809 |
else |
|
810 |
return &fdctrl->drives[2]; |
|
811 |
} |
|
812 |
#endif |
|
813 |
|
|
776 | 814 |
static fdrive_t *get_cur_drv (fdctrl_t *fdctrl) |
777 | 815 |
{ |
778 |
return fdctrl->cur_drv == 0 ? drv0(fdctrl) : drv1(fdctrl); |
|
816 |
switch (fdctrl->cur_drv) { |
|
817 |
case 0: return drv0(fdctrl); |
|
818 |
case 1: return drv1(fdctrl); |
|
819 |
#if MAX_FD == 4 |
|
820 |
case 2: return drv2(fdctrl); |
|
821 |
case 3: return drv3(fdctrl); |
|
822 |
#endif |
|
823 |
default: return NULL; |
|
824 |
} |
|
779 | 825 |
} |
780 | 826 |
|
781 | 827 |
/* Status A register : 0x00 (read-only) */ |
... | ... | |
923 | 969 |
{ |
924 | 970 |
uint32_t retval = 0; |
925 | 971 |
|
926 |
if (fdctrl_media_changed(drv0(fdctrl)) || |
|
927 |
fdctrl_media_changed(drv1(fdctrl))) |
|
972 |
if (fdctrl_media_changed(drv0(fdctrl)) |
|
973 |
|| fdctrl_media_changed(drv1(fdctrl)) |
|
974 |
#if MAX_FD == 4 |
|
975 |
|| fdctrl_media_changed(drv2(fdctrl)) |
|
976 |
|| fdctrl_media_changed(drv3(fdctrl)) |
|
977 |
#endif |
|
978 |
) |
|
928 | 979 |
retval |= FD_DIR_DSKCHG; |
929 | 980 |
if (retval != 0) |
930 | 981 |
FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval); |
... | ... | |
1367 | 1418 |
/* Drives position */ |
1368 | 1419 |
fdctrl->fifo[0] = drv0(fdctrl)->track; |
1369 | 1420 |
fdctrl->fifo[1] = drv1(fdctrl)->track; |
1421 |
#if MAX_FD == 4 |
|
1422 |
fdctrl->fifo[2] = drv2(fdctrl)->track; |
|
1423 |
fdctrl->fifo[3] = drv3(fdctrl)->track; |
|
1424 |
#else |
|
1370 | 1425 |
fdctrl->fifo[2] = 0; |
1371 | 1426 |
fdctrl->fifo[3] = 0; |
1427 |
#endif |
|
1372 | 1428 |
/* timers */ |
1373 | 1429 |
fdctrl->fifo[4] = fdctrl->timer0; |
1374 | 1430 |
fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0); |
... | ... | |
1400 | 1456 |
/* Drives position */ |
1401 | 1457 |
drv0(fdctrl)->track = fdctrl->fifo[3]; |
1402 | 1458 |
drv1(fdctrl)->track = fdctrl->fifo[4]; |
1459 |
#if MAX_FD == 4 |
|
1460 |
drv2(fdctrl)->track = fdctrl->fifo[5]; |
|
1461 |
drv3(fdctrl)->track = fdctrl->fifo[6]; |
|
1462 |
#endif |
|
1403 | 1463 |
/* timers */ |
1404 | 1464 |
fdctrl->timer0 = fdctrl->fifo[7]; |
1405 | 1465 |
fdctrl->timer1 = fdctrl->fifo[8]; |
... | ... | |
1421 | 1481 |
/* Drives position */ |
1422 | 1482 |
fdctrl->fifo[2] = drv0(fdctrl)->track; |
1423 | 1483 |
fdctrl->fifo[3] = drv1(fdctrl)->track; |
1484 |
#if MAX_FD == 4 |
|
1485 |
fdctrl->fifo[4] = drv2(fdctrl)->track; |
|
1486 |
fdctrl->fifo[5] = drv3(fdctrl)->track; |
|
1487 |
#else |
|
1424 | 1488 |
fdctrl->fifo[4] = 0; |
1425 | 1489 |
fdctrl->fifo[5] = 0; |
1490 |
#endif |
|
1426 | 1491 |
/* timers */ |
1427 | 1492 |
fdctrl->fifo[6] = fdctrl->timer0; |
1428 | 1493 |
fdctrl->fifo[7] = fdctrl->timer1; |
Also available in: Unified diff