ISA ROM Board Support

This commit is contained in:
Jasmine Iwanek
2025-05-04 21:44:53 -04:00
parent 7957da5838
commit 16975c374f
11 changed files with 960 additions and 1 deletions

View File

@@ -70,6 +70,7 @@
#include <86box/unittester.h>
#include <86box/novell_cardkey.h>
#include <86box/isamem.h>
#include <86box/isarom.h>
#include <86box/isartc.h>
#include <86box/lpt.h>
#include <86box/serial.h>
@@ -181,6 +182,7 @@ int postcard_enabled = 0; /* (C) enable
int unittester_enabled = 0; /* (C) enable unit tester device */
int gameport_type[GAMEPORT_MAX] = { 0, 0 }; /* (C) enable gameports */
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
int isarom_type[ISAROM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA ROM cards */
int isartc_type = 0; /* (C) enable ISA RTC card */
int gfxcard[GFXCARD_MAX] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
@@ -1472,6 +1474,10 @@ pc_reset_hard_init(void)
zip_hard_reset();
/* Reset any ISA ROM cards. */
isarom_reset();
/* Reset any ISA RTC cards. */
isartc_reset();

View File

@@ -46,6 +46,7 @@
#include <86box/ini.h>
#include <86box/config.h>
#include <86box/isamem.h>
#include <86box/isarom.h>
#include <86box/isartc.h>
#include <86box/lpt.h>
#include <86box/serial.h>
@@ -1699,6 +1700,7 @@ load_other_peripherals(void)
if (!novell_keycard_enabled)
ini_section_delete_var(cat, "novell_keycard_enabled");
// ISA RAM Boards
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
sprintf(temp, "isamem%d_type", c);
@@ -1709,6 +1711,17 @@ load_other_peripherals(void)
ini_section_delete_var(cat, temp);
}
// ISA ROM Boards
for (uint8_t c = 0; c < ISAROM_MAX; c++) {
sprintf(temp, "isarom%d_type", c);
p = ini_section_get_string(cat, temp, "none");
isarom_type[c] = isarom_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
p = ini_section_get_string(cat, "isartc_type", "none");
isartc_type = isartc_get_from_internal_name(p);
@@ -1858,6 +1871,8 @@ config_load(void)
cdrom[0].sound_on = 1;
mem_size = 64;
isartc_type = 0;
for (i = 0; i < ISAROM_MAX; i++)
isarom_type[i] = 0;
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = 0;
@@ -2706,6 +2721,7 @@ save_other_peripherals(void)
else
ini_section_set_int(cat, "novell_keycard_enabled", novell_keycard_enabled);
// ISA RAM Boards
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
sprintf(temp, "isamem%d_type", c);
if (isamem_type[c] == 0)
@@ -2715,6 +2731,16 @@ save_other_peripherals(void)
isamem_get_internal_name(isamem_type[c]));
}
// ISA ROM Boards
for (uint8_t c = 0; c < ISAROM_MAX; c++) {
sprintf(temp, "isarom%d_type", c);
if (isarom_type[c] == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
isarom_get_internal_name(isarom_type[c]));
}
if (isartc_type == 0)
ini_section_delete_var(cat, "isartc_type");
else

View File

@@ -33,6 +33,7 @@ add_library(dev OBJECT
i2c_gpio.c
ibm_5161.c
isamem.c
isarom.c
isartc.c
isapnp.c
kbc_at.c

643
src/device/isarom.c Normal file
View File

@@ -0,0 +1,643 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of ISA ROM card Expansions.
*
* Authors: Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2025 Jasmine Iwanek.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/nvr.h>
#include <86box/isarom.h>
#define ISAROM_CARD 0
#define ISAROM_CARD_DUAL 1
#define ISAROM_CARD_QUAD 2
#ifdef ENABLE_ISAROM_LOG
int isarom_do_log = ENABLE_ISAROM_LOG;
static void
isarom_log(const char *fmt, ...)
{
va_list ap;
if (isarom_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define isarom_log(fmt, ...)
#endif
typedef struct isarom_t {
struct {
rom_t rom;
uint32_t addr;
const char *fn;
uint32_t size;
uint32_t len;
char nvr_path[64];
uint8_t wp;
} socket[4];
uint8_t inst;
uint8_t type;
} isarom_t;
static inline uint8_t
get_limit(uint8_t type)
{
if (type == ISAROM_CARD_DUAL)
return 2;
if (type == ISAROM_CARD_QUAD)
return 4;
return 1;
}
static inline void
isarom_save_nvr(char *path, uint8_t *data, size_t size)
{
if (path[0] == 0x00)
return;
FILE *fp = nvr_fopen(path, "wb");
if (fp) {
fwrite(data, 1, size, fp);
fclose(fp);
}
}
void
isarom_close(void *priv)
{
isarom_t *dev = (isarom_t *) priv;
if (!priv)
return;
for (uint8_t i = 0; i < get_limit(dev->type); i++)
if (dev->socket[i].rom.rom) {
isarom_log("isarom[%u]: saving NVR for socket %u -> %s (%u bytes)\n",
dev->inst, i, dev->socket[i].nvr_path, dev->socket[i].size);
isarom_save_nvr(dev->socket[i].nvr_path, dev->socket[i].rom.rom, dev->socket[i].size);
}
free(dev);
}
static void *
isarom_init(const device_t *info)
{
isarom_t *dev = (isarom_t *) calloc(1, sizeof(isarom_t));
if (!dev)
return NULL;
dev->inst = device_get_instance();
dev->type = (uint8_t) info->local;
isarom_log("isarom[%u]: initializing device (type=%u)\n", dev->inst, dev->type);
for (uint8_t i = 0; i < get_limit(dev->type); i++) {
char key_fn[12];
char key_addr[14];
char key_size[14];
char key_writes[22];
char suffix[4] = "";
if (i > 0)
snprintf(suffix, sizeof(suffix), "%d", i + 1);
snprintf(key_fn, sizeof(key_fn), "bios_fn%s", suffix);
snprintf(key_addr, sizeof(key_addr), "bios_addr%s", suffix);
snprintf(key_size, sizeof(key_size), "bios_size%s", suffix);
snprintf(key_writes, sizeof(key_writes), "rom_writes_enabled%s", suffix);
dev->socket[i].fn = device_get_config_string(key_fn);
dev->socket[i].addr = device_get_config_hex20(key_addr);
dev->socket[i].size = device_get_config_int(key_size);
// Note: 2K is the smallest ROM I've found, but 86box's memory granularity is 4k, the number below is fine
// as we'll end up allocating no less than 4k due to the device config limits.
dev->socket[i].len = (dev->socket[i].size > 2048) ? dev->socket[i].size - 1 : 0;
dev->socket[i].wp = (uint8_t) device_get_config_int(key_writes) ? 1 : 0;
isarom_log("isarom[%u]: socket %u: addr=0x%05X size=%u wp=%u fn=%s\n",
dev->inst, i, dev->socket[i].addr, dev->socket[i].size,
dev->socket[i].wp, dev->socket[i].fn ? dev->socket[i].fn : "(null)");
if (dev->socket[i].addr != 0 && dev->socket[i].fn != NULL) {
rom_init(&dev->socket[i].rom,
dev->socket[i].fn,
dev->socket[i].addr,
dev->socket[i].size,
dev->socket[i].len,
0,
MEM_MAPPING_EXTERNAL);
isarom_log("isarom[%u]: ROM initialized for socket %u\n", dev->inst, i);
if (dev->socket[i].wp) {
mem_mapping_set_write_handler(&dev->socket[i].rom.mapping, rom_write, rom_writew, rom_writel);
snprintf(dev->socket[i].nvr_path, sizeof(dev->socket[i].nvr_path), "isarom_%i_%i.nvr", dev->inst, i + 1);
FILE *fp = nvr_fopen(dev->socket[i].nvr_path, "rb");
if (fp != NULL) {
fread(dev->socket[i].rom.rom, 1, dev->socket[i].size, fp);
fclose(fp);
isarom_log("isarom[%u]: loaded %zu bytes from %s\n", dev->inst, read_bytes, dev->socket[i].nvr_path);
} else
isarom_log("isarom[%u]: NVR not found, skipping load (%s)\n", dev->inst, dev->socket[i].nvr_path);
}
}
}
return dev;
}
#define BIOS_FILE_FILTER "ROM files (*.bin *.rom)|*.bin,*.rom"
#define BIOS_ADDR_SELECTION { \
{ "Disabled", 0x00000 }, \
{ "C000H", 0xc0000 }, \
{ "C200H", 0xc2000 }, \
{ "C400H", 0xc4000 }, \
{ "C600H", 0xc6000 }, \
{ "C800H", 0xc8000 }, \
{ "CA00H", 0xca000 }, \
{ "CC00H", 0xcc000 }, \
{ "CE00H", 0xce000 }, \
{ "D000H", 0xd0000 }, \
{ "D200H", 0xd2000 }, \
{ "D400H", 0xd4000 }, \
{ "D600H", 0xd6000 }, \
{ "D800H", 0xd8000 }, \
{ "DA00H", 0xda000 }, \
{ "DC00H", 0xdc000 }, \
{ "DE00H", 0xde000 }, \
{ "E000H", 0xe0000 }, \
{ "E200H", 0xe2000 }, \
{ "E400H", 0xe4000 }, \
{ "E600H", 0xe6000 }, \
{ "E800H", 0xe8000 }, \
{ "EA00H", 0xea000 }, \
{ "EC00H", 0xec000 }, \
{ "EE00H", 0xee000 }, \
{ "", 0 } \
}
#define BIOS_SIZE_SELECTION { \
{ "4K", 4096 }, \
{ "8K", 8192 }, \
{ "16K", 16384 }, \
{ "32K", 32768 }, \
{ "64K", 65536 }, \
{ "", 0 } \
}
// clang-format off
static const device_config_t isarom_config[] = {
{
.name = "bios_fn",
.description = "BIOS File",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = BIOS_FILE_FILTER,
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr",
.description = "BIOS Address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size",
.description = "BIOS Size:",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled",
.description = "Enable BIOS extension ROM Writes",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t isarom_dual_config[] = {
{
.name = "bios_fn",
.description = "BIOS File (ROM #1)",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = BIOS_FILE_FILTER,
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr",
.description = "BIOS Address (ROM #1)",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size",
.description = "BIOS Size (ROM #1):",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled",
.description = "Enable BIOS extension ROM Writes (ROM #1)",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "bios_fn2",
.description = "BIOS File (ROM #2)",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = BIOS_FILE_FILTER,
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr2",
.description = "BIOS Address (ROM #2)",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size2",
.description = "BIOS Size (ROM #2):",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled2",
.description = "Enable BIOS extension ROM Writes (ROM #2)",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t isarom_quad_config[] = {
{
.name = "bios_fn",
.description = "BIOS File (ROM #1)",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = BIOS_FILE_FILTER,
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr",
.description = "BIOS Address (ROM #1)",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size",
.description = "BIOS Size (ROM #1):",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled",
.description = "Enable BIOS extension ROM Writes (ROM #1)",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "bios_fn2",
.description = "BIOS File (ROM #2)",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = BIOS_FILE_FILTER,
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr2",
.description = "BIOS Address (ROM #2)",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size2",
.description = "BIOS Size (ROM #2):",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled2",
.description = "Enable BIOS extension ROM Writes (ROM #2)",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "bios_fn3",
.description = "BIOS File (ROM #3)",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = "ROM files (*.bin *.rom)|*.bin,*.rom",
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr3",
.description = "BIOS Address (ROM #3)",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size3",
.description = "BIOS Size (ROM #3):",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled3",
.description = "Enable BIOS extension ROM Writes (ROM #3)",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "bios_fn4",
.description = "BIOS File (ROM #4)",
.type = CONFIG_FNAME,
.default_string = NULL,
.default_int = 0,
.file_filter = BIOS_FILE_FILTER,
.spinner = { 0 },
.selection = { },
.bios = { { 0 } }
},
{
.name = "bios_addr4",
.description = "BIOS Address (ROM #4)",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_ADDR_SELECTION,
.bios = { { 0 } }
},
{
.name = "bios_size4",
.description = "BIOS Size (ROM #4):",
.type = CONFIG_INT,
.default_string = NULL,
.default_int = 8192,
.file_filter = NULL,
.spinner = { 0 },
.selection = BIOS_SIZE_SELECTION,
.bios = { { 0 } }
},
{
.name = "rom_writes_enabled4",
.description = "Enable BIOS extension ROM Writes (ROM #4)",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
};
// clang-format on
static const device_t isarom_device = {
.name = "Generic ISA ROM Board",
.internal_name = "isarom",
.flags = DEVICE_ISA,
.local = ISAROM_CARD,
.init = isarom_init,
.close = isarom_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = isarom_config
};
static const device_t isarom_dual_device = {
.name = "Generic Dual ISA ROM Board",
.internal_name = "isarom_dual",
.flags = DEVICE_ISA,
.local = ISAROM_CARD_DUAL,
.init = isarom_init,
.close = isarom_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = isarom_dual_config
};
static const device_t isarom_quad_device = {
.name = "Generic Quad ISA ROM Board",
.internal_name = "isarom_quad",
.flags = DEVICE_ISA,
.local = ISAROM_CARD_QUAD,
.init = isarom_init,
.close = isarom_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = isarom_quad_config
};
static const struct {
const device_t *dev;
} boards[] = {
// clang-format off
{ &device_none },
{ &isarom_device },
{ &isarom_dual_device },
{ &isarom_quad_device },
{ NULL }
// clang-format on
};
void
isarom_reset(void)
{
for (uint8_t i = 0; i < ISAROM_MAX; i++) {
if (isarom_type[i] == 0)
continue;
/* Add the device instance to the system. */
device_add_inst(boards[isarom_type[i]].dev, i + 1);
}
}
const char *
isarom_get_name(int board)
{
if (boards[board].dev == NULL)
return NULL;
return (boards[board].dev->name);
}
const char *
isarom_get_internal_name(int board)
{
return device_get_internal_name(boards[board].dev);
}
int
isarom_get_from_internal_name(const char *str)
{
int c = 0;
while (boards[c].dev != NULL) {
if (!strcmp(boards[c].dev->internal_name, str))
return c;
c++;
}
/* Not found. */
return 0;
}
const device_t *
isarom_get_device(int board)
{
/* Add the device instance to the system. */
return boards[board].dev;
}
int
isarom_has_config(int board)
{
if (boards[board].dev == NULL)
return 0;
return (boards[board].dev->config ? 1 : 0);
}

View File

@@ -134,6 +134,7 @@ extern int postcard_enabled; /* (C) enable POST card */
extern int unittester_enabled; /* (C) enable unit tester device */
extern int gameport_type[]; /* (C) enable gameports */
extern int isamem_type[]; /* (C) enable ISA mem cards */
extern int isarom_type[]; /* (C) enable ISA ROM cards */
extern int isartc_type; /* (C) enable ISA RTC card */
extern int sound_is_float; /* (C) sound uses FP values */
extern int voodoo_enabled; /* (C) video option */

View File

@@ -122,6 +122,7 @@ typedef struct config_t {
int ide_qua_enabled; /* Quaternary IDE controller enabled */
int bugger_enabled; /* ISA bugger device enabled */
int isa_rtc_type; /* ISA RTC card */
int isa_rom_type[ISAROM_MAX]; /* ISA ROM boards */
int isa_mem_type[ISAMEM_MAX]; /* ISA memory boards */
/* Hard disks category */

View File

@@ -0,0 +1,37 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of ISA ROM card Expansions.
*
* Authors: Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2025 Jasmine Iwanek.
*/
#ifndef EMU_ISAROM_H
#define EMU_ISAROM_H
#define ISAROM_MAX 4 /* max #cards in system */
#ifdef __cplusplus
extern "C" {
#endif
/* Functions. */
extern void isarom_reset(void);
extern const char *isarom_get_name(int t);
extern const char *isarom_get_internal_name(int t);
extern int isarom_get_from_internal_name(const char *str);
extern const device_t *isarom_get_device(int t);
extern int isarom_has_config(int board);
#ifdef __cplusplus
}
#endif
#endif /*EMU_ISAROM_H*/

View File

@@ -39,6 +39,7 @@
#include <86box/video.h>
#include <86box/machine.h>
#include <86box/isamem.h>
#include <86box/isarom.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
@@ -111,6 +112,11 @@ machine_init_ex(int m)
/* Reset any ISA memory cards. */
isamem_reset();
#if 0
/* Reset any ISA ROM cards. */
isarom_reset();
#endif
/* Reset the fast off stuff. */
cpu_fast_off_reset();

View File

@@ -24,6 +24,7 @@ extern "C" {
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/isamem.h>
#include <86box/isarom.h>
#include <86box/isartc.h>
#include <86box/unittester.h>
#include <86box/novell_cardkey.h>
@@ -65,6 +66,10 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId)
if (auto *cb = findChild<QComboBox *>(QString("comboBoxIsaMemCard%1").arg(i + 1)))
cb->clear();
for (uint8_t i = 0; i < ISAROM_MAX; ++i)
if (auto *cb = findChild<QComboBox *>(QString("comboBoxIsaRomCard%1").arg(i + 1)))
cb->clear();
int c = 0;
int selectedRow = 0;
@@ -127,6 +132,47 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId)
findChild<QPushButton *>(QString("pushButtonConfigureIsaMemCard%1").arg(i + 1))->setEnabled((isamem_type[i] != 0) &&
isamem_has_config(isamem_type[i]) && machineHasIsa);
}
// ISA ROM Expansion Cards
QComboBox *isarom_cbox[ISAROM_MAX] = { 0 };
QAbstractItemModel *isarom_models[ISAROM_MAX] = { 0 };
int isarom_removeRows_[ISAROM_MAX] = { 0 };
int isarom_selectedRows[ISAROM_MAX] = { 0 };
for (uint8_t i = 0; i < ISAROM_MAX; ++i) {
isarom_cbox[i] = findChild<QComboBox *>(QString("comboBoxIsaRomCard%1").arg(i + 1));
isarom_models[i] = isarom_cbox[i]->model();
isarom_removeRows_[i] = isarom_models[i]->rowCount();
}
c = 0;
while (true) {
const QString name = DeviceConfig::DeviceName(isarom_get_device(c),
isarom_get_internal_name(c), 0);
if (name.isEmpty())
break;
if (device_is_valid(isarom_get_device(c), machineId)) {
for (uint8_t i = 0; i < ISAROM_MAX; ++i) {
int row = Models::AddEntry(isarom_models[i], name, c);
if (c == isarom_type[i])
isarom_selectedRows[i] = row - isarom_removeRows_[i];
}
}
c++;
}
for (uint8_t i = 0; i < ISAROM_MAX; ++i) {
isarom_models[i]->removeRows(0, isarom_removeRows_[i]);
isarom_cbox[i]->setEnabled(isarom_models[i]->rowCount() > 1);
isarom_cbox[i]->setCurrentIndex(-1);
isarom_cbox[i]->setCurrentIndex(isarom_selectedRows[i]);
findChild<QPushButton *>(QString("pushButtonConfigureIsaRomCard%1").arg(i + 1))->setEnabled((isarom_type[i] != 0) &&
isarom_has_config(isarom_type[i]) && machineHasIsa);
}
}
SettingsOtherPeripherals::~SettingsOtherPeripherals()
@@ -149,6 +195,12 @@ SettingsOtherPeripherals::save()
auto *cbox = findChild<QComboBox *>(QString("comboBoxIsaMemCard%1").arg(i + 1));
isamem_type[i] = cbox->currentData().toInt();
}
/* ISA ROM boards. */
for (int i = 0; i < ISAROM_MAX; i++) {
auto *cbox = findChild<QComboBox *>(QString("comboBoxIsaRomCard%1").arg(i + 1));
isarom_type[i] = cbox->currentData().toInt();
}
}
void
@@ -226,6 +278,66 @@ SettingsOtherPeripherals::on_pushButtonConfigureIsaMemCard4_clicked()
DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxIsaMemCard4->currentData().toInt()), 4);
}
void
SettingsOtherPeripherals::on_comboBoxIsaRomCard1_currentIndexChanged(int index)
{
if (index < 0)
return;
ui->pushButtonConfigureIsaRomCard1->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard1_clicked()
{
DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard1->currentData().toInt()), 1);
}
void
SettingsOtherPeripherals::on_comboBoxIsaRomCard2_currentIndexChanged(int index)
{
if (index < 0)
return;
ui->pushButtonConfigureIsaRomCard2->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard2_clicked()
{
DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard2->currentData().toInt()), 2);
}
void
SettingsOtherPeripherals::on_comboBoxIsaRomCard3_currentIndexChanged(int index)
{
if (index < 0)
return;
ui->pushButtonConfigureIsaRomCard3->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard3_clicked()
{
DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard3->currentData().toInt()), 3);
}
void
SettingsOtherPeripherals::on_comboBoxIsaRomCard4_currentIndexChanged(int index)
{
if (index < 0)
return;
ui->pushButtonConfigureIsaRomCard4->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard4_clicked()
{
DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard4->currentData().toInt()), 4);
}
void
SettingsOtherPeripherals::on_checkBoxUnitTester_stateChanged(int arg1)
{

View File

@@ -32,6 +32,15 @@ private slots:
void on_comboBoxIsaMemCard4_currentIndexChanged(int index);
void on_pushButtonConfigureIsaMemCard4_clicked();
void on_comboBoxIsaRomCard1_currentIndexChanged(int index);
void on_pushButtonConfigureIsaRomCard1_clicked();
void on_comboBoxIsaRomCard2_currentIndexChanged(int index);
void on_pushButtonConfigureIsaRomCard2_clicked();
void on_comboBoxIsaRomCard3_currentIndexChanged(int index);
void on_pushButtonConfigureIsaRomCard3_clicked();
void on_comboBoxIsaRomCard4_currentIndexChanged(int index);
void on_pushButtonConfigureIsaRomCard4_clicked();
void on_checkBoxUnitTester_stateChanged(int arg1);
void on_pushButtonConfigureUT_clicked();

View File

@@ -174,6 +174,123 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxRom">
<property name="title">
<string>ISA ROM Cards</string>
</property>
<layout class="QGridLayout" name="gridLayoutRom">
<item row="0" column="0">
<widget class="QLabel" name="labelIsaRomCard1">
<property name="text">
<string>Card 1:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxIsaRomCard1">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxVisibleItems">
<number>30</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButtonConfigureIsaRomCard1">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelIsaRomCard2">
<property name="text">
<string>Card 2:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBoxIsaRomCard2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxVisibleItems">
<number>30</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButtonConfigureIsaRomCard2">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelIsaRomCard3">
<property name="text">
<string>Card 3:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxIsaRomCard3">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxVisibleItems">
<number>30</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonConfigureIsaRomCard3">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelIsaRomCard4">
<property name="text">
<string>Card 4:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBoxIsaRomCard4">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxVisibleItems">
<number>30</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="pushButtonConfigureIsaRomCard4">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayoutIBPC">
<item>