From 31ca983604699c5e9daa2f36f4a9d0fe0795c299 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 20 Jul 2020 15:07:54 -0300 Subject: [PATCH 1/8] Fix STPC UART port check --- src/chipset/stpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index bf14981fc..4496887c9 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -618,7 +618,7 @@ stpc_serial_handlers(uint8_t val) uart1_io = 0x2f8; } - if ((uart0_io & 0x0f00) < 0x300) { + if (uart0_io < 0x300) { /* The address for UART0 defines the IRQs for both ports. */ uart0_irq = 3; uart1_irq = 4; From a4cf2c7859519cc680b9cac69fd7b9fda3bf200a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 20 Jul 2020 15:24:51 -0300 Subject: [PATCH 2/8] Fix STPC serial unlocking behavior, add some more comments to the code --- src/chipset/stpc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 4496887c9..30b02aab0 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -719,8 +719,9 @@ stpc_reg_read(uint16_t addr, void *priv) if (addr == 0x22) ret = dev->reg_offset; else if (dev->reg_offset >= 0xc0) - return 0xff; /* Cyrix CPU registers: let the CPU code handle those */ + return 0xff; /* Cyrix CPU registers: let the CPU code handle these */ else if ((dev->reg_offset == 0x56) || (dev->reg_offset == 0x57)) { + /* ELCR is in here, not in port 4D0h. */ ret = elcr_read(dev->reg_offset, NULL); if (dev->reg_offset == 0x57) ret |= (dev->regs[dev->reg_offset] & 0x01); @@ -743,7 +744,7 @@ stpc_reset(void *priv) dev->regs[0x7b] = 0xff; if (device_get_priv(&stpc_lpt_device)) dev->regs[0x4c] |= 0x80; /* LPT strap */ - if (stpc_serial_handlers(0)) + if (stpc_serial_handlers(0x00)) dev->regs[0x4c] |= 0x03; /* UART straps */ } @@ -977,7 +978,7 @@ stpc_serial_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - /* Initialization is performed by stpc_reset. */ + /* Initialization is performed by stpc_reset */ return dev; } @@ -1035,18 +1036,19 @@ stpc_lpt_write(uint16_t addr, uint8_t val, void *priv) stpc_lpt_t *dev = (stpc_lpt_t *) priv; if (dev->unlocked < 2) { - if (addr == 0x3f0) { - if (val == 0x55) - dev->unlocked++; - else - dev->unlocked = 0; - } + /* Cheat a little bit: in reality, any write to any + I/O port is supposed to reset the unlock counter. */ + if ((addr == 0x3f0) && (val == 0x55)) + dev->unlocked++; + else + dev->unlocked = 0; } else if (addr == 0x3f0) { if (val == 0xaa) dev->unlocked = 0; else dev->offset = val; } else if (dev->offset == 1) { + /* dev->reg1 is set by stpc_lpt_handlers */ stpc_lpt_handlers(dev, val); } else if (dev->offset == 4) { dev->reg4 = (val & 0x03); From 63a40f18ca6106e681c75dd2ab654b5c813f534a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Jul 2020 13:17:59 -0300 Subject: [PATCH 3/8] Fix header spacing in ioapic --- src/ioapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ioapic.c b/src/ioapic.c index a45ad14c7..498787582 100644 --- a/src/ioapic.c +++ b/src/ioapic.c @@ -7,7 +7,7 @@ * This file is part of the 86Box distribution. * * Skeleton I/O APIC implementation, currently housing the MPS - * table patcher for machines that require it. + * table patcher for machines that require it. * * * From ca12c8f757e81daaeebe89000af89318df25f535 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Jul 2020 13:27:06 -0300 Subject: [PATCH 4/8] Add Virtual PC 2007 port 440h device --- src/device/vpc2007.c | 187 +++++++++++++++++++++++++++++++++++++++++ src/win/Makefile.mingw | 17 +++- 2 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 src/device/vpc2007.c diff --git a/src/device/vpc2007.c b/src/device/vpc2007.c new file mode 100644 index 000000000..b9e8a2f6b --- /dev/null +++ b/src/device/vpc2007.c @@ -0,0 +1,187 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the port 440h device from Virtual PC 2007. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/plat.h> +#include <86box/ui.h> +#include <86box/mem.h> +#include "cpu.h" + + +typedef struct { + uint8_t port440, port440read, port442, port443, port444; +} vpc2007_t; + + +#ifdef ENABLE_VPC2007_LOG +int vpc2007_do_log = ENABLE_VPC2007_LOG; + + +static void +vpc2007_log(const char *fmt, ...) +{ + va_list ap; + + if (vpc2007_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +int vpc2007_do_log = 0; + +#define vpc2007_log(fmt, ...) +#endif + + +static uint8_t +vpc2007_read(uint16_t port, void *priv) +{ + vpc2007_t *dev = (vpc2007_t *) priv; + uint8_t ret = 0xff; + + switch (port) { + case 0x440: + ret = dev->port440read; + dev->port440read = 0x02; + break; + + case 0x445: + if ((dev->port440 == 0x1e) && (dev->port442 == 0x48) && (dev->port444 == 0xa7)) { + switch (dev->port443) { + case 0x0b: + ret = 0x00; + break; + + case 0x1b: case 0x05: + ret = 0x01; + break; + + case 0x02: + ret = 0x02; + break; + + case 0x11: + ret = 0x04; + break; + + case 0x12: + ret = 0x06; + break; + + case 0x04: case 0x0d: + ret = 0x08; + break; + + case 0x03: case 0x09: + ret = 0x0b; + break; + + case 0x15: + ret = 0x12; + break; + + case 0x17: + ret = 0x40; + break; + } + } + + if (ret == 0xff) + vpc2007_log("VPC2007: unknown combination %02X %02X %02X %02X\n", dev->port440, dev->port442, dev->port443, dev->port444); + + break; + + default: + vpc2007_log("VPC2007: read from unknown port %02X\n", port); + break; + } + + return ret; +} + + +static void +vpc2007_write(uint16_t port, uint8_t val, void *priv) +{ + vpc2007_t *dev = (vpc2007_t *) priv; + uint32_t seg; + + switch (port) { + case 0x440: + dev->port440 = val; + dev->port440read = 0x03; + break; + + case 0x442: + dev->port442 = val; + break; + + case 0x443: + dev->port443 = val; + break; + + case 0x444: + dev->port444 = val; + break; + } +} + + +static void * +vpc2007_init(const device_t *info) +{ + vpc2007_t *dev = (vpc2007_t *) malloc(sizeof(vpc2007_t)); + memset(dev, 0, sizeof(vpc2007_t)); + + io_sethandler(0x440, 6, + vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev); + + return dev; +} + + +static void +vpc2007_close(void *priv) +{ + vpc2007_t *dev = (vpc2007_t *) priv; + + io_removehandler(0x440, 6, + vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev); + + free(dev); +} + + +const device_t vpc2007_device = { + "Virtual PC 2007 Port 440h Device", + DEVICE_ISA, + 0, + vpc2007_init, vpc2007_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b50cdec49..00903dca8 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -84,6 +84,9 @@ ifeq ($(DEV_BUILD), y) ifndef VGAWONDER VGAWONDER := y endif + ifndef VIRTUALPC + VIRTUALPC := y + endif ifndef VNC VNC := y endif @@ -160,6 +163,9 @@ else ifndef VGAWONDER VGAWONDER := n endif + ifndef VIRTUALPC + VIRTUALPC := y + endif ifndef VNC VNC := n endif @@ -554,7 +560,7 @@ endif ifeq ($(STPC), y) OPTS += -DUSE_STPC -STPCOBJ := stpc.o +DEVBROBJ += stpc.o endif ifeq ($(596B), y) @@ -565,6 +571,11 @@ ifeq ($(VGAWONDER), y) OPTS += -DUSE_VGAWONDER endif +ifeq ($(VIRTUALPC), y) +OPTS += -DUSE_VIRTUALPC +DEVBROBJ += vpc2007.o +endif + ifeq ($(WIN471), y) OPTS += -DUSE_WIN471 endif @@ -617,7 +628,7 @@ CPUOBJ := cpu.o cpu_table.o \ CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o cs4031.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \ - sis_85c310.o sis_85c471.o sis_85c496.o opti283.o opti291.o $(STPCOBJ) \ + sis_85c310.o sis_85c471.o sis_85c496.o opti283.o opti291.o \ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \ amd640.o @@ -637,7 +648,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_sockets7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o vpc2007.o serial.o \ smbus.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ From bf97498626d35efa1958acbe22995acc8f280630 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Jul 2020 13:47:25 -0300 Subject: [PATCH 5/8] Fix missing declaration of VPC device and other issues --- src/device/vpc2007.c | 1 - src/include/86box/chipset.h | 1 + src/win/Makefile.mingw | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/vpc2007.c b/src/device/vpc2007.c index b9e8a2f6b..7dd9ba1e0 100644 --- a/src/device/vpc2007.c +++ b/src/device/vpc2007.c @@ -129,7 +129,6 @@ static void vpc2007_write(uint16_t port, uint8_t val, void *priv) { vpc2007_t *dev = (vpc2007_t *) priv; - uint32_t seg; switch (port) { case 0x440: diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 2e95dda02..a5cf6e3ab 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -71,6 +71,7 @@ extern const device_t piix4e_device; extern const device_t slc90e66_device; extern const device_t ioapic_device; +extern const device_t vpc2007_device; /* OPTi */ extern const device_t opti283_device; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 00903dca8..b30c0c10e 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -648,7 +648,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_sockets7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o vpc2007.o serial.o \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \ smbus.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ From 58b683eb3a00b310b50ee7ae10f3e99b9a7dbf8e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Jul 2020 13:48:20 -0300 Subject: [PATCH 6/8] Add Virtual PC 2007 machine --- src/include/86box/machine.h | 3 +++ src/machine/m_at_slot1.c | 40 ++++++++++++++++++++++++++++++++++++- src/machine/machine_table.c | 3 +++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 32b338854..4f5d60c2a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -418,6 +418,9 @@ extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_atc6310bxii_init(const machine_t *); extern int machine_at_tsunamiatx_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) +extern int machine_at_vpc2007_init(const machine_t *); +#endif #ifdef EMU_DEVICE_H extern const device_t *at_tsunamiatx_get_device(void); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 9236b459e..e161f7b1b 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -480,7 +480,7 @@ machine_at_p6sba_init(const machine_t *model) machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */ hwm_set_values(machine_hwm); device_add(&w83781d_device); - + return ret; } @@ -528,3 +528,41 @@ at_tsunamiatx_get_device(void) { return &es1371_onboard_device; } + + +#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) +int +machine_at_vpc2007_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/vpc2007/13500.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + device_add(&vpc2007_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ + + return ret; +} +#endif diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1122434f7..8c2c81a69 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -355,6 +355,9 @@ const machine_t machines[] = { { "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL }, { "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL}, {"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, { "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL}, {"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, +#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) + { "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL}, {"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_vpc2007_init, NULL }, +#endif /* Slot 2 machines(Including Slot 1/2 Hybrids) */ /* 440GX */ From 763b61c469713e4f2c09a82b7e56a56ab1f1c558 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Jul 2020 15:00:58 -0300 Subject: [PATCH 7/8] Add special behavior for a reserved 440BX bus speed bit for the Virtual PC 2007 machine --- src/chipset/intel_4x0.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 3f1449aaa..4a75760aa 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -29,6 +29,7 @@ #include <86box/keyboard.h> #include <86box/chipset.h> #include <86box/spd.h> +#include <86box/machine.h> enum @@ -442,9 +443,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case INTEL_440BX: case INTEL_440ZX: regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); + if (!strcmp(machines[machine].internal_name, "vpc2007")) + regs[0x51] |= 0x10; /* Virtual PC 2007 BIOS requires a reserved bus speed bit to be set */ break; case INTEL_440GX: - regs[0x51] = (regs[0x50] & 0x88) | (val & 0x08); + regs[0x51] = (regs[0x50] & 0x88) | (val & 0x08); /*regs[0x51] = (regs[0x50] & 0x88) | (val & 0x77);*/ break; } @@ -1551,6 +1554,8 @@ static void regs[0x51] |= 0x20; else if ((cpu_busspeed > 66666667) && (cpu_busspeed <= 100000000)) regs[0x51] |= 0x00; + if (!strcmp(machines[machine].internal_name, "vpc2007")) + regs[0x51] |= 0x10; /* Virtual PC 2007 BIOS requires a reserved bus speed bit to be set */ regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ regs[0x58] = 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; From e8f2fb0915853f3a52436f3e58424f1a7e0042d3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Jul 2020 15:02:59 -0300 Subject: [PATCH 8/8] Isolate 440BX special behavior to devbranch --- src/chipset/intel_4x0.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 4a75760aa..0fb6e17d9 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -443,8 +443,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case INTEL_440BX: case INTEL_440ZX: regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); +#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) if (!strcmp(machines[machine].internal_name, "vpc2007")) regs[0x51] |= 0x10; /* Virtual PC 2007 BIOS requires a reserved bus speed bit to be set */ +#endif break; case INTEL_440GX: regs[0x51] = (regs[0x50] & 0x88) | (val & 0x08); @@ -1554,8 +1556,10 @@ static void regs[0x51] |= 0x20; else if ((cpu_busspeed > 66666667) && (cpu_busspeed <= 100000000)) regs[0x51] |= 0x00; +#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) if (!strcmp(machines[machine].internal_name, "vpc2007")) regs[0x51] |= 0x10; /* Virtual PC 2007 BIOS requires a reserved bus speed bit to be set */ +#endif regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ regs[0x58] = 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;