From 3f0adb5211a9be8e3c4faf46d2e46beccb9b43ca Mon Sep 17 00:00:00 2001 From: nerd73 Date: Fri, 5 Jun 2020 10:22:59 -0600 Subject: [PATCH 1/3] Add the AMI Excalibur, a VLB OPTi 596/597 machine. Also adds emulation of the OPTi 5x7 chipset, and introduces a clock divider for VLB on 64-bit bus systems. --- src/chipset/opti5x7.c | 126 +++++++++++++++++++++++++++++++++++ src/cpu_common/cpu.c | 15 +++-- src/cpu_common/cpu.h | 7 +- src/cpu_common/cpu_table.c | 4 +- src/include/86box/chipset.h | 1 + src/include/86box/machine.h | 2 + src/machine/m_at_socket4_5.c | 20 ++++++ src/machine/machine_table.c | 3 + src/pit.c | 6 +- src/video/vid_et4000w32.c | 2 +- src/win/Makefile.mingw | 2 +- src/win/Makefile_ndr.mingw | 2 +- 12 files changed, 175 insertions(+), 15 deletions(-) create mode 100644 src/chipset/opti5x7.c diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c new file mode 100644 index 000000000..e725e67eb --- /dev/null +++ b/src/chipset/opti5x7.c @@ -0,0 +1,126 @@ +/*Based off the OPTI 82C546/82C547 datasheet. +The earlier 596/597 appears to be register compatible with the 546/547 from testing.*/ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + + +typedef struct +{ + uint8_t cur_reg, + regs[64]; + port_92_t *port_92; +} opti5x7_t; + +static void +opti5x7_recalcmapping(opti5x7_t *dev) +{ + uint32_t shflags = 0; + + shadowbios = 0; + shadowbios_write = 0; + + + shadowbios |= !!(dev->regs[0x06] & 0x05); + shadowbios_write |= !!(dev->regs[0x06] & 0x0a); + + shflags = (dev->regs[0x06] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + shflags |= (dev->regs[0x06] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state(0xe0000, 0x10000, shflags); + + shflags = (dev->regs[0x06] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + shflags |= (dev->regs[0x06] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state(0xf0000, 0x10000, shflags); + + flushmmucache(); +} +static void +opti5x7_write(uint16_t addr, uint8_t val, void *priv) +{ + opti5x7_t *dev = (opti5x7_t *) priv; +// pclog("Write %02x to OPTi 5x7 address %02x\n", val, addr); + + switch (addr) { + case 0x22: + dev->cur_reg = val; + break; + case 0x24: + dev->regs[dev->cur_reg] = val; + if (dev->cur_reg == 0x02) { + cpu_cache_ext_enabled = val & 0x10; + cpu_update_waitstates(); + } + if (dev->cur_reg == 0x06) { + opti5x7_recalcmapping(dev); + } + break; + } +} + + +static uint8_t +opti5x7_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + opti5x7_t *dev = (opti5x7_t *) priv; + + switch (addr) { + case 0x24: +// pclog("Read from OPTI 5x7 register %02x\n", dev->cur_reg); + ret = dev->regs[dev->cur_reg]; + break; + } + + return ret; +} + + +static void +opti5x7_close(void *priv) +{ + opti5x7_t *dev = (opti5x7_t *) priv; + + free(dev); +} + + +static void * +opti5x7_init(const device_t *info) +{ + opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t)); + memset(dev, 0, sizeof(opti5x7_t)); + + io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev); + io_sethandler(0x0024, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev); + + dev->port_92 = device_add(&port_92_device); +// pclog("OPTi 5x7 init\n"); + opti5x7_recalcmapping(dev); + + + return dev; +} + +const device_t opti5x7_device = { + "OPTi 82C5x6/82C5x7", + 0, + 0, + opti5x7_init, opti5x7_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/cpu_common/cpu.c b/src/cpu_common/cpu.c index 8a10948ac..c9b122dbe 100644 --- a/src/cpu_common/cpu.c +++ b/src/cpu_common/cpu.c @@ -141,7 +141,7 @@ CPU *cpu_s; int cpu_effective; int cpu_multi; double cpu_dmulti; -int cpu_16bitbus; +int cpu_16bitbus, cpu_64bitbus; int cpu_busspeed; int cpu_cyrix_alignment; int CPUID; @@ -309,7 +309,7 @@ cpu_set(void) isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); is_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) || (cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86); - is_pentium = (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX); + is_pentium = (cpu_s->cpu_type == CPU_P24T) || (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX); /* Not Pentiums, but they share the same SMM save state table layout. */ is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4); /* The WinChip datasheet claims these are Pentium-compatible. */ @@ -335,7 +335,8 @@ cpu_set(void) #endif cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); - + cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP); + if (cpu_s->multi) cpu_busspeed = cpu_s->rspeed / cpu_s->multi; else @@ -995,6 +996,7 @@ cpu_set(void) #endif break; + case CPU_P24T: case CPU_PENTIUM: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1787,7 +1789,8 @@ cpu_CPUID(void) break; } break; - + + case CPU_P24T: case CPU_PENTIUM: if (!EAX) { @@ -2697,6 +2700,7 @@ void cpu_RDMSR() } break; + case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: EAX = EDX = 0; @@ -3175,7 +3179,8 @@ void cpu_WRMSR() break; } break; - + + case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: switch (ECX) diff --git a/src/cpu_common/cpu.h b/src/cpu_common/cpu.h index e617f4e6d..3db00d1eb 100644 --- a/src/cpu_common/cpu.h +++ b/src/cpu_common/cpu.h @@ -52,6 +52,7 @@ enum { CPU_Cx486DX4, CPU_Am5x86, CPU_Cx5x86, + CPU_P24T, CPU_WINCHIP, /* 586 class CPUs */ CPU_WINCHIP2, CPU_PENTIUM, @@ -370,7 +371,7 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) /* Global variables. */ extern int cpu_iscyrix; -extern int cpu_16bitbus; +extern int cpu_16bitbus, cpu_64bitbus; extern int cpu_busspeed, cpu_pci_speed; extern int cpu_multi; extern double cpu_dmulti; @@ -379,8 +380,8 @@ extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4; extern int is_am486, is_pentium, is_k5, is_k6, is_p6; -extern int hascache; -extern int isibm486; +extern int hascache; +extern int isibm486; extern int is_rapidcad; extern int hasfpu; #define CPU_FEATURE_RDTSC (1 << 0) diff --git a/src/cpu_common/cpu_table.c b/src/cpu_common/cpu_table.c index 5d8ec3457..41cea5233 100644 --- a/src/cpu_common/cpu_table.c +++ b/src/cpu_common/cpu_table.c @@ -288,8 +288,8 @@ CPU cpus_i486[] = { {"iDX4/100", CPU_iDX4, 100000000, 3.0, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, - {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 2.5, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, - {"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 2.5, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, + {"Pentium OverDrive 63", CPU_P24T, 62500000, 2.5, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, + {"Pentium OverDrive 83", CPU_P24T, 83333333, 2.5, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, {"", -1, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0} }; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index ff92068fc..8ee9a3d54 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -47,6 +47,7 @@ extern const device_t i440zx_device; /* OPTi */ extern const device_t opti495_device; +extern const device_t opti5x7_device; /* C&T */ extern const device_t neat_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 45fc1af6c..5e85906ed 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -253,6 +253,8 @@ extern const device_t *at_cpqiii_get_device(void); #endif /* m_at_socket4_5.c */ +extern int machine_at_excalibur_init(const machine_t *); + extern int machine_at_batman_init(const machine_t *); extern int machine_at_ambradp60_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_VPP60) diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index 59e237567..0567a5d1a 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -41,6 +41,26 @@ #include <86box/sio.h> #include <86box/video.h> #include <86box/machine.h> +int +machine_at_excalibur_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted(L"roms/machines/excalibur/S75P.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ide_vlb_device); + device_add(&opti5x7_device); + device_add(&fdc37c663_device); + device_add(&keyboard_at_ami_device); + + return ret; +} static void diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b5598b194..84c619b43 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -206,6 +206,9 @@ const machine_t machines[] = { { "[486 PCI] Zida Tomato 4DP", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, /* Socket 4 machines */ + /* OPTi 596/597 */ + { "[Socket 4 OPTi] AMI Excalibur VLB", "excalibur", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_excalibur_init, NULL }, + /* 430LX */ { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VPP60) diff --git a/src/pit.c b/src/pit.c index 61d18e317..7c6c1923d 100644 --- a/src/pit.c +++ b/src/pit.c @@ -1029,8 +1029,10 @@ pit_set_clock(int clock) TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32)); isa_timing = (cpuclock / (double)8000000.0); - - bus_timing = (cpuclock / (double)cpu_busspeed); + if (cpu_64bitbus) + bus_timing = (cpuclock / ((double)cpu_busspeed) / 2); + else + bus_timing = (cpuclock / (double)cpu_busspeed); pci_timing = (cpuclock / (double)cpu_pci_speed); /* PCICLK in us for use with timer_on_auto(). */ diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index cf6d61fdc..1568eb008 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -1210,7 +1210,7 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *p) case 0x09: return 0; /*Programming interface*/ case 0x0a: return 0x00; /*Supports VGA interface, XGA compatible*/ - case 0x0b: return is_pentium ? 0x03 : 0x00; /* This has to be done in order to make this card work with the two 486 PCI machines. */ + case 0x0b: return cpu_64bitbus ? 0x03 : 0x00; /* This has to be done in order to make this card work with the two 486 PCI machines. */ case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 9e2ad81d9..e761fc091 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -515,7 +515,7 @@ CPUOBJ := cpu.o cpu_table.o \ $(DYNARECOBJ) CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ - intel_4x0.o neat.o opti495.o scamp.o scat.o \ + intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \ sis_85c471.o sis_85c496.o \ via_apollo.o via_vpx.o wd76c10.o diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 29ff11093..03ae92185 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -519,7 +519,7 @@ CPUOBJ := cpu.o cpu_table.o \ $(DYNARECOBJ) CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ - intel_4x0.o neat.o opti495.o scamp.o scat.o \ + intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \ sis_85c471.o sis_85c496.o \ via_apollo.o via_vpx.o wd76c10.o From 51572530ff470162c8597b1fc53ca8cf483f30b6 Mon Sep 17 00:00:00 2001 From: nerd73 Date: Fri, 5 Jun 2020 10:28:03 -0600 Subject: [PATCH 2/3] Remove waitstates from register 02. --- src/chipset/opti5x7.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index e725e67eb..4a83ed98d 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -63,7 +63,6 @@ opti5x7_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->cur_reg] = val; if (dev->cur_reg == 0x02) { cpu_cache_ext_enabled = val & 0x10; - cpu_update_waitstates(); } if (dev->cur_reg == 0x06) { opti5x7_recalcmapping(dev); From b04908f2a1d4510ba91b58aaae565d04cec9e4f0 Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Fri, 5 Jun 2020 19:30:39 +0300 Subject: [PATCH 3/3] 440LX implementation --- src/chipset/intel_4x0.c | 122 ++++++++++++++++++++++++++++++----- src/include/86box/chipset.h | 1 + src/include/86box/machine.h | 3 +- src/machine/m_at_socket370.c | 4 +- src/machine/machine_table.c | 3 +- 5 files changed, 111 insertions(+), 22 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 14cfa55f3..b06319e11 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -43,6 +43,7 @@ enum INTEL_430VX, INTEL_430TX, INTEL_440FX, + INTEL_440LX, INTEL_440BX, INTEL_440ZX }; @@ -94,7 +95,7 @@ i4x0_smram_handler_phase0(i4x0_t *dev) /* Disable any active mappings. */ if (dev->type >= INTEL_430FX) { - if (dev->type >= INTEL_440BX) { + if (dev->type >= INTEL_440LX) { /* Disable high extended SMRAM. */ /* TODO: This area should point to A0000-FFFFF. */ for (i = 0x100a0000; i < 0x100fffff; i += MEM_GRANULARITY_SIZE) { @@ -257,7 +258,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42); break; case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02); break; } @@ -265,7 +266,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x05: switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: regs[0x05] = (regs[0x05] & ~0x01) | (val & 0x01); break; @@ -278,6 +279,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x07] &= ~(val & 0x70); break; case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430VX: case INTEL_430TX: + case INTEL_440LX: regs[0x07] &= ~(val & 0x30); break; case INTEL_440FX: @@ -331,6 +333,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; } break; + + case 0x34: + switch (dev->type) { + case INTEL_440LX: + regs[0x34] = (val & 0xa0); + } + break; + case 0x4f: switch (dev->type) { case INTEL_430HX: @@ -365,6 +375,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x50] = (val & 0xf4); break; + case INTEL_440LX: + regs[0x50] = (val & 0x03); + break; case INTEL_440BX: regs[0x50] = (regs[0x50] & 0x14) | (val & 0xeb); break; @@ -382,6 +395,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x51] = (val & 0xc3); break; + case INTEL_440LX: + regs[0x51] = (val & 0x80); + break; case INTEL_440BX: case INTEL_440ZX: regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); break; @@ -400,6 +416,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x52] = val; break; + case INTEL_440LX: + regs[0x52] = (val & 0xd0); + break; case INTEL_440BX: case INTEL_440ZX: regs[0x52] = val & 0x07; break; @@ -417,6 +436,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: case INTEL_430TX: regs[0x53] = val & 0x3f; break; + case INTEL_440LX: + regs[0x53] = val & 0x0a; + break; case INTEL_440BX: /* Not applicable to 440ZX as that does not support ECC. */ regs[0x53] = val; @@ -438,6 +460,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x54] = val & 0x82; break; + case INTEL_440LX: + regs[0x54] = val; + break; } break; case 0x55: @@ -445,7 +470,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: case INTEL_430TX: regs[0x55] = val & 0x01; break; - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: regs[0x55] = val; break; } @@ -461,7 +486,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: regs[0x56] = val & 0x76; break; - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: regs[0x56] = val; break; } @@ -485,6 +510,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x57] = val & 0x77; break; + case INTEL_440LX: + regs[0x57] = val & 0x11; + break; case INTEL_440BX: regs[0x57] = val & 0x3f; break; @@ -499,7 +527,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430LX: default: regs[0x58] = val & 0x01; break; - case INTEL_430NX: + case INTEL_430NX: case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: regs[0x58] = val & 0x03; break; @@ -576,7 +604,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: default: regs[addr] = val; @@ -595,7 +623,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -610,7 +638,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x66: switch (dev->type) { case INTEL_430NX: case INTEL_430HX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -619,7 +647,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x67: switch (dev->type) { case INTEL_430NX: case INTEL_430HX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -640,7 +668,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430FX_PB640: regs[0x68] = val & 0x1f; break; - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: regs[0x68] = val & 0xc0; break; case INTEL_440BX: @@ -668,6 +696,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x6a: case 0x6b: switch (dev->type) { case INTEL_430NX: + case INTEL_440LX: case INTEL_440BX: regs[addr] = val; break; @@ -681,6 +710,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x6c: case 0x6d: case 0x6e: switch (dev->type) { + case INTEL_440LX: case INTEL_440BX: regs[addr] = val; break; @@ -692,6 +722,13 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; } break; + case 0x6f: + switch (dev->type){ + case INTEL_440LX: + regs[addr] = val; + break; + } + break; case 0x70: switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: @@ -704,7 +741,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: case INTEL_430TX: regs[addr] = val & 0xfc; break; - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: regs[addr] = val & 0xf8; break; } @@ -718,7 +755,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: regs[addr] = val; break; - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: regs[addr] = val & 0x1f; break; } @@ -853,6 +890,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x80] = val & 0x1b; break; + case INTEL_440LX: + regs[0x80] = val & 0x08; + break; case INTEL_440BX: case INTEL_440ZX: regs[0x7c] = val; break; @@ -861,7 +901,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x91: switch (dev->type) { case INTEL_430HX: case INTEL_440BX: - case INTEL_440FX: + case INTEL_440FX: case INTEL_440LX: /* Not applicable on 82443ZX. */ regs[0x91] &= ~(val & 0x11); break; @@ -869,6 +909,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x92: switch (dev->type) { + case INTEL_440LX: case INTEL_440BX: case INTEL_440ZX: regs[0x92] &= ~(val & 0x1f); break; @@ -877,6 +918,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x93: switch (dev->type) { case INTEL_440FX: + case INTEL_440LX: regs[0x93] = (val & 0x0f); trc_write(0x0093, val & 0x06, NULL); break; @@ -1097,7 +1139,7 @@ i4x0_reset(void *priv) else i4x0_write(0, 0x72, 0x00, priv); - if ((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) { + if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) { for (i = 0; i <= dev->max_func; i++) memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t)); } @@ -1268,6 +1310,28 @@ static void regs[0x71] = 0x10; regs[0x72] = 0x02; break; + case INTEL_440LX: + dev->max_func = 1; + + regs[0x02] = 0x80; regs[0x03] = 0x71; /* 82443LX */ + regs[0x06] = 0x90; + regs[0x10] = 0x08; + regs[0x34] = 0xa0; + if (cpu_busspeed <= 66666667) + regs[0x51] |= 0x00; + else if ((cpu_busspeed > 66666667) && (cpu_busspeed <= 100000000)) + regs[0x51] |= 0x20; + regs[0x53] = 0x83; + regs[0x57] = 0x28; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; + regs[0x72] = 0x02; + regs[0xa0] = 0x02; + regs[0xa2] = 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + break; case INTEL_440BX: case INTEL_440ZX: regs[0x7a] = (info->local >> 8) & 0xff; dev->max_func = (regs[0x7a] & 0x02) ? 0 : 1; @@ -1313,6 +1377,20 @@ static void i4x0_write(regs[0x5f], 0x5f, 0x00, dev); i4x0_write(regs[0x72], 0x72, 0x00, dev); + if ((dev->type == INTEL_440LX) && (dev->max_func == 1)) { + regs = (uint8_t *) dev->regs[1]; + + regs[0x00] = 0x86; regs[0x01] = 0x80; /* Intel */ + regs[0x02] = 0x81; regs[0x03] = 0x71; /* 82443LX */ + regs[0x06] = 0xa0; regs[0x07] = 0x02; + regs[0x0a] = 0x04; regs[0x0b] = 0x06; + regs[0x0e] = 0x01; + regs[0x1c] = 0xf0; + regs[0x1e] = 0xa0; regs[0x1f] = 0x02; + regs[0x20] = 0xf0; regs[0x21] = 0xff; + regs[0x24] = 0xf0; regs[0x25] = 0xff; + } + if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) { regs = (uint8_t *) dev->regs[1]; @@ -1484,6 +1562,20 @@ const device_t i440fx_device = NULL }; +const device_t i440lx_device = +{ + "Intel 82443LX", + DEVICE_PCI, + INTEL_440LX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + const device_t i440bx_device = { diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index ff92068fc..564203587 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -42,6 +42,7 @@ extern const device_t i430hx_device; extern const device_t i430vx_device; extern const device_t i430tx_device; extern const device_t i440fx_device; +extern const device_t i440lx_device; extern const device_t i440bx_device; extern const device_t i440zx_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 45fc1af6c..86a6b294c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -357,9 +357,8 @@ extern int machine_at_s2dge_init(const machine_t *); #endif /* m_at_socket370.c */ -#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_s370slm_init(const machine_t *); -#endif + extern int machine_at_cubx_init(const machine_t *); extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_63a_init(const machine_t *); diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 8852ee804..c730a1af6 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -41,7 +41,6 @@ #include "cpu.h" #include <86box/machine.h> -#if defined(DEV_BRANCH) && defined(NO_SIO) int machine_at_s370slm_init(const machine_t *model) { @@ -65,7 +64,7 @@ machine_at_s370slm_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440bx_device); /*i440LX*/ + device_add(&i440lx_device); device_add(&piix4e_device); device_add(&w83977tf_device); device_add(&keyboard_ps2_ami_pci_device); @@ -96,7 +95,6 @@ machine_at_s370slm_init(const machine_t *model) return ret; } -#endif int machine_at_cubx_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b5598b194..e0b56c03a 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -313,9 +313,8 @@ const machine_t machines[] = { /* PGA370 machines */ /* 440LX */ -#if defined(DEV_BRANCH) && defined(NO_SIO) { "[Socket 370 LX] Supermicro 370SLM", "s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, -#endif + /* 440BX */ { "[Socket 370 BX] ASUS CUBX", "cubx", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL }, { "[Socket 370 BX] A-Trend ATC7020BXII", "atc7020bxii", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL },