From 39b249fedfb4051f4a2d78d92af40f4631b7c027 Mon Sep 17 00:00:00 2001 From: bozoscum Date: Mon, 6 Oct 2025 09:28:00 +0800 Subject: [PATCH] Some modifications for Multitech machines (#6258) * add alternative OEM model names for Multitech machines * add Multitech PC-700 BIOS 3.30 * add Multitech PC-900 / Commodore PC-40 BIOS v2.07a.xc * add Multitech PC-500+ BIOS 4.03 and 4.06 * correcting display name of Multitech BIOS 3.10 to 3.1 * merge with origin/master * fix github-advanced-security check error 'uninitialized local variable' * implement the Multitech onboard ISA RTC device --- src/device/isartc.c | 162 +++++++++++++++++++-- src/include/86box/machine.h | 9 ++ src/machine/m_at_286.c | 62 +++++++- src/machine/m_xt.c | 273 +++++++++++++++++++++++++++++++----- src/machine/machine_table.c | 12 +- 5 files changed, 457 insertions(+), 61 deletions(-) diff --git a/src/device/isartc.c b/src/device/isartc.c index 06b7767c8..bdf057b4b 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -82,13 +82,14 @@ #include <86box/pic.h> #include <86box/isartc.h> -#define ISARTC_EV170 0 -#define ISARTC_DTK 1 -#define ISARTC_P5PAK 2 -#define ISARTC_A6PAK 3 -#define ISARTC_VENDEX 4 -#define ISARTC_MPLUS2 5 -#define ISARTC_MM58167 10 +#define ISARTC_EV170 0 +#define ISARTC_DTK 1 +#define ISARTC_P5PAK 2 +#define ISARTC_A6PAK 3 +#define ISARTC_VENDEX 4 +#define ISARTC_MPLUS2 5 +#define ISARTC_RTC58167 6 +#define ISARTC_MM58167 10 #define ISARTC_ROM_MM58167_1 "roms/rtc/glatick/GLaTICK_0.8.8_NS_86B.ROM" /* Generic 58167, AST or EV-170 */ #define ISARTC_ROM_MM58167_2 "roms/rtc/glatick/GLaTICK_0.8.8_NS_86B2.ROM" /* PII-147 */ @@ -509,6 +510,73 @@ mm67_write(uint16_t port, uint8_t val, void *priv) } } +/* Multitech PC-500/PC-500+ onboard RTC 58167 device disigned to use I/O port + * base+0 as register index and base+1 as register data read/write window, + * according to the official RTC utilities SDATE.EXE, STIME.EXE, and TODAY.EXE + * + * the RTC utilities check the RTC millisecond counter first to deteminate the + * presence of the RTC 58167 IC, so here implement the bogus_msec to fool them + */ +static uint8_t rtc58167_index = 0x00; + +static uint8_t +rtc58167_read(uint16_t port, void *priv) +{ + uint8_t ret = 0xff; + uint16_t bogus_msec = (uint16_t)((tsc * 1000) / cpu_s->rspeed); + + switch (port) + { + case 0x2c0: + case 0x300: + ret = rtc58167_index; + break; + + case 0x2c1: + case 0x301: + switch (rtc58167_index) + { + case MM67_MSEC: + ret = (uint8_t)(bogus_msec % 10) << 4; + break; + + case MM67_HUNTEN: + ret = RTC_BCD((uint8_t)((bogus_msec / 10) % 100)); + break; + + default: + ret = mm67_read(((port - 1) + rtc58167_index), priv); + break; + } + break; + + default: + break; + } + + return ret; +} + +static void +rtc58167_write(uint16_t port, uint8_t val, void *priv) +{ + switch (port) + { + case 0x2c0: + case 0x300: + rtc58167_index = val; + break; + + case 0x2c1: + case 0x301: + mm67_write(((port - 1) + rtc58167_index), val, priv); + break; + + default: + break; + } +} + /************************************************************************ * * * Generic code for all supported chips. * @@ -594,6 +662,19 @@ isartc_init(const device_t *info) dev->year = MM67_AL_DOM; /* year, NON STANDARD */ break; + case ISARTC_RTC58167: /* Multitech PC-500/PC-500+ onboard RTC */ + dev->flags |= FLAG_YEARBCD; + dev->base_addr = device_get_config_hex16("base"); + dev->base_addrsz = 8; + dev->irq = device_get_config_int("irq"); + dev->f_rd = rtc58167_read; + dev->f_wr = rtc58167_write; + dev->nvr.reset = mm67_reset; + dev->nvr.start = mm67_start; + dev->nvr.tick = mm67_tick; + dev->year = MM67_AL_HUNTEN; /* year, NON STANDARD */ + break; + default: break; } @@ -929,18 +1010,69 @@ const device_t vendex_xt_rtc_onboard_device = { .config = NULL }; +static const device_config_t rtc58167_config[] = { + // clang-format off + { + .name = "irq", + .description = "IRQ2", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "Enabled", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x2C0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2C0H", .value = 0x2c0 }, + { .description = "300H", .value = 0x300 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END} + // clang-format on +}; + +const device_t rtc58167_device = { + .name = "RTC 58167 IC (Multitech)", + .internal_name = "rtc58167_xt_rtc", + .flags = DEVICE_ISA, + .local = ISARTC_RTC58167, + .init = isartc_init, + .close = isartc_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rtc58167_config +}; + static const struct { const device_t *dev; } boards[] = { // clang-format off - { &device_none }, - { &ev170_device }, - { &pii147_device }, - { &p5pak_device }, - { &a6pak_device }, - { &mplus2_device }, - { &mm58167_device }, - { NULL } + { &device_none }, + { &ev170_device }, + { &pii147_device }, + { &p5pak_device }, + { &a6pak_device }, + { &mplus2_device }, + //{ &rtc58167_device }, /* Multitech onboard ISA RTC */ + { &mm58167_device }, + { NULL } // clang-format on }; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index fadd19f7f..98d9fbd45 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -496,6 +496,9 @@ extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_grid1520_init(const machine_t *); extern int machine_at_pc900_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pc900_device; +#endif extern int machine_at_mr286_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_m290_init(const machine_t *); @@ -1361,7 +1364,13 @@ extern int machine_xt_micoms_xl7turbo_init(const machine_t *); extern const device_t pc500_device; #endif extern int machine_xt_pc500_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pc500plus_device; +#endif extern int machine_xt_pc500plus_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pc700_device; +#endif extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc4i_init(const machine_t *); extern int machine_xt_openxt_init(const machine_t *); diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index 7f6442940..20baec312 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -339,13 +339,69 @@ machine_at_grid1520_init(const machine_t *model) return ret; } +static const device_config_t pc900_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pc900_v207a", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { + .name = "BIOS V2.07A", + .internal_name = "pc900_v207a", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { "roms/machines/pc900/mpf_pc900_v207a.bin", "" } + }, + { + .name = "BIOS V2.07A.XC", + .internal_name = "pc900_v207a_xc", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { "roms/machines/pc900/cbm_pc40_v207a_xc.bin", "" } + } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pc900_device = { + .name = "Multitech PC-900", + .internal_name = "pc900", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pc900_config +}; + int machine_at_pc900_init(const machine_t *model) { - int ret = 0; + int ret = 0; + const char *fn; - ret = bios_load_linear("roms/machines/pc900/mpf_pc900_v207a.bin", - 0x000f8000, 32768, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000f8000, 32768, 0); + device_context_restore(); if (bios_only || !ret) return ret; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index c59b4ef37..550d336a2 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -46,6 +46,7 @@ #include <86box/video.h> extern const device_t vendex_xt_rtc_onboard_device; +extern const device_t rtc58167_device; /* 8088 */ static void @@ -1171,7 +1172,7 @@ static const device_config_t pc500_config[] = { .files = { "roms/machines/pc500/rom330.bin", "" } }, { - .name = "3.10", + .name = "3.1", .internal_name = "pc500_310", .bios_type = BIOS_NORMAL, .files_no = 1, @@ -1182,6 +1183,37 @@ static const device_config_t pc500_config[] = { { .files_no = 0 } } }, + { + .name = "rtc_irq", + .description = "RTC IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "Enabled", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "rtc_port", + .description = "RTC Port Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "2C0H", .value = 0x2c0 }, + { .description = "300H", .value = 0x300 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -1202,6 +1234,209 @@ const device_t pc500_device = { int machine_xt_pc500_init(const machine_t *model) +{ + int ret = 0; + int rtc_irq = -1; + int rtc_port = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + rtc_irq = machine_get_config_int("rtc_irq"); + rtc_port = machine_get_config_int("rtc_port"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 8192, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + device_add(&kbc_pc_device); + + machine_xt_common_init(model, 0); + + if (rtc_port != 0) + device_add(&rtc58167_device); + + return ret; +} + +static const device_config_t pc500plus_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pc500plus_404", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "4.06", + .internal_name = "pc500plus_406", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/machines/pc500/rom406.bin", "" } + }, + { + .name = "4.04", + .internal_name = "pc500plus_404", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/machines/pc500/rom404.bin", "" } + }, + { + .name = "4.03", + .internal_name = "pc500plus_403", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/machines/pc500/rom403.bin", "" } + }, + { .files_no = 0 } + }, + }, + { + .name = "rtc_irq", + .description = "RTC IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "Enabled", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "rtc_port", + .description = "Onboard RTC", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "Enabled", .value = 0x2c0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pc500plus_device = { + .name = "Multitech PC-500 plus", + .internal_name = "pc500plus_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pc500plus_config +}; + +int +machine_xt_pc500plus_init(const machine_t *model) +{ + int ret = 0; + int rtc_irq = -1; + int rtc_port = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + rtc_irq = machine_get_config_int("rtc_irq"); + rtc_port = machine_get_config_int("rtc_port"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fc000, 16384, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + device_add(&kbc_pc_device); + + machine_xt_common_init(model, 0); + + if (rtc_port != 0) + device_add(&rtc58167_device); + + return ret; +} + +static const device_config_t pc700_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pc700_330", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "3.30", + .internal_name = "pc700_330", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc700/multitech pc-700 3.30.bin", "" } + }, + { + .name = "3.1", + .internal_name = "pc700_31", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc700/multitech pc-700 3.1.bin", "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pc700_device = { + .name = "Multitech PC-700", + .internal_name = "pc700_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pc700_config +}; + +int +machine_xt_pc700_init(const machine_t *model) { int ret = 0; const char *fn; @@ -1225,42 +1460,6 @@ machine_xt_pc500_init(const machine_t *model) return ret; } -int -machine_xt_pc500plus_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/pc500/rom404.bin", - 0x000fc000, 16384, 0); - - if (bios_only || !ret) - return ret; - - device_add(&kbc_pc_device); - - machine_xt_common_init(model, 0); - - return ret; -} - -int -machine_xt_pc700_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/pc700/multitech pc-700 3.1.bin", - 0x000fe000, 8192, 0); - - if (bios_only || !ret) - return ret; - - device_add(&kbc_pc_device); - - machine_xt_common_init(model, 0); - - return ret; -} - int machine_xt_pc4i_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9b7b30354..f0672a743 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1097,7 +1097,7 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Multitech PC-500", + .name = "[8088] Multitech PC-500 / Franklin PC 8000", .internal_name = "pc500", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, @@ -1174,7 +1174,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &pc500plus_device, .kbd_device = &keyboard_pc_xt_device, .fdc_device = NULL, .sio_device = NULL, @@ -1183,7 +1183,7 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Multitech PC-700", + .name = "[8088] Multitech PC-700 / Siemens SICOMP PC 16 05", .internal_name = "pc700", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, @@ -1217,7 +1217,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &pc700_device, .kbd_device = &keyboard_pc_xt_device, .fdc_device = NULL, .sio_device = NULL, @@ -3346,7 +3346,7 @@ const machine_t machines[] = { }, /* Has IBM AT KBC firmware. */ { - .name = "[ISA] Multitech PC-900", + .name = "[ISA] Multitech PC-900 / Commodore PC 40 / NBI 4200", .internal_name = "pc900", .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, @@ -3380,7 +3380,7 @@ const machine_t machines[] = { .kbc_p1 = 0x000004f0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &pc900_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL,