From 91874e231a634cf11592464f78d941184213e386 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 22 Jul 2024 03:19:40 +0200 Subject: [PATCH] The monster FDC ROM is now optionally writable (also finally made the SCSI NVR's per-instance), closes #4623. --- src/floppy/fdc_monster.c | 73 +++++++++++++++++++++++++++++++++++++-- src/include/86box/mem.h | 5 +++ src/mem/mem.c | 13 +++++++ src/scsi/scsi_aha154x.c | 9 +++-- src/scsi/scsi_ncr53c8xx.c | 14 ++++---- src/scsi/scsi_pcscsi.c | 3 +- 6 files changed, 104 insertions(+), 13 deletions(-) diff --git a/src/floppy/fdc_monster.c b/src/floppy/fdc_monster.c index 1629ac1c4..2feafdf07 100644 --- a/src/floppy/fdc_monster.c +++ b/src/floppy/fdc_monster.c @@ -41,13 +41,71 @@ typedef struct monster_fdc_t { rom_t bios_rom; fdc_t *fdc_pri; fdc_t *fdc_sec; + char *nvr_path; } monster_fdc_t; +static void +rom_write(uint32_t addr, uint8_t val, void *priv) +{ + const rom_t *rom = (rom_t *) priv; + +#ifdef ROM_TRACE + if (rom->mapping.base == ROM_TRACE) + rom_log("ROM: read byte from BIOS at %06lX\n", addr); +#endif + + if (addr < rom->mapping.base) + return; + if (addr >= (rom->mapping.base + rom->sz)) + return; + rom->rom[(addr - rom->mapping.base) & rom->mask] = val; +} + +static void +rom_writew(uint32_t addr, uint16_t val, void *priv) +{ + rom_t *rom = (rom_t *) priv; + +#ifdef ROM_TRACE + if (rom->mapping.base == ROM_TRACE) + rom_log("ROM: read word from BIOS at %06lX\n", addr); +#endif + + if (addr < (rom->mapping.base - 1)) + return; + if (addr >= (rom->mapping.base + rom->sz)) + return; + *(uint16_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask] = val; +} + +static void +rom_writel(uint32_t addr, uint32_t val, void *priv) +{ + rom_t *rom = (rom_t *) priv; + +#ifdef ROM_TRACE + if (rom->mapping.base == ROM_TRACE) + rom_log("ROM: read long from BIOS at %06lX\n", addr); +#endif + + if (addr < (rom->mapping.base - 3)) + return; + if (addr >= (rom->mapping.base + rom->sz)) + return; + *(uint32_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask] = val; +} + static void monster_fdc_close(void *priv) { monster_fdc_t *dev = (monster_fdc_t *) priv; + FILE *f = fopen(dev->nvr_path, "wb"); + if (f != NULL) { + fwrite(dev->bios_rom.rom, 1, 0x2000, f); + fclose(f); + } + free(dev); } @@ -79,9 +137,18 @@ monster_fdc_init(UNUSED(const device_t *info)) fdc_set_dma_ch(dev->fdc_sec, sec_dma); #endif -#if 0 uint8_t rom_writes_enabled = device_get_config_int("rom_writes_enabled"); -#endif + if (rom_writes_enabled) { + mem_mapping_set_write_handler(&dev->bios_rom.mapping, rom_write, rom_writew, rom_writel); + dev->nvr_path = "monster_fdc_0.nvr"; + dev->nvr_path[12] = device_get_instance() + 0x30; + FILE *f = fopen(dev->nvr_path, "rb"); + if (f != NULL) { + fread(dev->bios_rom.rom, 1, 0x2000, f); + fclose(f); + } + } else + dev->nvr_path = NULL; return dev; } @@ -197,6 +264,7 @@ static const device_config_t monster_fdc_config[] = { { .description = "" } } }, +#endif { .name = "rom_writes_enabled", .description = "Enable BIOS extension ROM Writes", @@ -204,7 +272,6 @@ static const device_config_t monster_fdc_config[] = { .default_string = "", .default_int = 0 }, -#endif { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index beb690918..3c0e0aee0 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -391,6 +391,11 @@ extern void mem_mapping_set_handler(mem_mapping_t *, void (*write_w)(uint32_t addr, uint16_t val, void *priv), void (*write_l)(uint32_t addr, uint32_t val, void *priv)); +extern void mem_mapping_set_write_handler(mem_mapping_t *, + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv)); + extern void mem_mapping_set_p(mem_mapping_t *, void *priv); extern void mem_mapping_set_addr(mem_mapping_t *, diff --git a/src/mem/mem.c b/src/mem/mem.c index 8f2e0d935..ae6e4ae00 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2556,6 +2556,19 @@ mem_mapping_set_handler(mem_mapping_t *map, mem_mapping_recalc(map->base, map->size); } +void +mem_mapping_set_write_handler(mem_mapping_t *map, + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv)) +{ + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + + mem_mapping_recalc(map->base, map->size); +} + void mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) { diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 2927d797c..c811c2c87 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -1043,7 +1043,8 @@ aha_init(const device_t *info) case AHA_154xC: strcpy(dev->name, "AHA-154xC"); dev->bios_path = "roms/scsi/adaptec/aha1542c102.bin"; - dev->nvr_path = "aha1542c.nvr"; + dev->nvr_path = "aha1542c_0.nvr"; + dev->nvr_path[9] = device_get_instance() + 0x30; dev->fw_rev = "D001"; dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ @@ -1059,7 +1060,8 @@ aha_init(const device_t *info) case AHA_154xCF: strcpy(dev->name, "AHA-154xCF"); dev->bios_path = "roms/scsi/adaptec/aha1542cf211.bin"; - dev->nvr_path = "aha1542cf.nvr"; + dev->nvr_path = "aha1542cf_0.nvr"; + dev->nvr_path[10] = device_get_instance() + 0x30; dev->fw_rev = "E001"; dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ @@ -1080,7 +1082,8 @@ aha_init(const device_t *info) bios_rev = (char *) device_get_config_bios("bios_rev"); dev->bios_path = (char *) device_get_bios_file(info, bios_rev, 0); dev->mcode_path = (char *) device_get_bios_file(info, bios_rev, 1); - dev->nvr_path = "aha1542cp.nvr"; + dev->nvr_path = "aha1542cp_0.nvr"; + dev->nvr_path[10] = device_get_instance() + 0x30; dev->fw_rev = aha1542cp_rev; dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index f640c49a6..1fd9fcdba 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2571,37 +2571,39 @@ ncr53c8xx_init(const device_t *info) switch (dev->chip) { case CHIP_810: - dev->nvr_path = "ncr53c810.nvr"; + dev->nvr_path = "ncr53c810_0.nvr"; dev->wide = 0; break; case CHIP_815: dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c815.nvr"; + dev->nvr_path = "ncr53c815_0.nvr"; dev->wide = 0; break; case CHIP_820: - dev->nvr_path = "ncr53c820.nvr"; + dev->nvr_path = "ncr53c820_0.nvr"; dev->wide = 1; break; case CHIP_825: dev->chip_rev = 0x26; - dev->nvr_path = "ncr53c825a.nvr"; + dev->nvr_path = "ncr53c825_0.nvr"; dev->wide = 1; break; case CHIP_860: scsi_bus_set_speed(dev->bus, 20000000.0); dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c860.nvr"; + dev->nvr_path = "ncr53c860_0.nvr"; dev->wide = 1; break; case CHIP_875: scsi_bus_set_speed(dev->bus, 40000000.0); dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c875.nvr"; + dev->nvr_path = "ncr53c875_0.nvr"; dev->wide = 1; break; } + dev->nvr_path[10] = device_get_instance() + 0x30; + ncr53c8xx_pci_bar[0].addr_regs[0] = 1; ncr53c8xx_pci_bar[1].addr_regs[0] = 0; ncr53c8xx_pci_regs[0x04] = 3; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 674bbdabf..48b2d52fa 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1856,7 +1856,8 @@ dc390_init(UNUSED(const device_t *info)) if (dev->has_bios) esp_bios_disable(dev); - dev->nvr_path = "dc390.nvr"; + dev->nvr_path = "dc390_0.nvr"; + dev->nvr_path[6] = device_get_instance() + 0x30; /* Load the serial EEPROM. */ dc390_load_eeprom(dev);