From 8c18273b23d1ac1d5169cba8fb323c5f1517bb7e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jan 2026 19:10:00 +0100 Subject: [PATCH] Added the MSI-5156 (most of the work done by Kotochi). --- src/chipset/intel_piix.c | 6 +- src/include/86box/chipset.h | 3 + src/include/86box/machine.h | 4 ++ src/include/86box/nvr.h | 1 + src/machine/m_at_socket7.c | 125 ++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 47 +++++++++++++- src/nvr_at.c | 85 ++++++++++++++++++------ 7 files changed, 247 insertions(+), 24 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index c6f6486d1..9d4d88687 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1554,7 +1554,7 @@ piix_init(const device_t *info) dev->rev = (info->local >> 4) & 0x0f; dev->func_shift = (info->local >> 8) & 0x0f; dev->no_mirq0 = (info->local >> 12) & 0x0f; - dev->func0_id = info->local >> 16; + dev->func0_id = (info->local >> 16) & 0xffff; pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev, &dev->pci_slot); piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); @@ -1580,7 +1580,9 @@ piix_init(const device_t *info) dev->usb = device_add(&usb_device); if (dev->type > 3) { - if (!strcmp(machine_get_internal_name(), "ms5156")) + if (info->local & PIIX4_NVR_AMI_1995J) + dev->nvr = device_add(&piix4_ami_1995j_nvr_device); + else if (info->local & PIIX4_NVR_AMI_1995) dev->nvr = device_add(&piix4_ami_1995_nvr_device); else dev->nvr = device_add(&piix4_nvr_device); diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 64b5bd88f..4ded831bd 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -105,6 +105,9 @@ extern const device_t i450kx_device; extern const device_t sio_device; extern const device_t sio_zb_device; +#define PIIX4_NVR_AMI_1995 0x0000000100000000 +#define PIIX4_NVR_AMI_1995J 0x0000000200000000 + extern const device_t piix_device; extern const device_t piix_no_mirq_device; extern const device_t piix_old_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 92b448eeb..6ab3883c8 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1097,6 +1097,10 @@ extern const device_t an430tx_device; extern int machine_at_an430tx_init(const machine_t *); extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_thunderbolt_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms5156_device; +#endif +extern int machine_at_ms5156_init(const machine_t *); extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 4d187b785..9d6d78923 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -96,6 +96,7 @@ extern const device_t ami_1994_nvr_device; extern const device_t ami_1995_nvr_device; extern const device_t via_nvr_device; extern const device_t piix4_ami_1995_nvr_device; +extern const device_t piix4_ami_1995j_nvr_device; extern const device_t p6rp4_nvr_device; extern const device_t martin_nvr_device; extern const device_t elt_nvr_device; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7261e2616..24b0b9e84 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1548,6 +1548,131 @@ machine_at_thunderbolt_init(const machine_t *model) return ret; } +static const device_config_t ms5156_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms5156w", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision 1.0", + .internal_name = "ms5156a", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556MS10.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.0 (Japanese)", + .internal_name = "ms5156aj", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556J110.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.0 (Traditional Chinese)", + .internal_name = "ms5156atc", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556C410.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.3 (Simplified Chinese)", + .internal_name = "ms5156asc", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556C313.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 1.5", + .internal_name = "ms5156w", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/W556MS15.BIN", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 1.6B1 (ACPI Beta)", + .internal_name = "ms5156wab", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/W556MS16.001", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms5156_device = { + .name = "MSI MS-5156", + .internal_name = "ms5156", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms5156_config +}; + +int +machine_at_ms5156_init(const machine_t *model) +{ + int ret; + const char *fn; + + device_context(model->device); + int is_english = !strcmp(device_get_config_bios("bios"), "ms5156a"); + int is_award = !strcmp(device_get_config_bios("bios"), "ms5156w") || !strcmp(device_get_config_bios("bios"), "ms5156wab"); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ + + device_add(&i430tx_device); + if (is_award) + device_add(&piix4_device); + else if (is_english) + device_add_params(&piix4_device, (void *) PIIX4_NVR_AMI_1995); + else + device_add_params(&piix4_device, (void *) PIIX4_NVR_AMI_1995J); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); + device_add(&sst_flash_29ee010_device); /* assumed */ + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + int machine_at_ma23c_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2cd3db8a5..5437534ac 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -16232,6 +16232,51 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i430TX] MSI MS-5156", + .internal_name = "ms5156", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_ms5156_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 55000000, + .max_bus = 75000000, + .min_voltage = 2700, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 4096, + .max = 262144, + .step = 4096 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ms5156_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or AMI MEGAKEY '5' KBC firmware. */ { @@ -18288,7 +18333,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, /* Manual thinks the maximum memory is 1024MB (256x4MB), but there is no 4th memory slot */ + .max = 786432, /* Manual mistakenly says 1 GB with 256 MB in each slot, even though it only has three slots */ .step = 8192 }, .nvrmask = 255, diff --git a/src/nvr_at.c b/src/nvr_at.c index 8283c08b0..11b5ffc45 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -289,15 +289,16 @@ #define RTC_REGS 14 /* number of registers */ -#define FLAG_NO_NMI 0x001 -#define FLAG_AMI_1992_HACK 0x002 -#define FLAG_AMI_1994_HACK 0x004 -#define FLAG_AMI_1995_HACK 0x008 -#define FLAG_AMI_1999_HACK 0x010 -#define FLAG_P6RP4_HACK 0x020 -#define FLAG_PIIX4 0x040 -#define FLAG_MULTI_BANK 0x080 -#define FLAG_MARTIN_HACK 0x100 +#define FLAG_NO_NMI 0x001 +#define FLAG_AMI_1992_HACK 0x002 +#define FLAG_AMI_1994_HACK 0x004 +#define FLAG_AMI_1995_HACK 0x008 +#define FLAG_AMI_1999_HACK 0x010 +#define FLAG_AMI_1999J_HACK 0x020 +#define FLAG_P6RP4_HACK 0x040 +#define FLAG_PIIX4 0x080 +#define FLAG_MULTI_BANK 0x100 +#define FLAG_MARTIN_HACK 0x200 typedef struct local_t { int8_t stat; @@ -578,7 +579,9 @@ nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) nvr->is_new = 0; if ((reg == 0x52) && (local->flags & FLAG_AMI_1995_HACK)) nvr->is_new = 0; - if ((reg == 0x55) && (local->flags & FLAG_AMI_1999_HACK)) + if ((reg == 0x54) && (local->flags & FLAG_AMI_1999_HACK)) + nvr->is_new = 0; + if ((reg == 0x55) && (local->flags & FLAG_AMI_1999J_HACK)) nvr->is_new = 0; if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0]) return; @@ -830,6 +833,20 @@ nvr_read(uint16_t addr, void *priv) else ret = checksum & 0xff; } else if (!nvr->is_new && (local->flags & FLAG_AMI_1999_HACK)) { + /* The checksum at 3E-3F is for 37-3D and 40-73. */ + for (i = 0x37; i <= 0x3d; i++) + checksum += nvr->regs[i]; + for (i = 0x40; i <= 0x73; i++) { + if (i == 0x54) + checksum += (nvr->regs[i] & 0x3f); + else + checksum += nvr->regs[i]; + } + if (local->addr[addr_id] == 0x3e) + ret = checksum >> 8; + else + ret = checksum & 0xff; + } else if (!nvr->is_new && (local->flags & FLAG_AMI_1999J_HACK)) { /* The checksum at 3E-3F is for 37-3D and 40-73. */ for (i = 0x37; i <= 0x3d; i++) checksum += nvr->regs[i]; @@ -875,8 +892,15 @@ nvr_read(uint16_t addr, void *priv) ret = nvr->regs[local->addr[addr_id]]; break; - case 0x55: + case 0x54: if (!nvr->is_new && (local->flags & FLAG_AMI_1999_HACK)) + ret = nvr->regs[local->addr[addr_id]] & 0x3f; + else + ret = nvr->regs[local->addr[addr_id]]; + break; + + case 0x55: + if (!nvr->is_new && (local->flags & FLAG_AMI_1999J_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0xfc; else ret = nvr->regs[local->addr[addr_id]]; @@ -1198,15 +1222,20 @@ nvr_at_init(const device_t *info) local->cent = RTC_CENTURY_VIA; break; case 8: /* Epson Equity LT */ - if ((info->local & 0x1f) == 0x18) { - local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999_HACK); - local->def = 0x00; - nvr->irq = 8; - local->cent = RTC_CENTURY_AT; - } else { - nvr->irq = -1; - local->cent = RTC_CENTURY_ELT; - } + nvr->irq = -1; + local->cent = RTC_CENTURY_ELT; + break; + case 9: /* Intel PIIX4 + AMI 1999 hack */ + local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999_HACK); + local->def = 0x00; + nvr->irq = 8; + local->cent = RTC_CENTURY_AT; + break; + case 0x0a: /* Intel PIIX4 + AMI 1999J hack */ + local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999J_HACK); + local->def = 0x00; + nvr->irq = 8; + local->cent = RTC_CENTURY_AT; break; default: @@ -1485,7 +1514,21 @@ const device_t piix4_ami_1995_nvr_device = { .name = "Intel PIIX4 AMI WinBIOS 1995 PC/AT NVRAM", .internal_name = "piix4_ami_1995_nvr", .flags = DEVICE_ISA16, - .local = 0x10 | 8, + .local = 0x10 | 9, + .init = nvr_at_init, + .close = nvr_at_close, + .reset = nvr_at_reset, + .available = NULL, + .speed_changed = nvr_at_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t piix4_ami_1995j_nvr_device = { + .name = "Intel PIIX4 AMI WinBIOS 1995J PC/AT NVRAM", + .internal_name = "piix4_ami_1995j_nvr", + .flags = DEVICE_ISA16, + .local = 0x10 | 10, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset,