diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c
new file mode 100644
index 000000000..d20eb4ba6
--- /dev/null
+++ b/src/chipset/vl82c480.c
@@ -0,0 +1,185 @@
+/*
+ * 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 VLSI VL82c480 chipset.
+ *
+ * Authors: Sarah Walker,
+ *
+ * Copyright 2020 Sarah Walker.
+ */
+#include
+#include
+#include
+#include
+#include
+#include <86box/86box.h>
+#include "cpu.h"
+#include <86box/timer.h>
+#include <86box/device.h>
+#include <86box/io.h>
+#include <86box/mem.h>
+#include <86box/nmi.h>
+#include <86box/port_92.h>
+#include <86box/chipset.h>
+
+typedef struct {
+ int cfg_index;
+ uint8_t cfg_regs[256];
+} vl82c480_t;
+
+#define CFG_ID 0x00
+#define CFG_AAXS 0x0d
+#define CFG_BAXS 0x0e
+#define CFG_CAXS 0x0f
+#define CFG_DAXS 0x10
+#define CFG_EAXS 0x11
+#define CFG_FAXS 0x12
+
+#define ID_VL82C480 0x90
+
+static void
+shadow_control(uint32_t addr, uint32_t size, int state)
+{
+/* pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); */
+ switch (state) {
+ case 0:
+ mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ break;
+ case 1:
+ mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
+ break;
+ case 2:
+ mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
+ break;
+ case 3:
+ mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ break;
+ }
+ flushmmucache_nopc();
+}
+
+static void
+vl82c480_write(uint16_t addr, uint8_t val, void *p)
+{
+ vl82c480_t *dev = (vl82c480_t *)p;
+
+ switch (addr) {
+ case 0xec:
+ dev->cfg_index = val;
+ break;
+
+ case 0xed:
+ if (dev->cfg_index >= 0x01 && dev->cfg_index <= 0x24) {
+ dev->cfg_regs[dev->cfg_index] = val;
+ switch (dev->cfg_index) {
+ case CFG_AAXS:
+ shadow_control(0xa0000, 0x4000, val & 3);
+ shadow_control(0xa4000, 0x4000, (val >> 2) & 3);
+ shadow_control(0xa8000, 0x4000, (val >> 4) & 3);
+ shadow_control(0xac000, 0x4000, (val >> 6) & 3);
+ break;
+ case CFG_BAXS:
+ shadow_control(0xb0000, 0x4000, val & 3);
+ shadow_control(0xb4000, 0x4000, (val >> 2) & 3);
+ shadow_control(0xb8000, 0x4000, (val >> 4) & 3);
+ shadow_control(0xbc000, 0x4000, (val >> 6) & 3);
+ break;
+ case CFG_CAXS:
+ shadow_control(0xc0000, 0x4000, val & 3);
+ shadow_control(0xc4000, 0x4000, (val >> 2) & 3);
+ shadow_control(0xc8000, 0x4000, (val >> 4) & 3);
+ shadow_control(0xcc000, 0x4000, (val >> 6) & 3);
+ break;
+ case CFG_DAXS:
+ shadow_control(0xd0000, 0x4000, val & 3);
+ shadow_control(0xd4000, 0x4000, (val >> 2) & 3);
+ shadow_control(0xd8000, 0x4000, (val >> 4) & 3);
+ shadow_control(0xdc000, 0x4000, (val >> 6) & 3);
+ break;
+ case CFG_EAXS:
+ shadow_control(0xe0000, 0x4000, val & 3);
+ shadow_control(0xe4000, 0x4000, (val >> 2) & 3);
+ shadow_control(0xe8000, 0x4000, (val >> 4) & 3);
+ shadow_control(0xec000, 0x4000, (val >> 6) & 3);
+ break;
+ case CFG_FAXS:
+ shadow_control(0xf0000, 0x4000, val & 3);
+ shadow_control(0xf4000, 0x4000, (val >> 2) & 3);
+ shadow_control(0xf8000, 0x4000, (val >> 4) & 3);
+ shadow_control(0xfc000, 0x4000, (val >> 6) & 3);
+ break;
+ }
+ }
+ break;
+
+ case 0xee:
+ if (mem_a20_alt)
+ outb(0x92, inb(0x92) & ~2);
+ break;
+ }
+}
+
+static uint8_t
+vl82c480_read(uint16_t addr, void *p)
+{
+ vl82c480_t *dev = (vl82c480_t *)p;
+ uint8_t ret = 0xff;
+
+ switch (addr) {
+ case 0xec:
+ ret = dev->cfg_index;
+ break;
+
+ case 0xed:
+ ret = dev->cfg_regs[dev->cfg_index];
+ break;
+
+ case 0xee:
+ if (!mem_a20_alt)
+ outb(0x92, inb(0x92) | 2);
+ break;
+
+ case 0xef:
+ softresetx86();
+ cpu_set_edx();
+ break;
+ }
+
+ return ret;
+}
+
+static void
+vl82c480_close(void *p)
+{
+ vl82c480_t *dev = (vl82c480_t *)p;
+
+ free(dev);
+}
+
+
+static void *
+vl82c480_init(const device_t *info)
+{
+ vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t));
+ memset(dev, 0, sizeof(vl82c480_t));
+
+ dev->cfg_regs[CFG_ID] = ID_VL82C480;
+
+ io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev);
+
+ return dev;
+}
+
+const device_t vl82c480_device = {
+ "VLSI VL82c480",
+ 0,
+ 0,
+ vl82c480_init, vl82c480_close, NULL,
+ NULL, NULL, NULL,
+ NULL
+};
diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h
index 210ec241d..276da03c8 100644
--- a/src/include/86box/chipset.h
+++ b/src/include/86box/chipset.h
@@ -94,6 +94,7 @@ extern const device_t via_vt82c596b_device;
extern const device_t amd640_device;
/* VLSI */
+extern const device_t vl82c480_device;
extern const device_t vlsi_scamp_device;
/* WD */
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index 62f5a2203..b0b4fa054 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -436,8 +436,10 @@ extern const device_t *pcjr_get_device(void);
/* m_ps1.c */
extern int machine_ps1_m2011_init(const machine_t *);
extern int machine_ps1_m2121_init(const machine_t *);
-#if defined(DEV_BRANCH) && defined(USE_PS1M2133)
extern int machine_ps1_m2133_init(const machine_t *);
+
+#ifdef EMU_DEVICE_H
+extern const device_t *ps1_m2133_get_device(void);
#endif
/* m_ps1_hdc.c */
diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h
index 9723a184a..c2bc5aeae 100644
--- a/src/include/86box/sio.h
+++ b/src/include/86box/sio.h
@@ -30,6 +30,7 @@ extern const device_t pc87307_device;
extern const device_t pc87309_device;
extern const device_t pc87332_device;
extern const device_t pc97307_device;
+extern const device_t ps1_m2133_sio;
extern const device_t sio_detect_device;
extern const device_t um8669f_device;
extern const device_t w83787f_device;
diff --git a/src/include/86box/video.h b/src/include/86box/video.h
index 018b877a3..69682e002 100644
--- a/src/include/86box/video.h
+++ b/src/include/86box/video.h
@@ -221,6 +221,7 @@ extern const device_t gd5422_isa_device;
extern const device_t gd5424_vlb_device;
#endif
extern const device_t gd5426_vlb_device;
+extern const device_t gd5426_onboard_device;
extern const device_t gd5428_isa_device;
extern const device_t gd5428_vlb_device;
extern const device_t gd5428_mca_device;
diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c
index 9295b5b7b..52ac3a523 100644
--- a/src/machine/m_ps1.c
+++ b/src/machine/m_ps1.c
@@ -48,6 +48,8 @@
#include <86box/nmi.h>
#include <86box/rom.h>
#include <86box/device.h>
+#include <86box/chipset.h>
+#include <86box/sio.h>
#include <86box/nvr.h>
#include <86box/gameport.h>
#include <86box/lpt.h>
@@ -490,14 +492,6 @@ ps1_setup(int model)
device_add(&snd_device);
}
-#if defined(DEV_BRANCH) && defined(USE_PS1M2133)
- if (model == 2133) {
- device_add(&fdc_at_device);
-
- device_add(&ide_isa_device);
- }
-#endif
-
/* Enable the PS/1 VGA controller. */
if (model == 2011)
device_add(&ps1vga_device);
@@ -505,7 +499,6 @@ ps1_setup(int model)
device_add(&ibm_ps1_2121_device);
}
-
static void
ps1_common_init(const machine_t *model)
{
@@ -565,8 +558,6 @@ machine_ps1_m2121_init(const machine_t *model)
return ret;
}
-
-#if defined(DEV_BRANCH) && defined(USE_PS1M2133)
int
machine_ps1_m2133_init(const machine_t *model)
{
@@ -579,11 +570,21 @@ machine_ps1_m2133_init(const machine_t *model)
return ret;
ps1_common_init(model);
-
- ps1_setup(2133);
+ device_add(&fdc_at_device);
+ device_add(&ide_isa_device);
+ device_add(&vl82c480_device);
nmi_mask = 0x80;
+ if (gfxcard == VID_INTERNAL)
+ device_add(&gd5426_onboard_device);
+
return ret;
}
-#endif
+
+const device_t *
+ps1_m2133_get_device(void)
+{
+ return &gd5426_onboard_device;
+}
+
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index ee160fd48..063612dad 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -210,9 +210,7 @@ const machine_t machines[] = {
{ "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO | MACHINE_PS2, 4, 36, 1, 127, machine_at_acera1g_init, at_acera1g_get_device },
{ "[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 },
-#if defined(DEV_BRANCH) && defined(USE_PS1M2133)
- { "[VLB] 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, 1, 64, 1, 127, machine_ps1_m2133_init, NULL },
-#endif
+ { "[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, 1, 64, 1, 127, machine_ps1_m2133_init, ps1_m2133_get_device },
/* 486 machines with utilize the MCA bus */
#if defined(DEV_BRANCH) && defined(USE_PS2M70T4)
diff --git a/src/sio/sio_ps1_m2133.c b/src/sio/sio_ps1_m2133.c
new file mode 100644
index 000000000..264dd78c7
--- /dev/null
+++ b/src/sio/sio_ps1_m2133.c
@@ -0,0 +1,148 @@
+/*
+ * 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 chipset used by the IBM PS/1 Model 2133 EMEA 451
+ * whose name is currently unknown.
+ *
+ * Authors: Sarah Walker,
+ *
+ * Copyright 2020 Sarah Walker.
+ */
+#include
+#include
+#include
+#include
+#include
+#include <86box/86box.h>
+#include <86box/io.h>
+#include <86box/timer.h>
+#include <86box/device.h>
+#include <86box/lpt.h>
+#include <86box/serial.h>
+#include <86box/sio.h>
+
+
+typedef struct ps1_m2133_sio_t
+{
+ int idx;
+ uint8_t regs[3];
+ serial_t *uart[2];
+} ps1_m2133_sio_t;
+
+static uint16_t ps1_lpt_io[4] = {0x378, 0x3bc, 0x278, 0x378};
+static uint16_t ps1_com_io[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
+
+static uint8_t
+ps1_m2133_read(uint16_t port, void *p)
+{
+ ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *)p;
+ uint8_t ret = 0xff;
+
+ switch (port) {
+ case 0x398:
+ ret = dev->idx;
+ break;
+
+ case 0x399:
+ if (dev->idx < 3)
+ ret = dev->regs[dev->idx];
+ break;
+ }
+ return ret;
+}
+
+static void
+ps1_m2133_write(uint16_t port, uint8_t val, void *p)
+{
+ ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *)p;
+ uint16_t lpt_addr;
+
+ switch (port) {
+ case 0x398:
+ dev->idx = val;
+ break;
+
+ case 0x399:
+ if (dev->idx < 3) {
+ dev->regs[dev->idx] = val;
+
+ lpt1_remove();
+ lpt2_remove();
+ serial_remove(dev->uart[0]);
+ serial_remove(dev->uart[1]);
+
+ if (dev->regs[0] & 1) {
+ lpt_addr = ps1_lpt_io[dev->regs[1] & 3];
+
+ lpt1_init(lpt_addr);
+ if ((lpt_addr == 0x378) || (lpt_addr == 0x3bc)) {
+ if (((dev->regs[1] & 3) == 3) && (lpt_addr == 0x378)) {
+ lpt1_irq(5);
+ } else {
+ lpt1_irq(7);
+ }
+ } else if (lpt_addr == 0x278) {
+ lpt1_irq(5);
+ }
+ }
+
+ if (dev->regs[0] & 2)
+ serial_setup(dev->uart[0], ps1_com_io[(dev->regs[1] >> 2) & 3], 4);
+ if (dev->regs[0] & 4)
+ serial_setup(dev->uart[1], ps1_com_io[(dev->regs[1] >> 4) & 3], 3);
+ }
+ break;
+ }
+}
+
+static void
+ps1_m2133_reset(ps1_m2133_sio_t *dev)
+{
+ serial_remove(dev->uart[0]);
+ serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
+
+ serial_remove(dev->uart[1]);
+ serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ);
+
+ lpt1_remove();
+ lpt1_init(0x378);
+ lpt1_irq(7);
+}
+
+static void *
+ps1_m2133_init(const device_t *info)
+{
+ ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *) malloc(sizeof(ps1_m2133_sio_t));
+ memset(dev, 0, sizeof(ps1_m2133_sio_t));
+
+ dev->uart[0] = device_add_inst(&ns16450_device, 1);
+ dev->uart[1] = device_add_inst(&ns16450_device, 2);
+
+ io_sethandler(0x0398, 0x0002, ps1_m2133_read, NULL, NULL, ps1_m2133_write, NULL, NULL, dev);
+
+ ps1_m2133_reset(dev);
+
+ return dev;
+}
+
+static void
+ps1_m2133_close(void *p)
+{
+ ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *)p;
+
+ free(dev);
+}
+
+const device_t ps1_m2133_sio = {
+ "IBM PS/1 Model 2133 EMEA 451 Super I/O",
+ 0,
+ 0,
+ ps1_m2133_init, ps1_m2133_close, NULL,
+ NULL, NULL, NULL,
+ NULL
+};
diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c
index 09acdc3e0..c169253b0 100644
--- a/src/video/vid_cl54xx.c
+++ b/src/video/vid_cl54xx.c
@@ -3023,7 +3023,10 @@ static void
#endif
case CIRRUS_ID_CLGD5426:
- romfn = BIOS_GD5426_PATH;
+ if (info->local & 0x200) {
+ romfn = NULL;
+ } else
+ romfn = BIOS_GD5426_PATH;
break;
case CIRRUS_ID_CLGD5428:
@@ -3542,6 +3545,20 @@ const device_t gd5426_vlb_device =
gd5428_config
};
+const device_t gd5426_onboard_device =
+{
+ "Cirrus Logic CL-GD 5426 (On-board)",
+ DEVICE_VLB,
+ CIRRUS_ID_CLGD5426 | 0x200,
+ gd54xx_init,
+ gd54xx_close,
+ NULL,
+ NULL,
+ gd54xx_speed_changed,
+ gd54xx_force_redraw,
+ gd5428_config
+};
+
const device_t gd5428_isa_device =
{
"Cirrus Logic CL-GD 5428 (ISA)",
@@ -3586,7 +3603,7 @@ const device_t gd5428_mca_device =
const device_t gd5428_a1g_device =
{
- "Cirrus Logic CL-GD 5428 (Onboard)",
+ "Cirrus Logic CL-GD 5428 (On-Board)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5428,
gd54xx_init,
diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw
index bd90c39fe..2334fa603 100644
--- a/src/win/Makefile.mingw
+++ b/src/win/Makefile.mingw
@@ -563,7 +563,7 @@ CHIPSETOBJ := acc2168.o acer_m3a.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 opti5x7.o scamp.o scat.o \
sis_85c310.o sis_85c471.o sis_85c496.o \
- via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o \
+ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \
amd640.o
MCHOBJ := machine.o machine_table.o \
@@ -595,6 +595,7 @@ SIOOBJ := sio_acc3221.o \
sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o \
sio_fdc37c93x.o \
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \
+ sio_ps1_m2133.o \
sio_w83787f.o \
sio_w83877f.o sio_w83977f.o \
sio_um8669f.o