diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 459370724..d87193538 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1245,7 +1245,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 7: - if (!(fdc->flags & FDC_FLAG_TOSHIBA) && !(fdc->flags & FDC_FLAG_AT)) + if (!(fdc->flags & FDC_FLAG_TOSHIBA) && !(fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_UMC)) return; fdc->rate = val & 0x03; if (fdc->flags & FDC_FLAG_PS1) @@ -1294,7 +1294,7 @@ fdc_read(uint16_t addr, void *priv) ret = 0x00; /* -Drive 2 Installed */ if (!fdd_get_type(1)) - ret |= 80; + ret |= 0x80; /* -Drive Select 1,0 */ switch (drive) { case 0: @@ -1313,6 +1313,12 @@ fdc_read(uint16_t addr, void *priv) } else { if (is486 || !fdc->enable_3f1) ret = 0xff; + else{ + if(fdc->flags & FDC_FLAG_UMC) + { + drive = real_drive(fdc, fdc->dor & 1); + ret = !fdd_is_dd(drive) ? ((fdc->dor & 1) ? 2 : 1) : 0; + } else { ret = 0x70; @@ -1328,6 +1334,7 @@ fdc_read(uint16_t addr, void *priv) if (fdc->dor & 0x20) ret |= 2; } + } } break; case 2: @@ -2173,10 +2180,12 @@ fdc_set_base(fdc_t *fdc, int base) if (fdc->flags & FDC_FLAG_PCJR) io_sethandler(base, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); else { + if(fdc->flags & FDC_FLAG_UMC) + io_sethandler(base + 0x0001, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc); io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc); io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc); io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - if (fdc->flags & FDC_FLAG_TOSHIBA) + if ((fdc->flags & FDC_FLAG_TOSHIBA) || (fdc->flags & FDC_FLAG_UMC)) io_sethandler(base + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); } } @@ -2198,6 +2207,8 @@ fdc_remove(fdc_t *fdc) if (fdc->flags & FDC_FLAG_PCJR) io_removehandler(fdc->base_address, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); else { + if(fdc->flags & FDC_FLAG_UMC) + io_removehandler(fdc->base_address + 0x0001, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc); io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc); io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc); io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); @@ -2433,3 +2444,13 @@ const device_t fdc_dp8473_device = { fdc_reset, { NULL }, NULL, NULL }; + +const device_t fdc_um8398_device = { + "UMC UM8398 Floppy Drive Controller", + 0, + FDC_FLAG_UMC, + fdc_init, + fdc_close, + fdc_reset, + { NULL }, NULL, NULL +}; diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index bdc8149ef..ea754187e 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -34,12 +34,56 @@ #define ROM_B215 L"roms/floppy/magitronic/Magitronic B215 - BIOS ROM.bin" #define ROM_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff) +#define DRIVE_SELECT (int)(real_drive(dev->fdc_controller, i)) typedef struct { fdc_t *fdc_controller; rom_t rom; } b215_t; +static uint8_t +b215_read(uint16_t addr, void *priv) +{ + b215_t *dev = (b215_t *)priv; + + /* + Register 3F0h + + Bit (3-2) for Drive B: + Bit (1-0) for Drive A: + 0: 360KB + 1: 1.2MB + 2: 720KB + 3: 1.44MB + 4: +*/ + int drive_spec[2]; + + for (int i = 0; i <= 1; i++) + { + if (fdd_is_525(DRIVE_SELECT)) + { + if (!fdd_is_dd(DRIVE_SELECT)) + drive_spec[i] = 1; + else if (fdd_doublestep_40(DRIVE_SELECT)) + drive_spec[i] = 2; + else + drive_spec[i] = 0; + } + else + { + if (fdd_is_dd(DRIVE_SELECT) && !fdd_is_double_sided(DRIVE_SELECT)) + drive_spec[i] = 0; + else if (fdd_is_dd(DRIVE_SELECT) && fdd_is_double_sided(DRIVE_SELECT)) + drive_spec[i] = 2; + else + drive_spec[i] = 3; + } + } + + return ((drive_spec[1] << 2) | drive_spec[0]) & 0x0f; +} + static void b215_close(void *priv) { @@ -56,7 +100,8 @@ b215_init(const device_t *info) rom_init(&dev->rom, ROM_B215, ROM_ADDR, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - device_add(&fdc_xt_device); + dev->fdc_controller = device_add(&fdc_um8398_device); + io_sethandler(0x03f0, 1, b215_read, NULL, NULL, NULL, NULL, NULL, dev); return dev; } diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index b818258de..b51f93625 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -34,6 +34,7 @@ extern int fdc_type; #define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ #define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ #define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ +#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ typedef struct { @@ -179,6 +180,7 @@ extern const device_t fdc_at_smc_device; extern const device_t fdc_at_winbond_device; extern const device_t fdc_at_nsc_device; extern const device_t fdc_dp8473_device; +extern const device_t fdc_um8398_device; #endif #endif /*EMU_FDC_H*/