diff --git a/src/chipset/via_vt82c49x.c b/src/chipset/via_vt82c49x.c new file mode 100644 index 000000000..85d53340f --- /dev/null +++ b/src/chipset/via_vt82c49x.c @@ -0,0 +1,195 @@ +/* + * 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 VIA VT82C49X chipset. + * + * + * + * Authors: Tiseno100 + * + * Copyright 2020 Tiseno100 + * + */ + +#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 index, + regs[256]; +} vt82c49x_t; + +#define ENABLE_VT82C49X_LOG 1 + +#ifdef ENABLE_VT82C49X_LOG +int vt82c49x_do_log = ENABLE_VT82C49X_LOG; +static void +vt82c49x_log(const char *fmt, ...) +{ + va_list ap; + + if (vt82c49x_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define vt82c49x_log(fmt, ...) +#endif + +static void vt82c49x_shadow_recalc(vt82c49x_t *dev) +{ + +uint32_t wp_c, wp_e, wp_f; + +/* Register 40h */ +wp_c = (dev->regs[0x40] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; +wp_f = (dev->regs[0x40] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; +wp_e = (dev->regs[0x40] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; + +/* Register 30h */ +mem_set_mem_state_both(0xc0000, 0x4000, ((dev->regs[0x30] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x01) ? wp_c : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xc4000, 0x4000, ((dev->regs[0x30] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x04) ? wp_c : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xc8000, 0x4000, ((dev->regs[0x30] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x10) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xcc000, 0x4000, ((dev->regs[0x30] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x40) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + +/* Register 31h */ +mem_set_mem_state_both(0xd0000, 0x4000, ((dev->regs[0x31] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x01) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xd4000, 0x4000, ((dev->regs[0x31] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xd8000, 0x4000, ((dev->regs[0x31] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x10) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xdc000, 0x4000, ((dev->regs[0x31] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x40) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + +/* Register 32h */ +shadowbios = (dev->regs[0x40] & 0x20); +shadowbios_write = (dev->regs[0x40] & 0x10); +mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[0x32] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x32] & 0x40) ? wp_e : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[0x32] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x32] & 0x10) ? wp_f : MEM_WRITE_EXTANY)); + +} + +static void +vt82c49x_write(uint16_t addr, uint8_t val, void *priv) +{ + vt82c49x_t *dev = (vt82c49x_t *) priv; + + switch (addr) { + case 0xa8: + dev->index = val; + break; + + case 0xa9: + dev->regs[dev->index] = val; + + vt82c49x_log("dev->regs[0x%02x] = %02x\n", dev->index, val); + + switch(dev->index){ + /* Wait States */ + case 0x03: + cpu_update_waitstates(); + break; + + /* Shadow RAM */ + case 0x30: + case 0x31: + case 0x32: + case 0x40: + vt82c49x_shadow_recalc(dev); + break; + + /* External Cache Enable(Based on the 486-VC-HD BIOS) */ + case 0x50: + cpu_cache_ext_enabled = (val & 0x84); + break; + + /* SMI/SMM(Not at all perfect or even functional :/) */ + case 0x5b: + + if(val & 0x40) + mem_set_mem_state_smram(1, 0x30000, 0x20000, 0); + + if(val & 0x20) + smi_line = 1; + + break; + } + break; + } +} + + +static uint8_t +vt82c49x_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + vt82c49x_t *dev = (vt82c49x_t *) priv; + + switch (addr) { + case 0xa9: + ret = dev->regs[dev->index]; + break; + } + + return ret; +} + + +static void +vt82c49x_close(void *priv) +{ + vt82c49x_t *dev = (vt82c49x_t *) priv; + + free(dev); +} + + +static void * +vt82c49x_init(const device_t *info) +{ + vt82c49x_t *dev = (vt82c49x_t *) malloc(sizeof(vt82c49x_t)); + memset(dev, 0, sizeof(vt82c49x_t)); + + device_add(&port_92_device); + + io_sethandler(0x0a8, 0x0001, vt82c49x_read, NULL, NULL, vt82c49x_write, NULL, NULL, dev); + io_sethandler(0x0a9, 0x0001, vt82c49x_read, NULL, NULL, vt82c49x_write, NULL, NULL, dev); + + dev->regs[0x30] = 0x00; + dev->regs[0x31] = 0x00; + dev->regs[0x32] = 0x00; + vt82c49x_shadow_recalc(dev); + + return dev; +} + + +const device_t via_vt82c49x_device = { + "VIA VT82C49X", + 0, + 0, + vt82c49x_init, vt82c49x_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c new file mode 100644 index 000000000..c81116b36 --- /dev/null +++ b/src/chipset/via_vt82c505.c @@ -0,0 +1,161 @@ +/* + * 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 VIA VT82C505 VL/PCI Bridge Controller. + * + * + * + * Authors: Tiseno100 + * + * Copyright 2020 Tiseno100 + * + */ + +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> + +typedef struct vt82c505_t +{ + uint8_t pci_conf[256]; +} vt82c505_t; + +static void +vt82c505_write(int func, int addr, uint8_t val, void *priv) +{ + + vt82c505_t *dev = (vt82c505_t *) priv; + + /* Read-Only Registers */ + switch (addr) + { + case 0x00: case 0x01: + case 0x02: case 0x03: + return; + } + + switch(addr) + { + + case 0x04: + dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x07) | (val & 0x07); + break; + + case 0x07: + dev->pci_conf[0x07] = (dev->pci_conf[0x07] & ~0x90) | (val & 0x90); + break; + + case 0x90: + if((dev->pci_conf[0x90] & 0x08) && ((val & 0x07) != 0)) + pci_set_irq_routing(PCI_INTC, val & 0x07); + else + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + + if((dev->pci_conf[0x90] & 0x80) && (((val & 0x07) << 4) != 0)) + pci_set_irq_routing(PCI_INTD, ((val & 0x07) << 4)); + else + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + break; + + case 0x91: + if((dev->pci_conf[0x91] & 0x08) && ((val & 0x07) != 0)) + pci_set_irq_routing(PCI_INTA, val & 0x07); + else + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + + if((dev->pci_conf[0x91] & 0x80) && (((val & 0x07) << 4) != 0)) + pci_set_irq_routing(PCI_INTB, ((val & 0x07) << 4)); + else + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + break; + + } +} + +static uint8_t +vt82c505_read(int func, int addr, void *priv) +{ + + vt82c505_t *dev = (vt82c505_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + return ret; +} + +static void +vt82c505_reset(void *priv) +{ + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + +} + +static void +vt82c505_close(void *priv) +{ + vt82c505_t *dev = (vt82c505_t *) priv; + + free(dev); +} + +static void * +vt82c505_init(const device_t *info) +{ + + vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t)); + memset(dev, 0, sizeof(vt82c505_t)); + + pci_add_card(0, vt82c505_read, vt82c505_write, dev); + + dev->pci_conf[0x00] = 0x06; + dev->pci_conf[0x01] = 0x11; + + dev->pci_conf[0x02] = 0x05; + dev->pci_conf[0x03] = 0x05; + + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = 0x00; + + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x90; + + dev->pci_conf[0x81] = 0x01; + dev->pci_conf[0x84] = 0x03; + + dev->pci_conf[0x85] = 0x00; + + dev->pci_conf[0x93] = 0x40; + + return dev; +} + +const device_t via_vt82c505_device = { + "VIA VT82C505", + DEVICE_PCI, + 0, + vt82c505_init, + vt82c505_close, + vt82c505_reset, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 20aafc2ed..6f299d55e 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -97,6 +97,11 @@ extern const device_t stpc_lpt_device; #endif /* VIA */ + +extern const device_t via_vt82c49x_device; + +extern const device_t via_vt82c505_device; + extern const device_t via_vpx_device; extern const device_t via_vp3_device; extern const device_t via_mvp3_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c7affdfe4..e78006878 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -256,6 +256,8 @@ extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); +extern int machine_at_486vchd_init(const machine_t *); + extern int machine_at_pb410a_init(const machine_t *); extern int machine_at_acera1g_init(const machine_t *); @@ -289,6 +291,10 @@ extern int machine_at_pcm9340_init(const machine_t *); extern int machine_at_pcm5330_init(const machine_t *); #endif +#if defined(DEV_BRANCH) && defined(NO_SIO) +extern int machine_at_486vipio2_init(const machine_t *); +#endif + #ifdef EMU_DEVICE_H extern const device_t *at_acera1g_get_device(void); #endif diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1cd7b60fa..6e4759f3d 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -123,6 +123,26 @@ machine_at_rycleopardlx_init(const machine_t *model) return ret; } +int +machine_at_486vchd_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/486vchd/486-4386-VC-HD.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&via_vt82c49x_device); + device_add(&keyboard_at_device); + device_add(&fdc_at_device); + + return ret; +} + int machine_at_pb410a_init(const machine_t *model) { @@ -745,3 +765,34 @@ machine_at_pcm5330_init(const machine_t *model) return ret; } #endif + +#if defined(DEV_BRANCH) && defined(NO_SIO) +int +machine_at_486vipio2_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/486vipio2/1175G701.BIN", + 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_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&via_vt82c49x_device); + device_add(&via_vt82c505_device); + device_add(&ide_vlb_2ch_device); + device_add(&w83787f_device); + device_add(&keyboard_at_device); + + return ret; +} +#endif diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index cb03c2bfa..cbccfb389 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -217,6 +217,7 @@ const machine_t machines[] = { { "[ALi M1429] Olystar LIL1429", "ali1429", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, { "[ALi M1429] AMI WinBIOS 486", "win486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, { "[VLSI 82C480] IBM PS/1 model 2133", "ibmps1_2133", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI | MACHINE_VIDEO, 2, 32, 1, 127, machine_ps1_m2133_init, ps1_m2133_get_device }, + { "[VIA VT82C495] FIC 486-VC-HD", "486vchd", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 1, 32, 1, 127, machine_at_486vchd_init, NULL }, /* 486 machines with utilize the MCA bus */ #if defined(DEV_BRANCH) && defined(USE_PS2M70T4) @@ -237,6 +238,10 @@ const machine_t machines[] = { { "[STPC Atlas] AAEON PCM-5330", "pcm5330", MACHINE_TYPE_486, {{"ST", cpus_STPC133}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 32, 128, 32, 255, machine_at_pcm5330_init, NULL }, #endif +#if defined(DEV_BRANCH) && defined(NO_SIO) + { "[VIA VT82C496G] FIC VIP-IO2", "486vipio2", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_PS2 | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 255, machine_at_486vipio2_init, NULL }, +#endif + /* Socket 4 machines */ /* OPTi 596/597 */ { "[OPTi 597] AMI Excalibur VLB", "excalibur", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 2, 64, 2, 127, machine_at_excalibur_init, NULL }, @@ -274,9 +279,9 @@ const machine_t machines[] = { { "[i430FX-3V] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, { "[i430FX-3V] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2katx_init, NULL }, { "[i430FX-3V] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, + { "[i430FX-3V] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, { "[i430FX-3V] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, - { "[i430FX-3V] MR 430FX clone", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, - { "[i430FX-3V] MR Intel Advanced/ATX", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, + { "[i430FX-3V] ASUS TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, { "[i430FX-3V] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, { "[i430FX-3V] QDI Chariot", "chariot", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73VCH, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_chariot_init, NULL }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 066cef3df..4c7f62087 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -616,7 +616,7 @@ CPUOBJ := cpu.o cpu_table.o \ CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.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 \ + 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) \ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \ amd640.o