From d5a63540067b599350e90669b871b7c75ecd4dea Mon Sep 17 00:00:00 2001 From: rushieda <185547947+rushieda@users.noreply.github.com> Date: Mon, 19 May 2025 15:53:39 +0300 Subject: [PATCH 1/8] Add the Dell OptiPlex GXL/GXM --- src/include/86box/machine.h | 1 + src/machine/m_at_socket5.c | 32 +++++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c76761b3c..e9dc5bda9 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -672,6 +672,7 @@ extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); extern int machine_at_apollo_init(const machine_t *); +extern int machine_at_optiplex_gxl_init(const machine_t *); extern int machine_at_zappa_init(const machine_t *); extern int machine_at_powermatev_init(const machine_t *); extern int machine_at_hawk_init(const machine_t *); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4b3bbd49c..9981f8e85 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -236,6 +236,38 @@ machine_at_apollo_init(const machine_t *model) return ret; } +int +machine_at_optiplex_gxl_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/optiplex_gxl/DELL.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x10, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87332_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + static void machine_at_zappa_gpio_init(void) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 45986a50a..d9e6f2940 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10553,6 +10553,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a National Semiconductor PC87332VLJ Super I/O with AMIKey 'F' KBC firmware. */ + { + .name = "[i430FX] Dell OptiPlex GXL/GXM", + .internal_name = "optiplex_gxl", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_optiplex_gxl_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, /* Video: S3 Trio64V+ (86C765), Network: 3Com ETHERLINK III (3C509B) */ + .ram = { + .min = 8192, + .max = 131072, + .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 = &s3_phoenix_trio64vplus_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL /* not yet emulated */ + }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the PC87306 Super I/O chip, command 0xA1 returns '5'. Command 0xA0 copyright string: (C)1994 AMI . */ From ec613f16085fe70ce6fe02518f0e716cc2117a58 Mon Sep 17 00:00:00 2001 From: rushieda <185547947+rushieda@users.noreply.github.com> Date: Mon, 19 May 2025 16:18:32 +0300 Subject: [PATCH 2/8] Add the onboard sound for the OptiPlex GXL/GXM --- src/machine/m_at_socket5.c | 4 ++++ src/machine/machine_table.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 9981f8e85..7c5ab697a 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -40,6 +40,7 @@ #include <86box/sio.h> #include <86box/video.h> #include <86box/machine.h> +#include <86box/sound.h> int machine_at_plato_init(const machine_t *model) @@ -259,6 +260,9 @@ machine_at_optiplex_gxl_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d9e6f2940..3e50442c1 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10575,7 +10575,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, /* Video: S3 Trio64V+ (86C765), Network: 3Com ETHERLINK III (3C509B) */ + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM, /* Video: S3 Trio64V+ (86C765), Sound: Creative ViBRA 16S (CT2504), Network: 3Com ETHERLINK III (3C509B) */ .ram = { .min = 8192, .max = 131072, @@ -10590,7 +10590,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, - .snd_device = NULL, + .snd_device = &sb_vibra16s_onboard_device, .net_device = NULL /* not yet emulated */ }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the From d7282ddc46d2059cf1973d0b07d8dacfd5592850 Mon Sep 17 00:00:00 2001 From: rushieda <185547947+rushieda@users.noreply.github.com> Date: Mon, 19 May 2025 16:28:01 +0300 Subject: [PATCH 3/8] Block the Cyrix Cx6x86 from the Dell OptiPlex GXL/GXM as it cannot POST with it --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3e50442c1..f4031c0b7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10566,7 +10566,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_Cx6x86), .min_bus = 60000000, .max_bus = 66666667, .min_voltage = 3380, From e04628cc7cf13131f872c8bc8304eb0c29fa8fbf Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 19 May 2025 19:25:21 +0200 Subject: [PATCH 4/8] Trident pattern and memory access changes (May 19th, 2025) 1. DirectDraw memory address fixes of the day (removing the bit 6 of crtc 2a side of the if in recalctimings). 2. In spite of no documentration or NDA manuals, get data from the pattern registers as best as possible in 32bpp mode, this fixes patterns in 32bpp mode using various stuff. --- src/video/vid_tgui9440.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index af203f327..6fbdb7c3f 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -125,6 +125,7 @@ typedef struct tgui_t { uint8_t rop; uint32_t flags; uint8_t pattern[0x80]; + uint8_t pattern_32bpp[0x100]; int command; int offset; uint16_t ger22; @@ -142,6 +143,7 @@ typedef struct tgui_t { uint32_t pattern_8[8 * 8]; uint32_t pattern_16[8 * 8]; uint32_t pattern_32[8 * 8]; + int pattern_32_idx; } accel; uint8_t copy_latch[16]; /*TGUI9400CXi only*/ @@ -756,7 +758,7 @@ tgui_recalctimings(svga_t *svga) if (svga->vdisp == 1020) svga->vdisp += 2; - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) + if (tgui->oldctrl2 & 0x10) svga->ma_latch <<= 1; svga->lowres = !(svga->crtc[0x2a] & 0x40); @@ -2280,6 +2282,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (count == -1) tgui->accel.x = tgui->accel.y = 0; + tgui->accel.pattern_32_idx = 0; + if (tgui->accel.flags & TGUI_SOLIDFILL) { for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { @@ -2298,22 +2302,21 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (tgui->accel.bpp == 0) { for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tgui->accel.pattern_8[(y * 8) + (7 - x)] = tgui->accel.pattern[x + y * 8]; + tgui->accel.pattern_8[(y * 8) + x] = tgui->accel.pattern[x + y * 8]; } } pattern_data = tgui->accel.pattern_8; } else if (tgui->accel.bpp == 1) { for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tgui->accel.pattern_16[(y * 8) + (7 - x)] = tgui->accel.pattern[x * 2 + y * 16] | (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); + tgui->accel.pattern_16[(y * 8) + x] = tgui->accel.pattern[x * 2 + y * 16] | (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); } } pattern_data = tgui->accel.pattern_16; } else { - for (y = 0; y < 4; y++) { + for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tgui->accel.pattern_32[(y * 8) + (7 - x)] = tgui->accel.pattern[x * 4 + y * 32] | (tgui->accel.pattern[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern[x * 4 + y * 32 + 3] << 24); - tgui->accel.pattern_32[((y + 4) * 8) + (7 - x)] = tgui->accel.pattern[x * 4 + y * 32] | (tgui->accel.pattern[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern[x * 4 + y * 32 + 3] << 24); + tgui->accel.pattern_32[(y * 8) + x] = tgui->accel.pattern_32bpp[x * 4 + y * 32] | (tgui->accel.pattern_32bpp[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern_32bpp[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern_32bpp[x * 4 + y * 32 + 3] << 24); } } pattern_data = tgui->accel.pattern_32; @@ -2396,6 +2399,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) count -= 3; } + READ(tgui->accel.dst, dst_dat); pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; @@ -3192,6 +3196,8 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv) case 0x21fe: case 0x21ff: tgui->accel.pattern[addr & 0x7f] = val; + tgui->accel.pattern_32bpp[tgui->accel.pattern_32_idx] = val; + tgui->accel.pattern_32_idx = (tgui->accel.pattern_32_idx + 1) & 0xff; break; default: From 9f46d0b9d8c700e5c04d89e4229958a75906e310 Mon Sep 17 00:00:00 2001 From: rushieda <185547947+rushieda@users.noreply.github.com> Date: Mon, 19 May 2025 20:59:08 +0300 Subject: [PATCH 5/8] Fix the initialization and general purpose I/O (GPIO) pins for the OptiPlex GXL/GXM --- src/device/kbc_at.c | 11 ++++++++++- src/machine/m_at_socket5.c | 5 +++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 58aab476c..7413b45cf 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1096,7 +1096,16 @@ write64_generic(void *priv, uint8_t val) - Bit 5: Manufacturing jumper (must be set); */ uint8_t p1 = 0x24; - kbc_delay_to_ob(dev, p1, 0, 0x01); + kbc_delay_to_ob(dev, p1, 0, 0x00); + } else if (!strcmp(machine_get_internal_name(), "optiplex_gxl")) { + /* + Dell OptiPlex GXL/GXM: + - Bit 3: Password disable jumper (must be clear); + - Bit 4: Keyboard fuse (must be set); + - Bit 5: Manufacturing jumper (must be set); + */ + uint8_t p1 = 0x30; + kbc_delay_to_ob(dev, p1, 0, 0x00); } else { /* (B0 or F0) | (0x08 or 0x0c) */ uint8_t p1_out = ((dev->p1 | fixed_bits) & 0xf0) | diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 7c5ab697a..5572d0484 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -248,7 +248,8 @@ machine_at_optiplex_gxl_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + device_add(&amstrad_megapc_nvr_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); @@ -263,7 +264,7 @@ machine_at_optiplex_gxl_init(const machine_t *model) if (sound_card_current[0] == SOUND_INTERNAL) machine_snd = device_add(machine_get_snd_device(machine)); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_phoenix_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&pc87332_device); From dbc2baebe915f443e5ce0cb6c81739cdc0cd9d1e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 19 May 2025 22:22:03 +0200 Subject: [PATCH 6/8] Small ATI Mach8 changes (May 19th, 2025) 1. Report the ATI 28800 of the Graphics Ultra as 28800-6. 2. Access the upper word properly on vdisp. 3. Make sure there's enough vsyncstart/vtotal space for a full vertical display. --- src/video/vid_ati_mach8.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 8423f096b..a9544e724 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2510,6 +2510,12 @@ mach_in(uint16_t addr, void *priv) case 0xa9: temp = svga->vc & 0xff; break; + case 0xaa: + if (ATI_GRAPHICS_ULTRA) + temp = 0x06; + else + temp = 0x00; + break; case 0xb0: temp = mach->regs[0xb0] | 0x80; temp &= ~0x18; @@ -2699,12 +2705,10 @@ mach_set_resolution(mach_t *mach, svga_t *svga) dev->vdisp += 2; dev->v_total = dev->v_total_reg + 1; - if (dev->interlace) - dev->v_total >>= 1; dev->v_syncstart = dev->v_sync_start + 1; - if (dev->interlace) - dev->v_syncstart >>= 1; + + mach_log("VSYNCSTART=%d, VTOTAL=%d, interlace=%02x, vdisp=%d.\n", dev->v_syncstart, dev->v_total, dev->interlace, dev->vdisp); if (ATI_8514A_ULTRA) { if ((mach->accel.clock_sel & 0x01) && @@ -3233,7 +3237,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) { if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x20)) { - WRITE8(port, dev->v_disp, val); + WRITE8(port, dev->v_disp, val >> 8); dev->v_disp &= 0x1fff; } } @@ -3267,7 +3271,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) { if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x10)) { - WRITE8(port, dev->v_sync_start, val); + WRITE8(port, dev->v_sync_start, val >> 8); dev->v_sync_start &= 0x1fff; } } From 06f4491193967cec42871b0748bf73f3d68cc6f0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 20 May 2025 20:33:22 +0200 Subject: [PATCH 7/8] Mach8 mode changes of the day (May 20th, 2025) Make the previously Mach8 add-on only mode changes also available to the Graphics Ultra, should fix incorrect resolutions after switching from fullscreen DOS prompt to windowed and viceversa under Win98 (and SE). --- src/video/vid_ati_mach8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index a9544e724..0b5673d69 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2710,7 +2710,7 @@ mach_set_resolution(mach_t *mach, svga_t *svga) mach_log("VSYNCSTART=%d, VTOTAL=%d, interlace=%02x, vdisp=%d.\n", dev->v_syncstart, dev->v_total, dev->interlace, dev->vdisp); - if (ATI_8514A_ULTRA) { + if (!ATI_MACH32) { if ((mach->accel.clock_sel & 0x01) && !(dev->accel.advfunc_cntl & 0x01)) ret = 2; From 39a3d1ded022201f2a48f0d63646ba2ece313682 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 21 May 2025 14:04:55 +0600 Subject: [PATCH 8/8] Backport RxConfig fixes from QEMU --- src/network/net_rtl8139.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 5138b5168..0d07a8f83 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -2549,6 +2549,12 @@ rtl8139_io_writeb(uint32_t addr, uint8_t val, void *priv) break; + case RxConfig: + rtl8139_log("RxConfig write(b) val=0x%02x\n", val); + rtl8139_RxConfig_write(s, + (rtl8139_RxConfig_read(s) & 0xFFFFFF00) | val); + break; + default: rtl8139_log("not implemented write(b) addr=0x%x val=0x%02x\n", addr, val); break;