Added the ZEOS Martin.

This commit is contained in:
OBattler
2025-05-16 05:04:48 +02:00
parent 4beee4452b
commit 941766f2e8
8 changed files with 226 additions and 52 deletions

View File

@@ -24,34 +24,37 @@
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/machine.h>
#include <86box/mem.h>
#include <86box/nmi.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct vl82c480_t {
uint8_t idx;
uint8_t regs[256];
uint8_t idx;
uint8_t regs[256];
uint32_t banks[4];
} vl82c480_t;
static int
vl82c480_shflags(uint8_t access)
vl82c480_shflags(uint8_t access, uint8_t access2)
{
int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
int wp = ((access2 & 0x03) == 0x01);
switch (access) {
default:
case 0x00:
ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
ret = MEM_READ_EXTANY | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY);
break;
case 0x01:
ret = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
ret = MEM_READ_EXTANY | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL);
break;
case 0x02:
ret = MEM_READ_INTERNAL | MEM_WRITE_EXTANY;
ret = MEM_READ_INTERNAL | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY);
break;
case 0x03:
ret = MEM_READ_INTERNAL | MEM_WRITE_INTERNAL;
ret = MEM_READ_INTERNAL | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL);
break;
}
@@ -59,27 +62,60 @@ vl82c480_shflags(uint8_t access)
}
static void
vl82c480_recalc(vl82c480_t *dev)
vl82c480_recalc_shadow(vl82c480_t *dev)
{
uint32_t base;
uint8_t access;
uint8_t access2;
shadowbios = 0;
shadowbios_write = 0;
for (uint8_t i = 0; i < 6; i++) {
for (uint8_t j = 0; j < 8; j += 2) {
base = 0x000a0000 + (i << 16) + (j << 13);
access = (dev->regs[0x0d + i] >> j) & 3;
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access));
base = 0x000a0000 + (i << 16) + (j << 13);
access = (dev->regs[0x0d + i] >> j) & 3;
access2 = (dev->regs[0x13 + i] >> j) & 3;
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access, access2));
shadowbios |= ((base >= 0xe0000) && (access & 0x02));
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01));
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01) && !(access2 & 0x01));
}
}
flushmmucache();
}
static void
vl82c480_recalc_banks(vl82c480_t *dev)
{
uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 };
uint8_t shifts[4] = { 0, 4, 0, 4 };
uint8_t regs[4] = { 0x02, 0x02, 0x03, 0x03 };
uint32_t total = 0;
for (uint8_t i = 0; i < 4; i++) {
uint8_t shift = shifts[i];
uint8_t reg = regs[i];
uint8_t cfg = (dev->regs[reg] >> shift) & 0x7;
uint32_t size = sizes[cfg];
total += MIN(dev->banks[i], size);
}
if (total > 1024) {
mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000);
mem_mapping_set_addr(&ram_high_mapping, 0x00100000, (total - 1024) << 10);
} else {
if (total >= 1024)
mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000);
else
mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_high_mapping);
}
flushmmucache();
}
static void
vl82c480_write(uint16_t addr, uint8_t val, void *priv)
{
@@ -91,16 +127,24 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0xed:
if (dev->idx >= 0x01 && dev->idx <= 0x24) {
if (((dev->idx >= 0x01) && (dev->idx <= 0x19)) ||
((dev->idx >= 0x20) && (dev->idx <= 0x24))) {
switch (dev->idx) {
default:
dev->regs[dev->idx] = val;
break;
case 0x02: case 0x03:
dev->regs[dev->idx] = val;
if (!strcmp(machine_get_internal_name(), "martin"))
vl82c480_recalc_banks(dev);
break;
case 0x04:
if (dev->regs[0x00] == 0x98)
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7);
else
dev->regs[dev->idx] = val;
if (!strcmp(machine_get_internal_name(), "martin"))
dev->regs[dev->idx] &= 0x1f;
break;
case 0x05:
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef);
@@ -108,14 +152,11 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
case 0x07:
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf);
break;
case 0x0d:
case 0x0e:
case 0x0f:
case 0x10:
case 0x11:
case 0x12:
case 0x0d ... 0x18:
dev->regs[dev->idx] = val;
vl82c480_recalc(dev);
vl82c480_recalc_shadow(dev);
if (dev->idx >= 0x13)
flushmmucache();
break;
}
}
@@ -124,8 +165,8 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
/* TODO: This is actually Fast A20 disable. */
#if 0
case 0xee:
if (mem_a20_alt)
outb(0x92, inb(0x92) & ~2);
mem_a20_alt = 0x00;
mem_a20_recalc();
break;
#endif
@@ -146,14 +187,16 @@ vl82c480_read(uint16_t addr, void *priv)
break;
case 0xed:
ret = dev->regs[dev->idx];
if (((dev->idx >= 0x01) && (dev->idx <= 0x19)) ||
((dev->idx >= 0x20) && (dev->idx <= 0x24)))
ret = dev->regs[dev->idx];
break;
/* TODO: This is actually Fast A20 enable. */
#if 0
case 0xee:
if (!mem_a20_alt)
outb(0x92, inb(0x92) | 2);
mem_a20_alt = 0x02;
mem_a20_recalc();
break;
#endif
@@ -180,7 +223,9 @@ vl82c480_close(void *priv)
static void *
vl82c480_init(const device_t *info)
{
vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t));
vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t));
uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 };
uint32_t ms = mem_size;
dev->regs[0x00] = info->local;
dev->regs[0x01] = 0xff;
@@ -191,9 +236,27 @@ vl82c480_init(const device_t *info)
dev->regs[0x07] = 0x21;
dev->regs[0x08] = 0x38;
for (uint8_t i = 0; i < 4; i++) {
uint32_t size = 0;
for (uint8_t j = 2; i < 7; j++) {
if (ms >= sizes[j])
size = sizes[j];
else
break;
}
ms -= size;
dev->banks[i] = size;
if ((ms == 0) || (size == 0))
break;
}
io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev);
device_add(&port_92_device);
device_add(&port_92_pci_device);
return dev;
}

View File

@@ -545,6 +545,7 @@ extern int machine_at_exp4349_init(const machine_t *);
extern int machine_at_vect486vl_init(const machine_t *);
extern int machine_at_d824_init(const machine_t *);
extern int machine_at_martin_init(const machine_t *);
extern int machine_at_403tg_init(const machine_t *);
extern int machine_at_403tg_d_init(const machine_t *);

View File

@@ -99,6 +99,7 @@ extern const device_t ami_1994_nvr_device;
extern const device_t ami_1995_nvr_device;
extern const device_t via_nvr_device;
extern const device_t p6rp4_nvr_device;
extern const device_t martin_nvr_device;
extern const device_t elt_nvr_device;
#endif

View File

@@ -724,7 +724,9 @@ machine_at_cmdsl386sx25_init(const machine_t *model)
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5402_onboard_device);
machine_at_common_ide_init(model);
machine_at_common_init_ex(model, 2);
device_add(&ide_isa_device);
device_add(&ali5105_device); /* The FDC is part of the ALi M5105. */
device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */

View File

@@ -412,14 +412,16 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
device_add(&vl82c480_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5428_onboard_device);
machine_at_common_init_ex(model, 2);
device_add(&vl82c480_device);
device_add(&vl82c113_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_ide_device);
return ret;
@@ -436,13 +438,13 @@ machine_at_d824_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&vl82c480_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5428_onboard_device);
machine_at_common_init_ex(model, 2);
device_add(&vl82c480_device);
/*
Technically, it should be the VL82C114 but we do not have
a proper datasheet of it that tells us the registers.
@@ -455,6 +457,30 @@ machine_at_d824_init(const machine_t *model)
return ret;
}
int
machine_at_martin_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/martin/NONSCSI.ROM",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
device_add(&vl82c480_device);
device_add(&vl82c113_device);
device_add(&ide_vlb_device);
device_add(&fdc37c651_ide_device);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_acera1g_init(const machine_t *model)
{

View File

@@ -6526,7 +6526,7 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has a standard IBM PS/2 KBC firmware or a clone thereof. */
/* Has a VLSI VL82C114 Combination I/O which holds the KBC. */
{
.name = "[VLSI 82C481] Siemens Nixdorf D824",
.internal_name = "d824",
@@ -6554,7 +6554,7 @@ const machine_t machines[] = {
.max = 32768,
.step = 2048
},
.nvrmask = 127,
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
@@ -6773,6 +6773,46 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has AMI MegaKey KBC. */
{
.name = "[i420TX] J-Bond PCI400C-A",
.internal_name = "pci400ca",
.type = MACHINE_TYPE_486_S2,
.chipset = MACHINE_CHIPSET_INTEL_420TX,
.init = machine_at_pci400ca_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET3,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PCI,
.flags = MACHINE_SCSI,
.ram = {
.min = 1024,
.max = 65536,
.step = 1024
},
.nvrmask = 127,
.kbc_device = &keyboard_at_ami_device,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* This has a standalone AMI Megakey 1993, which is type 'P'. */
{
.name = "[IMS 8848] Tekram G486IP",
@@ -6934,13 +6974,13 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has AMI MegaKey KBC. */
/* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */
{
.name = "[i420TX] J-Bond PCI400C-A",
.internal_name = "pci400ca",
.name = "[VLSI 82C480] ZEOS Martin",
.internal_name = "martin",
.type = MACHINE_TYPE_486_S2,
.chipset = MACHINE_CHIPSET_INTEL_420TX,
.init = machine_at_pci400ca_init,
.chipset = MACHINE_CHIPSET_VLSI_VL82C480,
.init = machine_at_martin_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
@@ -6955,15 +6995,15 @@ const machine_t machines[] = {
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PCI,
.flags = MACHINE_SCSI,
.bus_flags = MACHINE_PS2,
.flags = MACHINE_IDE | MACHINE_APM,
.ram = {
.min = 1024,
.min = 2048,
.max = 65536,
.step = 1024
.step = 2048
},
.nvrmask = 127,
.kbc_device = &keyboard_at_ami_device,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
@@ -6975,7 +7015,6 @@ const machine_t machines[] = {
.net_device = NULL
},
/* 486 machines - Socket 3 */
/* 486 machines with just the ISA slot */
/* Has a Fujitsu MBL8042H KBC. */

View File

@@ -296,6 +296,7 @@
#define FLAG_P6RP4_HACK 0x10
#define FLAG_PIIX4 0x20
#define FLAG_MULTI_BANK 0x40
#define FLAG_MARTIN_HACK 0x80
typedef struct local_t {
int8_t stat;
@@ -733,6 +734,13 @@ nvr_read(uint16_t addr, void *priv)
ret = REGD_VRT;
break;
case 0x11:
if (local->flags & FLAG_MARTIN_HACK)
ret = nvr->regs[local->addr[addr_id]] | 0x02;
else
ret = nvr->regs[local->addr[addr_id]];
break;
case 0x2c:
if (!nvr->is_new && (local->flags & FLAG_AMI_1994_HACK))
ret = nvr->regs[local->addr[addr_id]] & 0x7f;
@@ -771,6 +779,17 @@ nvr_read(uint16_t addr, void *priv)
ret = checksum >> 8;
else
ret = checksum & 0xff;
} else if (!nvr->is_new && (local->flags & FLAG_MARTIN_HACK)) {
for (i = 0x10; i <= 0x2d; i++) {
if (i == 0x11)
checksum += (nvr->regs[i] | 0x02);
else
checksum += nvr->regs[i];
}
if (local->addr[addr_id] == 0x2e)
ret = checksum >> 8;
else
ret = checksum & 0xff;
} else
ret = nvr->regs[local->addr[addr_id]];
break;
@@ -1123,9 +1142,11 @@ nvr_at_init(const device_t *info)
if (info->local & 0x10) {
local->def = 0x00;
local->flags |= FLAG_AMI_1992_HACK;
} else if (info->local == 36)
} else if ((info->local == 36) || (info->local == 68)) {
local->def = 0x00;
else
if (info->local == 68)
local->flags |= FLAG_MARTIN_HACK;
} else
local->def = 0xff;
nvr->irq = 8;
local->cent = RTC_CENTURY_AT;
@@ -1160,6 +1181,9 @@ nvr_at_init(const device_t *info)
/* Initialize the generic NVR. */
nvr_init(nvr);
if (nvr->is_new && (local->flags & FLAG_MARTIN_HACK))
nvr->regs[0x11] = nvr->regs[0x2f] = 0x02;
if (nvr_at_inited == 0) {
/* Start the timers. */
timer_add(&local->update_timer, timer_update, nvr, 0);
@@ -1426,6 +1450,20 @@ const device_t amstrad_megapc_nvr_device = {
.config = NULL
};
const device_t martin_nvr_device = {
.name = "Zeos Martin NVRAM",
.internal_name = "martin_nvr",
.flags = DEVICE_ISA16,
.local = 68,
.init = nvr_at_init,
.close = nvr_at_close,
.reset = nvr_at_reset,
.available = NULL,
.speed_changed = nvr_at_speed_changed,
.force_redraw = NULL,
.config = NULL
};
const device_t elt_nvr_device = {
.name = "Epson Equity LT NVRAM",
.internal_name = "elt_nvr",

View File

@@ -22,6 +22,7 @@
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/machine.h>
#include <86box/nvr.h>
#include <86box/sio.h>
#include <86box/plat_unused.h>
@@ -133,7 +134,10 @@ vl82c113_init(UNUSED(const device_t *info))
{
vl82c113_t *dev = (vl82c113_t *) calloc(1, sizeof(vl82c113_t));
dev->nvr = device_add(&at_nvr_device);
if (!strcmp(machine_get_internal_name(), "martin"))
dev->nvr = device_add(&martin_nvr_device);
else
dev->nvr = device_add(&amstrad_megapc_nvr_device);
dev->nvr_enabled = 1;
dev->nvr_base = 0x0070;