diff --git a/src/chipset/chipset.h b/src/chipset/chipset.h
index f61cdcd3e..b78f177c5 100644
--- a/src/chipset/chipset.h
+++ b/src/chipset/chipset.h
@@ -64,6 +64,9 @@ extern const device_t sis_85c50x_device;
/* VIA */
extern const device_t via_mvp3_device;
+/* VLSI */
+extern const device_t vlsi_scamp_device;
+
/* WD */
extern const device_t wd76c10_device;
diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c
new file mode 100644
index 000000000..093b3863a
--- /dev/null
+++ b/src/chipset/scamp.c
@@ -0,0 +1,756 @@
+/*
+ * 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.
+ *
+ * Emulation of VLSI 82C311 ("SCAMP") chipset.
+ *
+ * Note: The datasheet mentions that the chipset supports up to 8MB
+ * of DRAM. This is intepreted as 'being able to refresh up to
+ * 8MB of DRAM chips', because it works fine with bus-based
+ * memory expansion.
+ *
+ * Version: @(#)scamp.c 1.0.0 2020/01/21
+ *
+ * Authors: Sarah Walker,
+ *
+ * Copyright 2020 Sarah Walker.
+ */
+#include
+#include
+#include
+#include
+#include
+#include "../86box.h"
+#include "../cpu/cpu.h"
+#include "../timer.h"
+#include "../device.h"
+#include "../io.h"
+#include "../mem.h"
+#include "../nmi.h"
+#include "../port_92.h"
+#include "chipset.h"
+
+typedef struct {
+ int cfg_index;
+ uint8_t cfg_regs[256];
+ int cfg_enable;
+
+ int ram_config;
+
+ mem_mapping_t ram_mapping[2];
+ uint32_t ram_virt_base[2], ram_phys_base[2];
+ uint32_t ram_mask[2];
+ int row_virt_shift[2], row_phys_shift[2];
+ int ram_interleaved[2];
+ int ibank_shift[2];
+} scamp_t;
+
+#define CFG_ID 0x00
+#define CFG_SLTPTR 0x02
+#define CFG_RAMMAP 0x03
+#define CFG_EMSEN1 0x0b
+#define CFG_EMSEN2 0x0c
+#define CFG_ABAXS 0x0e
+#define CFG_CAXS 0x0f
+#define CFG_DAXS 0x10
+#define CFG_FEAXS 0x11
+
+#define ID_VL82C311 0xd6
+
+#define RAMMAP_REMP386 (1 << 4)
+
+/*Commodore SL386SX requires proper memory slot decoding to detect memory size.
+ Therefore we emulate the SCAMP memory address decoding, and therefore are
+ limited to the DRAM combinations supported by the actual chip*/
+enum
+{
+ BANK_NONE,
+ BANK_256K,
+ BANK_256K_INTERLEAVED,
+ BANK_1M,
+ BANK_1M_INTERLEAVED,
+ BANK_4M,
+ BANK_4M_INTERLEAVED
+};
+
+static const struct
+{
+ int size_kb;
+ int rammap;
+ int bank[2];
+} ram_configs[] =
+{
+ {512, 0x0, {BANK_256K, BANK_NONE}},
+ {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}},
+ {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}},
+ {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}},
+ {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}},
+ {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}},
+ {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}},
+ {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}},
+ {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}},
+ {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}},
+ {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}},
+};
+
+static const struct
+{
+ int bank[2];
+ int remapped;
+} rammap[16] =
+{
+ {{BANK_256K, BANK_NONE}, 0},
+ {{BANK_256K_INTERLEAVED, BANK_NONE}, 0},
+ {{BANK_256K_INTERLEAVED, BANK_256K}, 0},
+ {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0},
+
+ {{BANK_1M, BANK_NONE}, 0},
+ {{BANK_1M_INTERLEAVED, BANK_NONE}, 0},
+ {{BANK_1M_INTERLEAVED, BANK_1M}, 0},
+ {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0},
+
+ {{BANK_4M, BANK_NONE}, 0},
+ {{BANK_4M_INTERLEAVED, BANK_NONE}, 0},
+ {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/
+ {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/
+
+ {{BANK_256K_INTERLEAVED, BANK_1M}, 0},
+ {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0},
+ {{BANK_1M_INTERLEAVED, BANK_4M}, 0},
+ {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/
+};
+
+/*The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous,
+ so we use separate routines for that special case*/
+static uint8_t
+ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int bank = (int)priv;
+ int row, column, byte;
+
+ addr -= dev->ram_virt_base[bank];
+ byte = addr & 1;
+ if (!dev->ram_interleaved[bank]) {
+ if (addr & 0x400)
+ return 0xff;
+
+ addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1);
+ column = (addr >> 1) & dev->ram_mask[bank];
+ row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9);
+
+ addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]);
+ } else {
+ column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1);
+ row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9);
+
+ addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1));
+ }
+
+ return ram[addr + dev->ram_phys_base[bank]];
+}
+static void
+ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int bank = (int)priv;
+ int row, column, byte;
+
+ addr -= dev->ram_virt_base[bank];
+ byte = addr & 1;
+ if (!dev->ram_interleaved[bank]) {
+ if (addr & 0x400)
+ return;
+
+ addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1);
+ column = (addr >> 1) & dev->ram_mask[bank];
+ row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9);
+
+ addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]);
+ } else {
+ column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1);
+ row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9);
+
+ addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1));
+ }
+
+ ram[addr + dev->ram_phys_base[bank]] = val;
+}
+
+/*Read/write handlers for interleaved memory banks. We must keep CPU and ram array
+ mapping linear, otherwise we won't be able to execute code from interleaved banks*/
+static uint8_t
+ram_mirrored_interleaved_read(uint32_t addr, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int bank = (int)priv;
+ int row, column, byte;
+
+ addr -= dev->ram_virt_base[bank];
+ byte = addr & 1;
+ if (!dev->ram_interleaved[bank]) {
+ if (addr & 0x400)
+ return 0xff;
+
+ addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1);
+ column = (addr >> 1) & dev->ram_mask[bank];
+ row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank];
+
+ addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]);
+ } else {
+ column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1);
+ row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank];
+
+ addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1));
+ }
+
+ return ram[addr + dev->ram_phys_base[bank]];
+}
+static void
+ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int bank = (int)priv;
+ int row, column, byte;
+
+ addr -= dev->ram_virt_base[bank];
+ byte = addr & 1;
+ if (!dev->ram_interleaved[bank]) {
+ if (addr & 0x400)
+ return;
+
+ addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1);
+ column = (addr >> 1) & dev->ram_mask[bank];
+ row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank];
+
+ addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]);
+ }
+ else {
+ column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1);
+ row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank];
+
+ addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1));
+ }
+
+ ram[addr + dev->ram_phys_base[bank]] = val;
+}
+
+static uint8_t
+ram_mirrored_read(uint32_t addr, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int bank = (int)priv;
+ int row, column, byte;
+
+ addr -= dev->ram_virt_base[bank];
+ byte = addr & 1;
+ column = (addr >> 1) & dev->ram_mask[bank];
+ row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank];
+ addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]);
+
+ return ram[addr + dev->ram_phys_base[bank]];
+}
+static void
+ram_mirrored_write(uint32_t addr, uint8_t val, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int bank = (int)priv;
+ int row, column, byte;
+
+ addr -= dev->ram_virt_base[bank];
+ byte = addr & 1;
+ column = (addr >> 1) & dev->ram_mask[bank];
+ row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank];
+ addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]);
+
+ ram[addr + dev->ram_phys_base[bank]] = val;
+}
+
+static void
+recalc_mappings(void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+ int c;
+ uint32_t virt_base = 0;
+ uint8_t cur_rammap = dev->cfg_regs[CFG_RAMMAP] & 0xf;
+ int bank_nr = 0;
+
+ for (c = 0; c < 2; c++)
+ mem_mapping_disable(&dev->ram_mapping[c]);
+
+ /*Once the BIOS programs the correct DRAM configuration, switch to regular
+ linear memory mapping*/
+ if (cur_rammap == ram_configs[dev->ram_config].rammap) {
+ mem_mapping_set_handler(&ram_low_mapping,
+ mem_read_ram, mem_read_ramw, mem_read_raml,
+ mem_write_ram, mem_write_ramw, mem_write_raml);
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
+ mem_mapping_enable(&ram_high_mapping);
+ return;
+ } else {
+ mem_mapping_set_handler(&ram_low_mapping,
+ ram_mirrored_read, NULL, NULL,
+ ram_mirrored_write, NULL, NULL);
+ mem_mapping_disable(&ram_low_mapping);
+ }
+
+ if (rammap[cur_rammap].bank[0] == BANK_NONE)
+ bank_nr = 1;
+
+/* pclog("Bank remap, cur_rammap=%x\n", cur_rammap); */
+
+ for (; bank_nr < 2; bank_nr++) {
+ uint32_t old_virt_base = virt_base;
+ int phys_bank = ram_configs[dev->ram_config].bank[bank_nr];
+
+/* pclog(" Bank %i: phys_bank=%i rammap_bank=%i virt_base=%08x phys_base=%08x\n", bank_nr, phys_bank, rammap[cur_rammap].bank[bank_nr], virt_base, dev->ram_phys_base[bank_nr]); */
+ dev->ram_virt_base[bank_nr] = virt_base;
+
+ if (virt_base == 0) {
+ switch (rammap[cur_rammap].bank[bank_nr]) {
+ case BANK_NONE:
+ fatal("Bank 0 is empty!\n");
+ break;
+
+ case BANK_256K:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000);
+ mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
+ }
+ virt_base += 512*1024;
+ dev->row_virt_shift[bank_nr] = 10;
+ break;
+
+ case BANK_256K_INTERLEAVED:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
+ mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
+ }
+ virt_base += 512*1024*2;
+ dev->row_virt_shift[bank_nr] = 10;
+ break;
+
+ case BANK_1M:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
+ mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
+ }
+ virt_base += 2048*1024;
+ dev->row_virt_shift[bank_nr] = 11;
+ break;
+
+ case BANK_1M_INTERLEAVED:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
+ mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
+ }
+ virt_base += 2048*1024*2;
+ dev->row_virt_shift[bank_nr] = 11;
+ break;
+
+ case BANK_4M:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
+ mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
+ }
+ virt_base += 8192*1024;
+ dev->row_virt_shift[bank_nr] = 12;
+ break;
+
+ case BANK_4M_INTERLEAVED:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
+ mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
+ }
+ virt_base += 8192*1024*2;
+ dev->row_virt_shift[bank_nr] = 12;
+ break;
+ }
+ } else {
+ switch (rammap[cur_rammap].bank[bank_nr]) {
+ case BANK_NONE:
+ break;
+
+ case BANK_256K:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x80000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]);
+ }
+ virt_base += 512*1024;
+ dev->row_virt_shift[bank_nr] = 10;
+ break;
+
+ case BANK_256K_INTERLEAVED:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]);
+ }
+ virt_base += 512*1024*2;
+ dev->row_virt_shift[bank_nr] = 10;
+ break;
+
+ case BANK_1M:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]);
+ }
+ virt_base += 2048*1024;
+ dev->row_virt_shift[bank_nr] = 11;
+ break;
+
+ case BANK_1M_INTERLEAVED:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]);
+ }
+ virt_base += 2048*1024*2;
+ dev->row_virt_shift[bank_nr] = 11;
+ break;
+
+ case BANK_4M:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]);
+ }
+ virt_base += 8192*1024;
+ dev->row_virt_shift[bank_nr] = 12;
+ break;
+
+ case BANK_4M_INTERLEAVED:
+ if (phys_bank != BANK_NONE) {
+ mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000);
+ mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]);
+ }
+ virt_base += 8192*1024*2;
+ dev->row_virt_shift[bank_nr] = 12;
+ break;
+ }
+ }
+ switch (rammap[cur_rammap].bank[bank_nr]) {
+ case BANK_256K: case BANK_1M: case BANK_4M:
+ mem_mapping_set_handler(&dev->ram_mapping[bank_nr],
+ ram_mirrored_read, NULL, NULL,
+ ram_mirrored_write, NULL, NULL);
+ if (!old_virt_base)
+ mem_mapping_set_handler(&ram_low_mapping,
+ ram_mirrored_read, NULL, NULL,
+ ram_mirrored_write, NULL, NULL);
+ /*pclog(" not interleaved\n");*/
+ break;
+
+ case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED:
+ mem_mapping_set_handler(&dev->ram_mapping[bank_nr],
+ ram_mirrored_interleaved_read, NULL, NULL,
+ ram_mirrored_interleaved_write, NULL, NULL);
+ if (!old_virt_base)
+ mem_mapping_set_handler(&ram_low_mapping,
+ ram_mirrored_interleaved_read, NULL, NULL,
+ ram_mirrored_interleaved_write, NULL, NULL);
+ /*pclog(" interleaved\n");*/
+ break;
+
+ case BANK_4M_INTERLEAVED:
+ if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) {
+ mem_mapping_set_handler(&dev->ram_mapping[bank_nr],
+ ram_mirrored_256k_in_4mi_read, NULL, NULL,
+ ram_mirrored_256k_in_4mi_write, NULL, NULL);
+ if (!old_virt_base)
+ mem_mapping_set_handler(&ram_low_mapping,
+ ram_mirrored_256k_in_4mi_read, NULL, NULL,
+ ram_mirrored_256k_in_4mi_write, NULL, NULL);
+ /*pclog(" 256k in 4mi\n");*/
+ } else {
+ mem_mapping_set_handler(&dev->ram_mapping[bank_nr],
+ ram_mirrored_interleaved_read, NULL, NULL,
+ ram_mirrored_interleaved_write, NULL, NULL);
+ if (!old_virt_base)
+ mem_mapping_set_handler(&ram_low_mapping,
+ ram_mirrored_interleaved_read, NULL, NULL,
+ ram_mirrored_interleaved_write, NULL, NULL);
+ /*pclog(" interleaved\n");*/
+ }
+ break;
+ }
+ }
+}
+
+#define NR_ELEMS(x) (sizeof(x) / sizeof(x[0]))
+
+
+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
+scamp_write(uint16_t addr, uint8_t val, void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+
+/* pclog("scamp_write: addr=%04x val=%02x\n", addr, val); */
+ switch (addr) {
+ case 0xec:
+ if (dev->cfg_enable)
+ dev->cfg_index = val;
+ break;
+
+ case 0xed:
+ if (dev->cfg_enable) {
+ if (dev->cfg_index >= 0x02 && dev->cfg_index <= 0x16) {
+ dev->cfg_regs[dev->cfg_index] = val;
+/* pclog("SCAMP CFG[%02x]=%02x\n", dev->cfg_index, val); */
+ switch (dev->cfg_index) {
+ case CFG_SLTPTR:
+ break;
+
+ case CFG_RAMMAP:
+ recalc_mappings(dev);
+ mem_mapping_disable(&ram_remapped_mapping);
+ if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) {
+ /*Enabling remapping will disable all shadowing*/
+ mem_remap_top(384);
+ shadow_control(0xa0000, 0x60000, 0);
+ } else {
+ shadow_control(0xa0000, 0x8000, dev->cfg_regs[CFG_ABAXS] & 3);
+ shadow_control(0xa8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 2) & 3);
+ shadow_control(0xb0000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 4) & 3);
+ shadow_control(0xb8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 6) & 3);
+
+ shadow_control(0xc0000, 0x4000, dev->cfg_regs[CFG_CAXS] & 3);
+ shadow_control(0xc4000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 2) & 3);
+ shadow_control(0xc8000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 4) & 3);
+ shadow_control(0xcc000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 6) & 3);
+
+ shadow_control(0xd0000, 0x4000, dev->cfg_regs[CFG_DAXS] & 3);
+ shadow_control(0xd4000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 2) & 3);
+ shadow_control(0xd8000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 4) & 3);
+ shadow_control(0xdc000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 6) & 3);
+
+ shadow_control(0xe0000, 0x8000, dev->cfg_regs[CFG_FEAXS] & 3);
+ shadow_control(0xe8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 2) & 3);
+ shadow_control(0xf0000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 4) & 3);
+ shadow_control(0xf8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 6) & 3);
+ }
+ break;
+
+ case CFG_ABAXS:
+ if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) {
+ shadow_control(0xa0000, 0x8000, val & 3);
+ shadow_control(0xa8000, 0x8000, (val >> 2) & 3);
+ shadow_control(0xb0000, 0x8000, (val >> 4) & 3);
+ shadow_control(0xb8000, 0x8000, (val >> 6) & 3);
+ }
+ break;
+
+ case CFG_CAXS:
+ if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) {
+ 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:
+ if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) {
+ 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_FEAXS:
+ if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) {
+ shadow_control(0xe0000, 0x8000, val & 3);
+ shadow_control(0xe8000, 0x8000, (val >> 2) & 3);
+ shadow_control(0xf0000, 0x8000, (val >> 4) & 3);
+ shadow_control(0xf8000, 0x8000, (val >> 6) & 3);
+ }
+ break;
+ }
+ }
+ }
+ break;
+
+ case 0xee:
+ if (dev->cfg_enable && mem_a20_alt)
+ outb(0x92, inb(0x92) & ~2);
+ break;
+ }
+}
+
+
+static uint8_t
+scamp_read(uint16_t addr, void *priv)
+{
+ uint8_t ret = 0xff;
+
+ switch (addr) {
+ case 0xee:
+ if (!mem_a20_alt)
+ outb(0x92, inb(0x92) | 2);
+ break;
+
+ case 0xef:
+ softresetx86();
+ cpu_set_edx();
+ break;
+ }
+
+/* pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret); */
+ return ret;
+}
+
+static void
+scamp_close(void *priv)
+{
+ scamp_t *dev = (scamp_t *) priv;
+
+ free(dev);
+}
+
+
+static void *
+scamp_init(const device_t *info)
+{
+ uint32_t addr;
+ int c;
+ scamp_t *dev = (scamp_t *)malloc(sizeof(scamp_t));
+ memset(dev, 0, sizeof(scamp_t));
+
+ dev->cfg_regs[CFG_ID] = ID_VL82C311;
+ dev->cfg_enable = 1;
+
+ io_sethandler(0x00e8, 0x0001,
+ scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev);
+ io_sethandler(0x00ea, 0x0006,
+ scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev);
+ io_sethandler(0x00f4, 0x0002,
+ scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev);
+ io_sethandler(0x00f9, 0x0001,
+ scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev);
+ io_sethandler(0x00fb, 0x0001,
+ scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev);
+
+ dev->ram_config = 0;
+
+ /*Find best fit configuration for the requested memory size*/
+ for (c = 0; c < NR_ELEMS(ram_configs); c++) {
+ if (mem_size < ram_configs[c].size_kb)
+ break;
+
+ dev->ram_config = c;
+ }
+
+ mem_mapping_set_handler(&ram_low_mapping,
+ ram_mirrored_read, NULL, NULL,
+ ram_mirrored_write, NULL, NULL);
+ mem_mapping_disable(&ram_high_mapping);
+
+ addr = 0;
+ for (c = 0; c < 2; c++) {
+ mem_mapping_add(&dev->ram_mapping[c], 0, 0,
+ ram_mirrored_read, NULL, NULL,
+ ram_mirrored_write, NULL, NULL,
+ &ram[addr], MEM_MAPPING_INTERNAL, (void *)c);
+ mem_mapping_disable(&dev->ram_mapping[c]);
+
+ dev->ram_phys_base[c] = addr;
+/* pclog("Bank calc : %i = %08x\n", c ,addr);*/
+
+ switch (ram_configs[dev->ram_config].bank[c]) {
+ case BANK_NONE:
+ dev->ram_mask[c] = 0;
+ dev->ram_interleaved[c] = 0;
+ break;
+
+ case BANK_256K:
+ addr += 512*1024;
+ dev->ram_mask[c] = 0x1ff;
+ dev->row_phys_shift[c] = 10;
+ dev->ram_interleaved[c] = 0;
+ break;
+
+ case BANK_256K_INTERLEAVED:
+ addr += 512*1024*2;
+ dev->ram_mask[c] = 0x1ff;
+ dev->row_phys_shift[c] = 10;
+ dev->ibank_shift[c] = 19;
+ dev->ram_interleaved[c] = 1;
+ break;
+
+ case BANK_1M:
+ addr += 2048*1024;
+ dev->ram_mask[c] = 0x3ff;
+ dev->row_phys_shift[c] = 11;
+ dev->ram_interleaved[c] = 0;
+ break;
+
+ case BANK_1M_INTERLEAVED:
+ addr += 2048*1024*2;
+ dev->ram_mask[c] = 0x3ff;
+ dev->row_phys_shift[c] = 11;
+ dev->ibank_shift[c] = 21;
+ dev->ram_interleaved[c] = 1;
+ break;
+
+ case BANK_4M:
+ addr += 8192*1024;
+ dev->ram_mask[c] = 0x7ff;
+ dev->row_phys_shift[c] = 12;
+ dev->ram_interleaved[c] = 0;
+ break;
+
+ case BANK_4M_INTERLEAVED:
+ addr += 8192*1024*2;
+ dev->ram_mask[c] = 0x7ff;
+ dev->row_phys_shift[c] = 12;
+ dev->ibank_shift[c] = 23;
+ dev->ram_interleaved[c] = 1;
+ break;
+ }
+ }
+
+ mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+
+ return dev;
+}
+
+
+const device_t vlsi_scamp_device = {
+ "VLSI SCAMP",
+ 0,
+ 0,
+ scamp_init, scamp_close, NULL,
+ NULL, NULL, NULL,
+ NULL
+};
\ No newline at end of file
diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c
index 52193d402..d977d37b3 100644
--- a/src/machine/m_at_286_386sx.c
+++ b/src/machine/m_at_286_386sx.c
@@ -8,7 +8,7 @@
*
* Implementation of 286 and 386SX machines.
*
- * Version: @(#)m_at_286_386sx.c 1.0.2 2019/11/19
+ * Version: @(#)m_at_286_386sx.c 1.0.3 2020/01/22
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -35,6 +35,7 @@
#include "../floppy/fdc.h"
#include "../disk/hdc.h"
#include "../video/video.h"
+#include "../video/vid_cl54xx.h"
#include "../video/vid_et4000.h"
#include "../video/vid_oak_oti.h"
#include "../video/vid_paradise.h"
@@ -409,3 +410,33 @@ machine_at_wd76c10_init(const machine_t *model)
return ret;
}
+
+const device_t *
+at_commodore_sl386sx_get_device(void)
+{
+ return &gd5402_onboard_device;
+}
+
+int
+machine_at_commodore_sl386sx_init(const machine_t *model)
+{
+ int ret;
+
+ ret = bios_load_interleaved(L"roms/machines/cbm_sl386sx25/cbm-sl386sx-bios-lo-v1.04-390914-04.bin",
+ L"roms/machines/cbm_sl386sx25/cbm-sl386sx-bios-hi-v1.04-390915-04.bin",
+ 0x000f0000, 65536, 0);
+
+ if (bios_only || !ret)
+ return ret;
+
+ machine_at_common_ide_init(model);
+
+ device_add(&keyboard_at_device);
+ device_add(&fdc_at_device);
+ device_add(&vlsi_scamp_device);
+
+ if (gfxcard == VID_INTERNAL)
+ device_add(&gd5402_onboard_device);
+
+ return ret;
+}
diff --git a/src/machine/machine.h b/src/machine/machine.h
index 53353f7cc..72f6f199e 100644
--- a/src/machine/machine.h
+++ b/src/machine/machine.h
@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
- * Version: @(#)machine.h 1.0.36 2020/01/20
+ * Version: @(#)machine.h 1.0.37 2020/01/22
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -201,10 +201,12 @@ extern int machine_at_spc4216p_init(const machine_t *);
extern int machine_at_kmxc02_init(const machine_t *);
extern int machine_at_deskmaster286_init(const machine_t *);
+extern int machine_at_commodore_sl386sx_init(const machine_t *);
extern int machine_at_wd76c10_init(const machine_t *);
#ifdef EMU_DEVICE_H
-extern const device_t *at_ama932j_get_device(void);
+extern const device_t *at_ama932j_get_device(void);
+extern const device_t *at_commodore_sl386sx_get_device(void);
#endif
/* m_at_386dx_486.c */
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index e0dd2570b..2af281f54 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -11,7 +11,7 @@
* NOTES: OpenAT wip for 286-class machine with open BIOS.
* PS2_M80-486 wip, pending receipt of TRM's for machine.
*
- * Version: @(#)machine_table.c 1.0.53 2020/01/20
+ * Version: @(#)machine_table.c 1.0.54 2020/01/22
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -127,6 +127,7 @@ const machine_t machines[] = {
{ "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL },
#endif
{ "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL },
+ { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device },
{ "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL },
{ "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
diff --git a/src/machine/machine_table_new.c b/src/machine/machine_table_new.c
index 30223d562..8787c911c 100644
--- a/src/machine/machine_table_new.c
+++ b/src/machine/machine_table_new.c
@@ -11,7 +11,7 @@
* NOTES: OpenAT wip for 286-class machine with open BIOS.
* PS2_M80-486 wip, pending receipt of TRM's for machine.
*
- * Version: @(#)machine_table.c 1.0.53 2020/01/20
+ * Version: @(#)machine_table.c 1.0.54 2020/01/22
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -112,6 +112,7 @@ const machine_t machines[] = {
{ "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL },
#endif
{ "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL },
+ { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device },
{ "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL },
{ "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c
index 1ba5b7a38..65e2d66f0 100644
--- a/src/video/vid_cl54xx.c
+++ b/src/video/vid_cl54xx.c
@@ -9,7 +9,7 @@
* Emulation of select Cirrus Logic cards (CL-GD 5428,
* CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported).
*
- * Version: @(#)vid_cl_54xx.c 1.0.32 2020/01/11
+ * Version: @(#)vid_cl_54xx.c 1.0.32 2020/01/22
*
* Authors: TheCollector1995,
* Miran Grca,
@@ -36,10 +36,13 @@
#include "vid_svga_render.h"
#include "vid_cl54xx.h"
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
+#define BIOS_GD5402_PATH L"roms/video/cirruslogic/avga2.rom"
#define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi"
+
+#if defined(DEV_BRANCH) && defined(USE_CL5422)
#define BIOS_GD5422_PATH L"roms/video/cirruslogic/cl5422.bin"
#endif
+
#define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin"
#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin"
#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN"
@@ -2906,21 +2909,25 @@ static void
gd54xx->has_bios = 1;
switch (id) {
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
case CIRRUS_ID_CLGD5402:
+ romfn = BIOS_GD5402_PATH;
+ break;
+
case CIRRUS_ID_CLGD5420:
romfn = BIOS_GD5420_PATH;
break;
+
+#if defined(DEV_BRANCH) && defined(USE_CL5422)
case CIRRUS_ID_CLGD5422:
case CIRRUS_ID_CLGD5424:
romfn = BIOS_GD5422_PATH;
break;
#endif
-
+
case CIRRUS_ID_CLGD5426:
romfn = BIOS_GD5426_PATH;
break;
-
+
case CIRRUS_ID_CLGD5428:
if (gd54xx->vlb)
romfn = BIOS_GD5428_PATH;
@@ -3021,7 +3028,6 @@ static void
svga->hwcursor.yoff = 32;
svga->hwcursor.xoff = 0;
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
if (id >= CIRRUS_ID_CLGD5420) {
gd54xx->vclk_n[0] = 0x4a;
gd54xx->vclk_d[0] = 0x2b;
@@ -3041,16 +3047,6 @@ static void
gd54xx->vclk_n[3] = 0x7e;
gd54xx->vclk_d[3] = 0x33;
}
-#else
- gd54xx->vclk_n[0] = 0x4a;
- gd54xx->vclk_d[0] = 0x2b;
- gd54xx->vclk_n[1] = 0x5b;
- gd54xx->vclk_d[1] = 0x2f;
- gd54xx->vclk_n[2] = 0x45;
- gd54xx->vclk_d[2] = 0x30;
- gd54xx->vclk_n[3] = 0x7e;
- gd54xx->vclk_d[3] = 0x33;
-#endif
svga->extra_banks[1] = 0x8000;
@@ -3072,13 +3068,19 @@ static void
return gd54xx;
}
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
+static int
+gd5402_available(void)
+{
+ return rom_present(BIOS_GD5402_PATH);
+}
+
static int
gd5420_available(void)
{
return rom_present(BIOS_GD5420_PATH);
}
+#if defined(DEV_BRANCH) && defined(USE_CL5422)
static int
gd5422_available(void)
{
@@ -3186,7 +3188,6 @@ gd54xx_force_redraw(void *p)
gd54xx->svga.fullchange = changeframecount;
}
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
static const device_config_t gd5422_config[] =
{
{
@@ -3207,7 +3208,6 @@ static const device_config_t gd5422_config[] =
"","",-1
}
};
-#endif
static const device_config_t gd5428_config[] =
{
@@ -3290,7 +3290,6 @@ static const device_config_t gd5434_config[] =
}
};
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
const device_t gd5402_isa_device =
{
"Cirrus Logic GD-5402 (ACUMOS AVGA2)",
@@ -3298,7 +3297,20 @@ const device_t gd5402_isa_device =
CIRRUS_ID_CLGD5402,
gd54xx_init, gd54xx_close,
NULL,
- gd5420_available, /* Common BIOS between 5402 and 5420 */
+ gd5402_available,
+ gd54xx_speed_changed,
+ gd54xx_force_redraw,
+ NULL,
+};
+
+const device_t gd5402_onboard_device =
+{
+ "Cirrus Logic GD-5402 (ACUMOS AVGA2) (On-Board)",
+ DEVICE_AT | DEVICE_ISA,
+ CIRRUS_ID_CLGD5402,
+ gd54xx_init, gd54xx_close,
+ NULL,
+ NULL,
gd54xx_speed_changed,
gd54xx_force_redraw,
NULL,
@@ -3311,12 +3323,13 @@ const device_t gd5420_isa_device =
CIRRUS_ID_CLGD5420,
gd54xx_init, gd54xx_close,
NULL,
- gd5420_available, /* Common BIOS between 5402 and 5420 */
+ gd5420_available,
gd54xx_speed_changed,
gd54xx_force_redraw,
gd5422_config,
};
+#if defined(DEV_BRANCH) && defined(USE_CL5422)
const device_t gd5422_isa_device = {
"Cirrus Logic GD-5422",
DEVICE_AT | DEVICE_ISA,
diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h
index b777d28dc..10c3eea0f 100644
--- a/src/video/vid_cl54xx.h
+++ b/src/video/vid_cl54xx.h
@@ -1,9 +1,10 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
extern const device_t gd5402_isa_device;
+extern const device_t gd5402_onboard_device;
extern const device_t gd5420_isa_device;
+#if defined(DEV_BRANCH) && defined(USE_CL5422)
extern const device_t gd5422_isa_device;
extern const device_t gd5424_vlb_device;
#endif
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index ac4a26084..5c33070f2 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -8,7 +8,7 @@
*
* Define all known video cards.
*
- * Version: @(#)vid_table.c 1.0.48 2020/01/20
+ * Version: @(#)vid_table.c 1.0.49 2020/01/22
*
* Authors: Miran Grca,
* Fred N. van Kempen,
@@ -94,9 +94,9 @@ video_cards[] = {
#endif
{ "[ISA] CGA", "cga", &cga_device },
{ "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device },
-#if defined(DEV_BRANCH) && defined(USE_CL5422)
{ "[ISA] Cirrus Logic CL-GD 5402", "cl_gd5402_isa", &gd5402_isa_device },
{ "[ISA] Cirrus Logic CL-GD 5420", "cl_gd5420_isa", &gd5420_isa_device },
+#if defined(DEV_BRANCH) && defined(USE_CL5422)
{ "[ISA] Cirrus Logic CL-GD 5422", "cl_gd5422_isa", &gd5422_isa_device },
#endif
{ "[ISA] Cirrus Logic CL-GD 5428", "cl_gd5428_isa", &gd5428_isa_device },
diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw
index 15b579cf3..0e2287be5 100644
--- a/src/win/Makefile.mingw
+++ b/src/win/Makefile.mingw
@@ -565,7 +565,7 @@ CPUOBJ := cpu.o cpu_table.o \
$(DYNARECOBJ)
CHIPSETOBJ := acc2168.o acer_m3a.o ali1429.o headland.o \
- intel_4x0.o neat.o opti495.o scat.o \
+ intel_4x0.o neat.o opti495.o scamp.o scat.o \
sis_85c471.o sis_85c496.o \
via_mvp3.o wd76c10.o
diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw
index 1ef8540d9..62713f351 100644
--- a/src/win/Makefile_ndr.mingw
+++ b/src/win/Makefile_ndr.mingw
@@ -571,7 +571,7 @@ CPUOBJ := cpu.o cpu_table.o \
$(DYNARECOBJ)
CHIPSETOBJ := acc2168.o acer_m3a.o ali1429.o headland.o \
- intel_4x0.o neat.o opti495.o scat.o \
+ intel_4x0.o neat.o opti495.o scamp.o scat.o \
sis_85c471.o sis_85c496.o \
via_mvp3.o wd76c10.o