From 9107c2fa257df891fbc4be8c8c47c0e14096ec5c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 04:56:31 +0100 Subject: [PATCH] Added the AOpen AP61 and fixed floppies on the LG IBM 440 FX. --- src/chipset/intel_i450kx.c | 56 +++++++++++++++++-------------------- src/cpu/cpu.c | 56 +++++++++++-------------------------- src/cpu/cpu.h | 17 ++++------- src/include/86box/machine.h | 2 +- src/machine/m_at_socket8.c | 39 ++++++++++++++++++++++++-- src/machine/machine_table.c | 40 ++++++++++++++++++++++++++ src/sio/sio_w83787f.c | 10 ++++--- src/sio/sio_w83877f.c | 11 ++++---- 8 files changed, 139 insertions(+), 92 deletions(-) diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 90b807a6d..2f6547309 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -8,19 +8,14 @@ * * Implementation of the Intel 450KX Mars Chipset. * + * i450GX is way more popular of an option but needs more stuff. * + * Authors: Miran Grca, + * Tiseno100, * - * Authors: Tiseno100 - * + * Copyright 2021-2024 Miran Grca. * Copyright 2021 Tiseno100. */ - -/* -Note: i450KX PB manages PCI memory access with MC manages DRAM memory access. -Due to 86Box limitations we can't manage them seperately thus it is dev branch till then. - -i450GX is way more popular of an option but needs more stuff. -*/ #include #include #include @@ -97,17 +92,18 @@ i450kx_smram_recalc(i450kx_t *dev, int bus) const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; uint32_t addr; uint32_t size; + int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08); smram_disable(dev->smram[bus]); addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24); size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000; - if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) { + if ((addr != 0x00000000) && enable) { if (bus) - smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable); else - smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0); } flushmmucache(); @@ -118,10 +114,8 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus) { const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; -#if 0 - // int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED); -#endif - int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); if (bus) mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state); @@ -136,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x04: dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53); @@ -373,6 +367,7 @@ pb_write(int func, int addr, uint8_t val, void *priv) default: break; } + } } static uint8_t @@ -381,10 +376,12 @@ pb_read(int func, int addr, void *priv) const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->pb_pci_conf[addr]; - // pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -407,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x4c: dev->mc_pci_conf[addr] = val & 0xdf; @@ -600,6 +597,7 @@ mc_write(int func, int addr, uint8_t val, void *priv) default: break; } + } } static uint8_t @@ -608,10 +606,12 @@ mc_read(int func, int addr, void *priv) const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->mc_pci_conf[addr]; - // pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -622,10 +622,6 @@ i450kx_reset(void *priv) i450kx_t *dev = (i450kx_t *) priv; uint32_t i; -#if 0 - // pclog("i450KX: i450kx_reset()\n"); -#endif - /* Defaults PB */ dev->pb_pci_conf[0x00] = 0x86; dev->pb_pci_conf[0x01] = 0x80; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index b6cd6f9ad..c3e3c39d4 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2372,10 +2372,10 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - if (!strcmp(machine_get_internal_name(), "ap61")) { + /* if (!strcmp(machine_get_internal_name(), "ap61")) { EAX = 0x00000001; EDX = 0x00000000; - } else { + } else */ { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries Data TLB: 4 KB pages, 4-way set associative, 64 entries */ @@ -2799,7 +2799,9 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { case 0x00: case 0x01: break; @@ -2821,6 +2823,11 @@ amd_k_invalid_rdmsr: EDX = msr.apic_base >> 32; cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + case 0x20: + EAX = msr.ecx20 & 0xffffffff; + EDX = msr.ecx20 >> 32; + break; case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -3022,26 +3029,6 @@ amd_k_invalid_rdmsr: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; break; - case 0x1002ff: - EAX = msr.ecx1002ff & 0xffffffff; - EDX = msr.ecx1002ff >> 32; - break; - case 0x40000020: - EAX = msr.ecx40000020 & 0xffffffff; - EDX = msr.ecx40000020 >> 32; - break; - case 0xf0f00250: - EAX = msr.ecxf0f00250 & 0xffffffff; - EDX = msr.ecxf0f00250 >> 32; - break; - case 0xf0f00258: - EAX = msr.ecxf0f00258 & 0xffffffff; - EDX = msr.ecxf0f00258 >> 32; - break; - case 0xf0f00259: - EAX = msr.ecxf0f00259 & 0xffffffff; - EDX = msr.ecxf0f00259 >> 32; - break; default: i686_invalid_rdmsr: cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); @@ -3303,7 +3290,9 @@ amd_k_invalid_wrmsr: case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { case 0x00: case 0x01: if (EAX || EDX) @@ -3318,6 +3307,10 @@ amd_k_invalid_wrmsr: msr.apic_base = EAX | ((uint64_t) EDX << 32); #endif break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + case 0x20: + msr.ecx20 = EAX | ((uint64_t) EDX << 32); + break; case 0x2a: break; case 0x79: @@ -3462,21 +3455,6 @@ amd_k_invalid_wrmsr: case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; - case 0x1002ff: - msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); - break; - case 0x40000020: - msr.ecx40000020 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00250: - msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00258: - msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00259: - msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32); - break; default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9aee59e60..e185f2e4a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -253,6 +253,12 @@ typedef struct { /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ + + /* Weird long MSR's used by the Hyper-V BIOS. */ + uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits + like a real Deschutes does. */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t ecx79; /* 0x00000079 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ @@ -314,9 +320,6 @@ typedef struct { /* IBM 486SLC and 486BL MSR's */ uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_efer; /* 0xc0000080 */ @@ -338,14 +341,6 @@ typedef struct { /* K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_l2aar; /* 0xc0000089 */ - - /* Weird long MSR's used by the Hyper-V BIOS. */ - uint64_t ecx40000020; /* 0x40000020 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ - uint64_t ecxf0f00258; /* 0xf0f00258 */ - uint64_t ecxf0f00259; /* 0xf0f00259 */ } msr_t; typedef struct { diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index faed59dae..73b27afbf 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -705,8 +705,8 @@ extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); /* m_at_socket8.c */ +extern int machine_at_ap61_init(const machine_t *); extern int machine_at_p6rp4_init(const machine_t *); -extern int machine_at_aurora_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 6e63af732..7ce9d5095 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -39,6 +39,39 @@ #include "cpu.h" #include <86box/machine.h> +int +machine_at_ap61_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap61/ap61r120.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0xFE, 0xFF, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i450kx_device); + device_add(&sio_zb_device); + device_add(&ide_cmd646_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc37c665_device); + device_add(&sst_flash_29ee010_device); + // device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_p6rp4_init(const machine_t *model) { @@ -183,8 +216,10 @@ machine_at_lgibm440fx_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83787f_device); + // device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ami_device); + // device_add(&w83787f_device); + device_add(&w83877f_president_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7406cce30..101052f4e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11655,6 +11655,46 @@ const machine_t machines[] = { /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i450KX] AOpen AP61", + .internal_name = "ap61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_450KX, + .init = machine_at_ap61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i450KX] ASUS P/I-P6RP4", .internal_name = "p6rp4", diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index 33cfc6311..2e4b82059 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -215,8 +215,9 @@ static void w83787f_fdc_handler(w83787f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08)) + if (!(dev->regs[0] & 0x20)) fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -258,10 +259,10 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) return; } else { if (dev->locked) { - if (dev->rw_locked) + if (dev->rw_locked && (dev->cur_reg <= 0x0b)) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else @@ -363,7 +364,7 @@ w83787f_read(uint16_t port, void *priv) else if (port == 0x252) { if (dev->cur_reg == 7) ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); - else if (!dev->rw_locked) + else if (!dev->rw_locked || (dev->cur_reg > 0x0b)) ret = dev->regs[dev->cur_reg]; } } @@ -406,6 +407,7 @@ w83787f_reset(w83787f_t *dev) dev->regs[0x00] = 0xd0; fdc_reset(dev->fdc); + w83787f_fdc_handler(dev); dev->regs[0x01] = 0x2C; dev->regs[0x03] = 0x70; diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877f.c index 8cbb82876..c9a437630 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877f.c @@ -78,12 +78,12 @@ w83877f_remap(w83877f_t *dev) { uint8_t hefras = HEFRAS; - io_removehandler(0x250, 0x0002, + io_removehandler(0x250, 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); io_removehandler(FDC_PRIMARY_ADDR, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250); - io_sethandler(dev->base_address, 0x0002, + io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->key_times = hefras + 1; dev->key = (hefras ? 0x86 : 0x88) | HEFERE; @@ -155,8 +155,9 @@ static void w83877f_fdc_handler(w83877f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + if (dev->regs[0x20] & 0xc0) + fdc_set_base(dev->fdc, make_port(dev, 0x20)); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -252,7 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x29) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else