Implement the VLSI SuperCore/Wildcat chipsets (#6247)

* Add the VLSI SuperCore and Wildcat chipsets

* Disable logging and minor cleanups

* Add the AST Bravo MS P/90 (Rattler)

* Add the AT&T Globalyst 620 (NCR 3248)

* Add the DEC Celebris 5xx

* Add the DFI G586VPM Rev C

* Add the Packard Bell PB600

* Fix southbridge PCI Command Register writes

* Block the Cyrix 6x86 on incompatible machines

* Rename the AT&T Globalyst 620 to include the names of the NCR counterparts

* Add the Zeos Pantera Wildcat

* Add RZ-1001 variant of the RZ-1000 PCI IDE controller and made the Zeos Pantera Wildcat use it

* Add the Micronics M54Si

* Update machine_table.c

* Re-add new machines to machine table

* Update machine inits to use new KBC device names

* Use correct machine init method as NVRAM init is done by the chipset code

* Use a Phoenix KBC for the AST Bravo since the BIOS calls command D5h to show the KBC revision

* Update KBC comments in machine table

* Update VLSI 59x chipset comments

* Update machine inits for new super I/O code

* Reorganize machines and update comments

* AST readout device actually has multiple indexed registers

* Implement the AST Bravo MS ECP DMA configuration

* Implement jumpered/hardwired ECP DMA for the remaining machines

* Fix ECP DMA on the AST Bravo MS

* Move the DEC Celebris to the Socket 4/5 category

* Implement SMI I/O port read, fixes APM init on AT&T, Micronics and Zeos machines

* Convert AST readout device to new logging system

* Update KBC init to new method

* Cleanups
This commit is contained in:
win2kgamer
2025-09-28 21:48:33 -05:00
committed by GitHub
parent 4d35eee630
commit 5c9fa029bf
15 changed files with 1663 additions and 1 deletions

View File

@@ -92,5 +92,6 @@ add_library(chipset OBJECT
via_apollo.c
via_pipc.c
vl82c480.c
vl82c59x.c
wd76c10.c
)

644
src/chipset/vl82c59x.c Normal file
View File

@@ -0,0 +1,644 @@
/*
* 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 SuperCore and Wildcat chipsets.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* win2kgamer
*
* Copyright 2020-2025 Miran Grca.
* Copyright 2025 win2kgamer
*/
#ifdef ENABLE_VL82C59X_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/device.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/apm.h>
#include <86box/machine.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/pit_fast.h>
#include <86box/plat_unused.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/port_92.h>
#include <86box/spd.h>
#include <86box/keyboard.h>
#include <86box/chipset.h>
#include <86box/log.h>
#ifdef ENABLE_VL82C59X_LOG
int vl82c59x_do_log = ENABLE_VL82C59X_LOG;
static void
vl82c59x_log(void *priv, const char *fmt, ...)
{
if (vl82c59x_do_log) {
va_list ap;
va_start(ap, fmt);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define vl82c59x_log(fmt, ...)
#endif
typedef struct vl82c59x_t {
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t type;
uint8_t is_compaq;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[256];
uint16_t pmio;
uint8_t pmio_set;
uint8_t pmreg;
smram_t *smram[4];
port_92_t *port_92;
nvr_t *nvr;
void * log; /* New logging system */
} vl82c59x_t;
static int
vl82c59x_shflags(uint8_t access)
{
int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
switch (access) {
default:
case 0x00:
ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
break;
case 0x01:
ret = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
break;
case 0x02:
ret = MEM_READ_INTERNAL | MEM_WRITE_EXTANY;
break;
case 0x03:
ret = MEM_READ_INTERNAL | MEM_WRITE_INTERNAL;
break;
}
return ret;
}
static void
vl82c59x_recalc(vl82c59x_t *dev)
{
uint32_t base;
uint8_t access;
shadowbios = 0;
shadowbios_write = 0;
for (uint8_t i = 0; i < 4; i++) {
for (uint8_t j = 0; j < 8; j += 2) {
base = 0x000c0000 + (i << 16) + (j << 13);
access = (dev->pci_conf[0x66 + i] >> j) & 3;
mem_set_mem_state_both(base, 0x4000, vl82c59x_shflags(access));
shadowbios |= ((base >= 0xe0000) && (access & 0x02));
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01));
}
}
flushmmucache();
}
static void
vl82c59x_smram(vl82c59x_t *dev)
{
smram_disable_all();
/* A/B region SMRAM seems to not be controlled by 591 reg 0x7C/SMRAM enable */
/* Dell Dimension BIOS breaks if A0000 region is controlled by SMRAM enable */
if (dev->pci_conf[0x64] & 0x55) {
smram_enable(dev->smram[1], 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x64] & 0xAA, dev->pci_conf[0x64] & 0x55);
}
if (dev->pci_conf[0x65] & 0x55) {
smram_enable(dev->smram[2], 0x000b0000, 0x000b0000, 0x10000, dev->pci_conf[0x65] & 0xAA, dev->pci_conf[0x65] & 0x55);
}
/* Handle E region SMRAM */
if (dev->pci_conf[0x7C] & 0x80) {
if (dev->pci_conf[0x68] & 0x05) {
smram_enable(dev->smram[3], 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x0A, dev->pci_conf[0x68] & 0x05);
}
if (dev->pci_conf[0x68] & 0x50) {
smram_enable(dev->smram[4], 0x000e8000, 0x000e8000, 0x8000, dev->pci_conf[0x68] & 0xA0, dev->pci_conf[0x68] & 0x50);
}
}
flushmmucache();
}
static void
vl82c59x_pm_write(uint16_t addr, uint8_t val, void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
vl82c59x_log(dev->log, "VL82c593 SMI I/O: [W] (%04X) = %02X\n", addr, val);
/* Verify SMI Global Enable and Software SMI Enable are set */
if ((dev->pci_conf_sb[0x6D] & 0x80) && (dev->pci_conf_sb[0x60] & 0x80)) {
dev->pci_conf_sb[0x61] = 0x80;
dev->pmreg = val;
smi_raise();
}
}
static uint8_t
vl82c59x_pm_read(uint16_t addr, void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
uint8_t ret = 0x00;
ret = dev->pmreg;
vl82c59x_log(dev->log, "VL82c593 SMI I/O: [R] (%04X) = %02X\n", addr, ret);
return ret;
}
static void
vl82c59x_set_pm_io(void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
uint8_t highbyte = dev->pci_conf_sb[0x62];
uint8_t lowbyte = dev->pci_conf_sb[0x63];
/* Check for existing I/O mapping and remove it */
if (dev->pmio_set == 1) {
vl82c59x_log(dev->log, "VL82c59x: Removing SMI IO handler for %04X\n", dev->pmio);
io_removehandler(dev->pmio, 0x0001, vl82c59x_pm_read, NULL, NULL, vl82c59x_pm_write, NULL, NULL, dev);
dev->pmio_set = 0;
}
if ((highbyte != 0x00) | (lowbyte != 0x00)) {
dev->pmio = ((highbyte << 8) + lowbyte);
vl82c59x_log(dev->log, "VL82c59x: Adding SMI IO handler for %04X\n", dev->pmio);
io_sethandler(dev->pmio, 0x0001, vl82c59x_pm_read, NULL, NULL, vl82c59x_pm_write, NULL, NULL, dev);
dev->pmio_set = 1;
}
}
static void
vl82c59x_write(int func, int addr, uint8_t val, void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
vl82c59x_log(dev->log, "[%04X:%08X] VL82c591: [W] (%02X, %02X) = %02X\n", CS, cpu_state.pc, func, addr, val);
if (func == 0x00)
switch (addr) {
case 0x04:
case 0x05: /* PCI Command Register */
dev->pci_conf[addr] = val;
break;
case 0x54: /* Cache Control Register 1 */
dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = (val & 0xc0);
cpu_update_waitstates();
break;
case 0x55: /* Cache Control Register 2 */
dev->pci_conf[addr] = val;
cpu_cache_int_enabled = (val & 0x40);
cpu_update_waitstates();
break;
case 0x58: /* RAMCFG0 */
case 0x59: /* RAMCFG1 */
dev->pci_conf[addr] = val;
break;
case 0x5A: /* Wildcat EDO RAM control */
if (dev->type == 0x01) {
dev->pci_conf[addr] = val;
}
break;
case 0x5C: /* RAMCTL0 */
case 0x5D: /* RAMCTL1 */
case 0x5E: /* RAMCTL2 */
case 0x5F:
case 0x60:
case 0x62:
/* Apricot XEN-PC Ruby/Jade BIOS requires bit 2 to be set or */
/* CMOS setup hangs on subsequent runs after NVRAM is initialized */
dev->pci_conf[addr] = val;
break;
case 0x64: /* A-B SMRAM regs */
case 0x65:
dev->pci_conf[addr] = val;
vl82c59x_smram(dev);
break;
case 0x66: /* Shadow RAM */
case 0x67:
case 0x68:
case 0x69:
dev->pci_conf[addr] = val;
vl82c59x_recalc(dev);
vl82c59x_smram(dev);
break;
case 0x6C: /* L2 Cacheability registers */
case 0x6D:
case 0x6E:
case 0x6F:
case 0x70:
case 0x71:
case 0x74: /* Suspected PMRA registers */
case 0x75:
case 0x76:
case 0x78:
case 0x79:
case 0x7A:
dev->pci_conf[addr] = val;
break;
case 0x7C: /* MISCSSET, bit 7 is SMRAM enable (for the E region) */
/* io.c logging shows BIOSes setting Bit 7 here */
dev->pci_conf[addr] = val;
vl82c59x_smram(dev);
break;
case 0x7D: /* Unknown but seems Wildcat-specific, Zeos and PB600 BIOSes hang if bit 3 is writable */
if (dev->type == 0x01) {
dev->pci_conf[addr] = val & 0xf7;
}
break;
default:
if (addr > 0x3F)
vl82c59x_log(dev->log, "VL82c591: Unknown reg [W] (%02X, %02X) = %02X\n", func, addr, val);
break;
}
}
static uint8_t
vl82c59x_read(int func, int addr, void *priv)
{
const vl82c59x_t *dev = (vl82c59x_t *) priv;
uint8_t ret = 0xff;
if (func == 0x00) {
switch (addr) {
default:
ret = dev->pci_conf[addr];
break;
}
}
vl82c59x_log(dev->log, "[%04X:%08X] VL82c591: [R] (%02X, %02X) = %02X\n", CS, cpu_state.pc, func, addr, ret);
return ret;
}
static void
vl82c59x_sb_write(int func, int addr, uint8_t val, void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
uint8_t irq;
const uint8_t irq_array[8] = { 3, 5, 9, 10, 11, 12, 14, 15 };
vl82c59x_log(dev->log, "[%04X:%08X] VL82c593: [W] (%02X, %02X) = %02X\n", CS, cpu_state.pc, func, addr, val);
if (func == 0x00)
switch (addr) {
case 0x04:
case 0x05: /* PCI Command Register */
dev->pci_conf_sb[addr] = val;
break;
case 0x50: /* MISCSETC */
case 0x51: /* MISCSETB */
case 0x52: /* MISCSETA */
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
case 0x58:
case 0x59:
case 0x5A:
/* Has at least one GPIO bit. Compaq Presario 700/900 586 BIOS */
/* uses bit 2 as an output to set the onboard ES688's base I/O */
/* address. Bit 2 cleared = 220, bit 2 set = 240 */
case 0x5C: /* Interrupt Assertion Level Register */
case 0x5D:
dev->pci_conf_sb[addr] = val;
break;
case 0x60: /* SMI Enable Register */
dev->pci_conf_sb[addr] = val;
break;
case 0x61: /* SMI Status Register */
dev->pci_conf_sb[addr] = 0x00;
break;
case 0x62: /* SMI I/O port high byte */
case 0x63: /* SMI I/O port low byte */
dev->pci_conf_sb[addr] = val;
vl82c59x_set_pm_io(dev);
break;
case 0x64: /* System Event Enable Register 1 */
dev->pci_conf_sb[addr] = val;
break;
case 0x65: /* System Event Status Register 1 */
dev->pci_conf_sb[addr] = 0x00;
break;
case 0x66: /* System Event Enable Register 2 */
dev->pci_conf_sb[addr] = val;
break;
case 0x67: /* System Event Status Register 2 */
dev->pci_conf_sb[addr] = 0x00;
break;
case 0x68: /* System Event Enable Register 3 */
dev->pci_conf_sb[addr] = val;
break;
case 0x69: /* System Event Status Register 3 */
dev->pci_conf_sb[addr] = 0x00;
break;
case 0x6A: /* PCI Activity Control Register */
dev->pci_conf_sb[addr] = val & 0x0f; /* Top 4 bits are Read/Clear */
break;
case 0x6B: /* Programmable I/O Range Register High Byte */
dev->pci_conf_sb[addr] = val;
break;
case 0x6C: /* Programmable I/O Range Register Low Byte */
dev->pci_conf_sb[addr] = val;
break;
case 0x6D: /* System Event Control Register/SMI Global Enable */
dev->pci_conf_sb[addr] = val;
break;
case 0x6E:
case 0x6F:
case 0x70:
case 0x71:
case 0x72: /* GPIO */
/* Compaq Presario and Prolinea use bits 6-4 for setting ECP DMA */
/* 011 (0x03) = DMA 3 (Default) */
/* 100 (0x04) = DMA 0 */
/* 111 (0x07) = DMA disabled */
case 0x73: /* GPIO */
dev->pci_conf_sb[addr] = val;
break;
case 0x74: /* PCI Interrupt Connection Register (PCIINT0/1) */
dev->pci_conf_sb[addr] = val;
irq = irq_array[val & 0x07];
pci_set_irq_routing(PCI_INTA, (irq != 0) ? irq : PCI_IRQ_DISABLED);
irq = irq_array[(val & 0x70) >> 4];
pci_set_irq_routing(PCI_INTB, (irq != 0) ? irq : PCI_IRQ_DISABLED);
break;
case 0x75: /* PCI Interrupt Connection Register (PCIINT2/3) */
dev->pci_conf_sb[addr] = val;
irq = irq_array[val & 0x07];
pci_set_irq_routing(PCI_INTC, (irq != 0) ? irq : PCI_IRQ_DISABLED);
irq = irq_array[(val & 0x70) >> 4];
pci_set_irq_routing(PCI_INTD, (irq != 0) ? irq : PCI_IRQ_DISABLED);
break;
case 0x76: /* PCI Interrupt Connection Register (ISA/PCIINT) */
dev->pci_conf_sb[addr] = val;
break;
case 0x77:
case 0x78:
dev->pci_conf_sb[addr] = val;
break;
default:
if (addr > 0x3F)
vl82c59x_log(dev->log, "VL82c593: Unknown reg [W] (%02X, %02X) = %02X\n", func, addr, val);
break;
}
}
static uint8_t
vl82c59x_sb_read(int func, int addr, void *priv)
{
const vl82c59x_t *dev = (vl82c59x_t *) priv;
uint8_t ret = 0xff;
if (func == 0x00)
switch (addr) {
case 0x69: /* Lower two bits are a CPU speed readout per Compaq's Prolinea E series TRG */
/* Per the Prolinea TRG bits 5/3/1 of 593 reg 0x73 must be set to 1 to read the jumpers */
if (dev->is_compaq && (dev->pci_conf_sb[0x73] & 0x2A)) {
/* Set bit 2 to 1 as this is required for the Prolinea E to be properly identified
in Compaq Computer Setup. */
ret = (dev->pci_conf_sb[addr] | 0x04);
if (cpu_busspeed <= 50000000)
ret = (ret & 0xfd); /* 50MHz: Bit 1 = 0 */
else
ret = (ret | 0x02); /* 60MHz: Bit 1 = 1 */
if (cpu_dmulti <= 1.5)
ret = (ret | 0x01); /* 1.5x mult: Bit 0 = 1 */
else
ret = (ret & 0xfe); /* 2.0x mult: Bit 0 = 0 */
} else {
ret = dev->pci_conf_sb[addr];
}
break;
default:
ret = dev->pci_conf_sb[addr];
break;
}
vl82c59x_log(dev->log, "[%04X:%08X] VL82c593: [R] (%02X, %02X) = %02X\n", CS, cpu_state.pc, func, addr, ret);
return ret;
}
static void
vl82c59x_reset(void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
/* Northbridge (VLSI VL82c591) */
dev->pci_conf[0x00] = 0x04;
dev->pci_conf[0x01] = 0x10;
switch (dev->type) {
case 0: /* SuperCore */
dev->pci_conf[0x02] = 0x05;
dev->pci_conf[0x03] = 0x00;
break;
case 1: /* Wildcat */
dev->pci_conf[0x02] = 0x07;
dev->pci_conf[0x03] = 0x00;
break;
}
dev->pci_conf[0x08] = 0x00;
dev->pci_conf[0x09] = 0x00;
dev->pci_conf[0x0a] = 0x00;
dev->pci_conf[0x0b] = 0x06;
/* Southbridge (VLSI VL82c593) */
dev->pci_conf_sb[0x00] = 0x04;
dev->pci_conf_sb[0x01] = 0x10;
switch (dev->type) {
case 0: /* SuperCore */
dev->pci_conf_sb[0x02] = 0x06;
dev->pci_conf_sb[0x03] = 0x00;
break;
case 1: /* Wildcat */
dev->pci_conf_sb[0x02] = 0x08;
dev->pci_conf_sb[0x03] = 0x00;
break;
}
dev->pci_conf_sb[0x08] = 0x00;
dev->pci_conf_sb[0x09] = 0x00;
dev->pci_conf_sb[0x0a] = 0x01;
dev->pci_conf_sb[0x0b] = 0x06;
/* Unsure on which register configures this (if any), per Compaq's
* Pentium-based Presario 700/900 Series and Prolinea E Series Desktop
* Technical Reference Guides the ISA bus runs at 8MHz while the
* Zeos Pantera Wildcat user manual says that the ISA bus runs at
* 7.5MHz on 90MHz (60MHz bus) systems and 8.25MHz on 100MHz (66MHz bus)
* systems.
*/
if (cpu_busspeed > 50000000)
cpu_set_isa_pci_div(4);
else
cpu_set_isa_pci_div(3);
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);
vl82c59x_smram(dev);
/* Reset SMI IO port */
dev->pmio = 0x0000;
dev->pmio_set = 0;
cpu_cache_int_enabled = 1;
cpu_cache_ext_enabled = 1;
cpu_update_waitstates();
}
static void
vl82c59x_close(void *priv)
{
vl82c59x_t *dev = (vl82c59x_t *) priv;
smram_del(dev->smram[1]);
smram_del(dev->smram[2]);
smram_del(dev->smram[3]);
smram_del(dev->smram[4]);
if (dev->log != NULL) {
log_close(dev->log);
dev->log = NULL;
}
free(dev);
}
static void *
vl82c59x_init(UNUSED(const device_t *info))
{
vl82c59x_t *dev = (vl82c59x_t *) calloc(1, sizeof(vl82c59x_t));
dev->type = (info->local & 0x0f);
dev->is_compaq = (info->local >> 4);
dev->log = log_open("VL82c59x");
/* VL82c591 (Northbridge) */
pci_add_card(PCI_ADD_NORTHBRIDGE, vl82c59x_read, vl82c59x_write, dev, &dev->nb_slot);
/* VL82c593 (Southbridge) */
pci_add_card(PCI_ADD_SOUTHBRIDGE, vl82c59x_sb_read, vl82c59x_sb_write, dev, &dev->sb_slot);
dev->port_92 = device_add(&port_92_device);
/* NVR */
dev->nvr = device_add(&at_nvr_device);
dev->smram[1] = smram_add();
dev->smram[2] = smram_add();
dev->smram[3] = smram_add();
dev->smram[4] = smram_add();
vl82c59x_reset(dev);
return dev;
}
const device_t vl82c59x_device = {
.name = "VLSI VL82c59x (SuperCore)",
.internal_name = "vl82c59x",
.flags = DEVICE_PCI,
.local = 0,
.init = vl82c59x_init,
.close = vl82c59x_close,
.reset = vl82c59x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t vl82c59x_compaq_device = {
.name = "VLSI VL82c59x (SuperCore with Compaq readout)",
.internal_name = "vl82c59x_compaq",
.flags = DEVICE_PCI,
.local = 0x10,
.init = vl82c59x_init,
.close = vl82c59x_close,
.reset = vl82c59x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t vl82c59x_wildcat_device = {
.name = "VLSI VL82c59x (Wildcat)",
.internal_name = "vl82c59x_wildcat",
.flags = DEVICE_PCI,
.local = 1,
.init = vl82c59x_init,
.close = vl82c59x_close,
.reset = vl82c59x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t vl82c59x_wildcat_compaq_device = {
.name = "VLSI VL82c59x (Wildcat with Compaq readout)",
.internal_name = "vl82c59x_wildcat_compaq",
.flags = DEVICE_PCI,
.local = 0x11,
.init = vl82c59x_init,
.close = vl82c59x_close,
.reset = vl82c59x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -18,6 +18,8 @@
add_library(dev OBJECT
access_bus.c
ast_nvr.c
ast_readout.c
bugger.c
cartridge.c
cassette.c

180
src/device/ast_nvr.c Normal file
View File

@@ -0,0 +1,180 @@
/*
* 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 AST Bravo MS secondary NVR
*
*
*
* Authors: win2kgamer
*
* Copyright 2025 win2kgamer.
*/
#ifdef ENABLE_AST_NVR_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/rom.h>
#include <86box/log.h>
#ifdef ENABLE_AST_NVR_LOG
int ast_nvr_do_log = ENABLE_AST_NVR_LOG;
static void
ast_nvr_log(void *priv, const char *fmt, ...)
{
if (ast_nvr_do_log) {
va_list ap;
va_start(ap, fmt);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define ast_nvr_log(fmt, ...)
#endif
typedef struct ast_nvr_t {
int addr;
int bank;
uint8_t *ram;
int size;
char *fn;
void * log; // New logging system
} ast_nvr_t;
static uint8_t
ast_nvr_read(uint16_t port, void *priv)
{
ast_nvr_t *nvr = (ast_nvr_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0x800 ... 0x8FF:
nvr->addr = ((nvr->bank << 8) + (port - 0x800));
ret = nvr->ram[nvr->addr];
break;
default:
break;
}
ast_nvr_log(nvr->log, "AST NVR Read [%02X:%02X] = %02X\n", nvr->bank, port, ret);
return ret;
}
static void
ast_nvr_write(uint16_t port, uint8_t val, void *priv)
{
ast_nvr_t *nvr = (ast_nvr_t *) priv;
ast_nvr_log(nvr->log, "AST NVR Write [%02X:%02X] = %02X\n", nvr->bank, port, val);
switch (port) {
case 0x800 ... 0x8FF:
nvr->addr = ((nvr->bank << 8) + (port - 0x800));
nvr->ram[nvr->addr] = val;
break;
case 0xC00:
nvr->bank = val;
default:
break;
}
}
static void *
ast_nvr_init(const device_t *info)
{
ast_nvr_t *nvr;
FILE *fp = NULL;
int c;
nvr = (ast_nvr_t *) calloc(1, sizeof(ast_nvr_t));
memset(nvr, 0x00, sizeof(ast_nvr_t));
nvr->log = log_open("ASTNVR");
nvr->size = 8192;
/* Set up the NVR file's name */
c = strlen(machine_get_internal_name()) + 9;
nvr->fn = (char *) calloc(1, (c + 1));
sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name());
io_sethandler(0x0800, 0x100,
ast_nvr_read, NULL, NULL, ast_nvr_write, NULL, NULL, nvr);
io_sethandler(0x0C00, 0x01,
ast_nvr_read, NULL, NULL, ast_nvr_write, NULL, NULL, nvr);
fp = nvr_fopen(nvr->fn, "rb");
nvr->ram = (uint8_t *) calloc(1, nvr->size);
memset(nvr->ram, 0xff, nvr->size);
if (fp != NULL) {
if (fread(nvr->ram, 1, nvr->size, fp) != nvr->size)
fatal("ast_nvr_init(): Error reading EEPROM data\n");
fclose(fp);
}
return nvr;
}
static void
ast_nvr_close (void *priv)
{
ast_nvr_t *nvr = (ast_nvr_t *) priv;
FILE *fp = NULL;
fp = nvr_fopen(nvr->fn, "wb");
if (fp != NULL) {
(void) fwrite(nvr->ram, nvr->size, 1, fp);
fclose(fp);
}
if (nvr->ram != NULL)
free(nvr->ram);
if (nvr->log != NULL) {
log_close(nvr->log);
nvr->log = NULL;
}
free(nvr);
}
const device_t ast_nvr_device = {
.name = "AST Secondary NVRAM for Bravo MS",
.internal_name = "ast_nvr",
.flags = 0,
.local = 0,
.init = ast_nvr_init,
.close = ast_nvr_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

198
src/device/ast_readout.c Normal file
View File

@@ -0,0 +1,198 @@
/*
* 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 AST Bravo MS jumper readout.
*
*
*
* Authors: win2kgamer
*
* Copyright 2025 win2kgamer
*/
#ifdef ENABLE_AST_READOUT_LOG
#include <stdarg.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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/chipset.h>
#include <86box/plat_unused.h>
#include <86box/lpt.h>
#include <86box/machine.h>
#include <86box/log.h>
/*
The AST readout device has multiple indexed registers that handle
jumper readout, software ECP DMA configuration and other unknown functions.
Register 0x00:
Bits 6-4 = ECP DMA configuration
010 (0x02) = DMA 0
101 (0x05) = DMA 1
111 (0x07) = DMA 3
Register 0x03:
Bit 7 = Force flash
Bit 6 = Password disable
Bit 5 = Mono/Color primary video (0=Color/1=Mono)
Bit 4 = Setup disable (0=Enable Setup/1=Disable Setup)
Bit 3 = Enable onboard video (0=Enable/1=Disable)
Bit 2 = ????
Bit 1 = ????
Bit 0 = ????
*/
typedef struct ast_readout_t {
uint8_t index;
uint8_t jumper[4];
void * log; // New logging system
} ast_readout_t;
#ifdef ENABLE_AST_READOUT_LOG
int ast_readout_do_log = ENABLE_AST_READOUT_LOG;
static void
ast_readout_log(void *priv, const char *fmt, ...)
{
if (ast_readout_do_log) {
va_list ap;
va_start(ap, fmt);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define ast_readout_log(fmt, ...)
#endif
static void
ast_readout_write(uint16_t port, uint8_t val, void *priv)
{
ast_readout_t *dev = (ast_readout_t *) priv;
switch (port) {
case 0xE0:
ast_readout_log(dev->log, "[%04X:%08X] AST Bravo Readout: Set Index %02X\n", CS, cpu_state.pc, val);
dev->index = val;
break;
case 0xE1:
ast_readout_log(dev->log, "[%04X:%08X] AST Bravo Readout: Write %02X:%02X\n", CS, cpu_state.pc, dev->index, val);
if ((dev->index == 0x00) && (!strcmp(machine_get_internal_name(), "bravoms586"))) {
uint8_t dmaval = ((val >> 4) & 0x07);
dev->jumper[dev->index] = val;
switch (dmaval) {
case 0x02:
ast_readout_log(dev->log, "ECP DMA set to 0\n");
lpt1_dma(0);
break;
case 0x05:
ast_readout_log(dev->log, "ECP DMA set to 1\n");
lpt1_dma(1);
break;
case 0x07:
ast_readout_log(dev->log, "ECP DMA set to 3\n");
lpt1_dma(3);
break;
default:
ast_readout_log(dev->log, "Unknown ECP DMA!\n");
break;
}
} else if (dev->index == 0x03) {
dev->jumper[dev->index] = (val & 0x07);
if (gfxcard[0] != 0x01)
dev->jumper[dev->index] |= 0x08;
}
else
dev->jumper[dev->index] = val;
break;
default:
break;
}
}
static uint8_t
ast_readout_read(uint16_t port, void *priv)
{
const ast_readout_t *dev = (ast_readout_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0xE0:
ast_readout_log(dev->log, "[%04X:%08X] AST Bravo Readout: Read Index %02X\n", CS, cpu_state.pc, dev->index);
ret = dev->index;
break;
case 0xE1:
ast_readout_log(dev->log, "[%04X:%08X] AST Bravo Readout: Read %02X:%02X\n", CS, cpu_state.pc, dev->index, dev->jumper[dev->index]);
ret = dev->jumper[dev->index];
break;
default:
break;
}
return ret;
}
static void
ast_readout_reset(void *priv)
{
ast_readout_t *dev = (ast_readout_t *) priv;
dev->jumper[0x03] = 0x06;
if (gfxcard[0] != 0x01)
dev->jumper[0x03] |= 0x08;
}
static void
ast_readout_close(void *priv)
{
ast_readout_t *dev = (ast_readout_t *) priv;
if (dev->log != NULL) {
log_close(dev->log);
dev->log = NULL;
}
free(dev);
}
static void *
ast_readout_init(const device_t *info)
{
ast_readout_t *dev = (ast_readout_t *) calloc(1, sizeof(ast_readout_t));
dev->log = log_open("AST Readout");
ast_readout_reset(dev);
io_sethandler(0x00E0, 0x0002, ast_readout_read, NULL, NULL, ast_readout_write, NULL, NULL, dev);
return dev;
}
const device_t ast_readout_device = {
.name = "AST Bravo MS Readout",
.internal_name = "ast_readout",
.flags = 0,
.local = 0,
.init = ast_readout_init,
.close = ast_readout_close,
.reset = ast_readout_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -40,6 +40,18 @@
Bit 0 = ????.
*/
/*
PB600 bit meanings:
Bit 7 = ???? (if 1 BIOS throws beep codes and won't POST)
Bit 6 = Super I/O chip: 1 = disabled, 0 = enabled
Bit 5 = ????
Bit 4 = ????
Bit 3 = ????
Bit 2 = ????
Bit 1 = Quick Boot: 1 = normal boot, 0 = quick boot/skip POST
Bit 0 = ????
*/
typedef struct phoenix_486_jumper_t {
uint8_t type;
uint8_t jumper;
@@ -70,6 +82,8 @@ phoenix_486_jumper_write(UNUSED(uint16_t addr), uint8_t val, void *priv)
phoenix_486_jumper_log("Phoenix 486 Jumper: Write %02x\n", val);
if (dev->type == 1)
dev->jumper = val & 0xbf;
else if (dev->type == 2) /* PB600 */
dev->jumper = ((val & 0xbf) | 0x02);
else
dev->jumper = val;
}
@@ -90,6 +104,8 @@ phoenix_486_jumper_reset(void *priv)
if (dev->type == 1)
dev->jumper = 0x00;
else if (dev->type == 2) /* PB600 */
dev->jumper = 0x02;
else {
dev->jumper = 0x9f;
if (gfxcard[0] != 0x01)
@@ -146,3 +162,17 @@ const device_t phoenix_486_jumper_pci_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t phoenix_486_jumper_pci_pb600_device = {
.name = "Phoenix 486 Jumper Readout (PB600)",
.internal_name = "phoenix_486_jumper_pci_pb600",
.flags = 0,
.local = 2,
.init = phoenix_486_jumper_init,
.close = phoenix_486_jumper_close,
.reset = phoenix_486_jumper_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -694,3 +694,18 @@ const device_t ide_cmd640_pci_single_channel_sec_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_pci_single_channel_legacy_only_device = {
.name = "CMD PCI-0640B PCI (Legacy Mode Only)",
.internal_name = "ide_cmd640_pci_single_channel_legacy_only",
.flags = DEVICE_PCI,
.local = 0x20000,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -51,6 +51,7 @@ typedef struct rz1000_t {
int irq_mode[2];
int irq_pin;
int irq_line;
uint8_t type;
} rz1000_t;
static int next_id = 0;
@@ -197,9 +198,12 @@ rz1000_reset(void *priv)
rz1000_log("dev->local = %08X\n", dev->local);
dev->type = ((dev->local >> 8) & 0x01);
rz1000_log("dev->type = %04X\n", dev->type);
dev->regs[0x00] = 0x42; /* PC Technology */
dev->regs[0x01] = 0x10;
dev->regs[0x02] = 0x00; /* RZ-1000 */
dev->regs[0x02] = dev->type; /* RZ-1000/RZ-1001 */
dev->regs[0x03] = 0x10;
dev->regs[0x04] = 0x00;
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
@@ -296,3 +300,17 @@ const device_t ide_rz1000_pci_single_channel_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t ide_rz1001_pci_device = {
.name = "PC Technology RZ-1001 PCI",
.internal_name = "ide_rz1001_pci",
.flags = DEVICE_PCI,
.local = 0x60100,
.init = rz1000_init,
.close = rz1000_close,
.reset = rz1000_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -214,6 +214,10 @@ extern const device_t via_vt8231_device;
/* VLSI */
extern const device_t vl82c480_device;
extern const device_t vl82c486_device;
extern const device_t vl82c59x_device;
extern const device_t vl82c59x_compaq_device;
extern const device_t vl82c59x_wildcat_device;
extern const device_t vl82c59x_wildcat_compaq_device;
extern const device_t vlsi_scamp_device;
/* WD */
@@ -228,6 +232,10 @@ extern const device_t nec_mate_unk_device;
extern const device_t phoenix_486_jumper_device;
extern const device_t phoenix_486_jumper_pci_device;
extern const device_t phoenix_486_jumper_pci_pb600_device;
extern const device_t ast_readout_device;
extern const device_t ast_nvr_device;
extern const device_t radisys_config_device;

View File

@@ -76,6 +76,7 @@ extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B
extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */
extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */
extern const device_t ide_cmd640_pci_single_channel_sec_device; /* CMD PCI-640B PCI (Only secondary channel) */
extern const device_t ide_cmd640_pci_single_channel_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only/Only primary channel) */
extern const device_t ide_cmd646_device; /* CMD PCI-646 */
extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */
extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */
@@ -89,6 +90,7 @@ extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/6
extern const device_t ide_rz1000_pci_device; /* PC Technology RZ-1000 PCI */
extern const device_t ide_rz1000_pci_single_channel_device; /* PC Technology RZ-1000 PCI (Only primary channel) */
extern const device_t ide_rz1001_pci_device; /* PC Technology RZ-1001 PCI */
extern const device_t ide_um8673f_device; /* UMC UM8673F */
extern const device_t ide_um8886af_device; /* UMC UM8886AF */

View File

@@ -301,6 +301,8 @@ enum {
MACHINE_CHIPSET_VLSI_VL82C480,
MACHINE_CHIPSET_VLSI_VL82C481,
MACHINE_CHIPSET_VLSI_VL82C486,
MACHINE_CHIPSET_VLSI_SUPERCORE,
MACHINE_CHIPSET_VLSI_WILDCAT,
MACHINE_CHIPSET_WD76C10,
MACHINE_CHIPSET_ZYMOS_POACH,
MACHINE_CHIPSET_MAX
@@ -890,6 +892,9 @@ extern int machine_at_ecs50x_init(const machine_t *);
/* OPTi 597 */
extern int machine_at_pci56001_init(const machine_t *);
/* VLSI SuperCore */
extern int machine_at_celebris5xx_init(const machine_t *);
/* m_at_socket5.c */
/* i430NX */
extern int machine_at_p54np4_init(const machine_t *);
@@ -930,6 +935,15 @@ extern int machine_at_torino_init(const machine_t *);
/* UMC 889x */
extern int machine_at_hot539_init(const machine_t *);
/* VLSI SuperCore */
extern int machine_at_bravoms586_init(const machine_t *);
extern int machine_at_g586vpmc_init(const machine_t *);
extern int machine_at_m54si_init(const machine_t *);
extern int machine_at_pb600_init(const machine_t *);
/* VLSI Wildcat */
extern int machine_at_globalyst620_init(const machine_t *);
/* m_at_socket7_3v.c */
/* i430FX */
#ifdef EMU_DEVICE_H
@@ -976,6 +990,9 @@ extern int machine_at_ap5s_init(const machine_t *);
extern int machine_at_pc140_6260_init(const machine_t *);
extern int machine_at_ms5124_init(const machine_t *);
/* VLSI Wildcat */
extern int machine_at_zeoswildcat_init(const machine_t *);
/* m_at_socket7.c */
/* i430HX */
extern int machine_at_acerm3a_init(const machine_t *);

View File

@@ -70,3 +70,35 @@ machine_at_pci56001_init(const machine_t *model)
return ret;
}
/* VLSI SuperCore */
int
machine_at_celebris5xx_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/celebris5xx/CELEBRIS.ROM",
0x000e0000, 131072, 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_IDE, 4, 1, 2, 3); /* Onboard */
pci_register_slot(0x09, PCI_CARD_VIDEO, 4, 1, 2, 3); /* Onboard */
pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 3, 2, 1); /* Slot 01 */
pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 1, 3, 2); /* Slot 02 */
device_add(&vl82c59x_device);
device_add(&intel_flash_bxt_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&ide_cmd640_pci_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
}

View File

@@ -765,3 +765,165 @@ machine_at_hot539_init(const machine_t *model)
return ret;
}
/* VLSI SuperCore */
int
machine_at_bravoms586_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/bravoms586/asttest.bin",
0x000e0000, 131072, 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_IDE, 2, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&vl82c59x_device);
device_add(&intel_flash_bxt_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&ide_cmd640_pci_single_channel_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
device_add(&ast_readout_device); /* AST custom jumper readout */
device_add(&ast_nvr_device); /* AST custom secondary NVR device */
return ret;
}
int
machine_at_g586vpmc_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/g586vpmc/Vpm_c3.bin",
0x000e0000, 131072, 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x02, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x08, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_IDE, 0, 0, 0, 0);
device_add(&vl82c59x_device);
device_add(&sst_flash_29ee010_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_398));
device_add(&ide_cmd646_device);
return ret;
}
int
machine_at_m54si_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/m54si/M54SI.03",
0x000e0000, 131072, 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_IDE, 0, 0, 0, 0); /* Onboard device */
pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
/* Slots are a guess since this BIOS won't work with pcireg */
device_add(&vl82c59x_device);
device_add(&intel_flash_bxt_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&ide_cmd640_pci_single_channel_device);
return ret;
}
int
machine_at_pb600_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/pb600/BIOS.ROM",
0x000e0000, 131072, 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(0x06, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0A, PCI_CARD_VIDEO, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_IDE, 4, 0, 0, 0);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
device_add(&vl82c59x_device);
device_add(&intel_flash_bxt_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&phoenix_486_jumper_pci_pb600_device);
device_add(&ide_cmd640_pci_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
return ret;
}
/* VLSI Wildcat */
int
machine_at_globalyst620_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/globalyst620/p107.bin",
0x000e0000, 131072, 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0F, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard device */
pci_register_slot(0x10, PCI_CARD_IDE, 0, 0, 0, 0); /* Onboard device */
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Slot 04 */
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); /* Slot 05 */
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); /* Slot 06 */
device_add(&vl82c59x_wildcat_device);
device_add(&intel_flash_bxt_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add(&ide_cmd640_pci_single_channel_legacy_only_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
return ret;
}

View File

@@ -1020,3 +1020,36 @@ machine_at_ms5124_init(const machine_t *model)
return ret;
}
/* VLSI Wildcat */
int
machine_at_zeoswildcat_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/zeoswildcat/003606.BIN",
0x000e0000, 131072, 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_IDE, 1, 2, 0, 0); /* Onboard device */
pci_register_slot(0x0E, PCI_CARD_SCSI, 1, 0, 0, 0); /* Onboard device */
pci_register_slot(0x0F, PCI_CARD_NETWORK, 1, 0, 0, 0); /* Onboard device */
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Slot 03 */
pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 2, 3, 1); /* Slot 04 */
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); /* Slot 05 */
/* Per the machine's manual there was an option for AMD SCSI and/or LAN controllers */
device_add(&vl82c59x_wildcat_device);
device_add(&intel_flash_bxt_device);
device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&ide_rz1001_pci_device);
return ret;
}

View File

@@ -163,6 +163,8 @@ const machine_filter_t machine_chipsets[] = {
{ "VLSI VL82C480", MACHINE_CHIPSET_VLSI_VL82C480 },
{ "VLSI VL82C481", MACHINE_CHIPSET_VLSI_VL82C481 },
{ "VLSI VL82C486", MACHINE_CHIPSET_VLSI_VL82C486 },
{ "VLSI SuperCore", MACHINE_CHIPSET_VLSI_SUPERCORE },
{ "VLSI Wildcat", MACHINE_CHIPSET_VLSI_WILDCAT },
{ "WD76C10", MACHINE_CHIPSET_WD76C10 }
};
@@ -11939,6 +11941,51 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* VLSI SuperCore */
/* This has Phoenix KBC firmware. */
{
.name = "[VLSI SuperCore] DEC Celebris 5xx",
.internal_name = "celebris5xx",
.type = MACHINE_TYPE_SOCKET4_5,
.chipset = MACHINE_CHIPSET_VLSI_SUPERCORE,
.init = machine_at_celebris5xx_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET4 | CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK(CPU_Cx6x86),
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 5000,
.min_multi = 1.0,
.max_multi = 2.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO,
.ram = {
.min = 4096,
.max = 131072,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_3,
.default_jumpered_ecp_dma = 3,
.kbc_device = &kbc_at_device,
.kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */
.kbc_p1 = 0x00000cf0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &s3_phoenix_vision864_pci_device,
.snd_device = NULL,
.net_device = NULL
},
/* Socket 5 machines */
/* 430NX */
@@ -12879,6 +12926,232 @@ const machine_t machines[] = {
.net_device = NULL
},
/* VLSI SuperCore */
/* This has AST KBC firmware, likely a Phoenix variant since the BIOS */
/* calls KBC command D5h to read the KBC revision. */
{
.name = "[VLSI SuperCore] AST Bravo MS P/90",
.internal_name = "bravoms586",
.type = MACHINE_TYPE_SOCKET5,
.chipset = MACHINE_CHIPSET_VLSI_SUPERCORE,
.init = machine_at_bravoms586_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK(CPU_Cx6x86),
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 2.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO,
.ram = {
.min = 4096,
.max = 131072,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_USE_CONFIG,
.default_jumpered_ecp_dma = -1,
.kbc_device = &kbc_at_device,
.kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */
.kbc_p1 = 0x00000cf0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &gd5434_onboard_pci_device,
.snd_device = NULL,
.net_device = NULL
},
/* Has a VIA KBC chip */
{
.name = "[VLSI SuperCore] DFI G586VPM Rev C",
.internal_name = "g586vpmc",
.type = MACHINE_TYPE_SOCKET5,
.chipset = MACHINE_CHIPSET_VLSI_SUPERCORE,
.init = machine_at_g586vpmc_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK_NONE,
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 2.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 4096,
.max = 262144,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_1 | MACHINE_DMA_3,
.default_jumpered_ecp_dma = 1,
.kbc_device = &kbc_at_device,
.kbc_params = KBC_VEN_VIA | 0x00424600, /* Guess */
.kbc_p1 = 0x00000cf0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* KBC firmware is unknown. No commands outside of the base PS/2 */
/* KBC command set are used. */
{
.name = "[VLSI SuperCore] Micronics M54Si",
.internal_name = "m54si",
.type = MACHINE_TYPE_SOCKET5,
.chipset = MACHINE_CHIPSET_VLSI_SUPERCORE,
.init = machine_at_m54si_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK(CPU_Cx6x86),
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 2.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 4096,
.max = 131072,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3,
.default_jumpered_ecp_dma = 4,
.kbc_device = &kbc_at_device,
.kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */
.kbc_p1 = 0x00000cf0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* This has Phoenix KBC firmware. */
{
.name = "[VLSI SuperCore] Packard Bell PB600",
.internal_name = "pb600",
.type = MACHINE_TYPE_SOCKET5,
.chipset = MACHINE_CHIPSET_VLSI_SUPERCORE,
.init = machine_at_pb600_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK_NONE,
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 2.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO,
.ram = {
.min = 8192,
.max = 139264,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_1 | MACHINE_DMA_3,
.default_jumpered_ecp_dma = 3,
.kbc_device = &kbc_at_device,
.kbc_params = KBC_VEN_PHOENIX | 0x00012900, /* Guess */
.kbc_p1 = 0x00000cf0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &gd5430_onboard_pci_device,
.snd_device = NULL,
.net_device = NULL
},
/* VLSI Wildcat */
/* This has Phoenix KBC firmware. */
{
.name = "[VLSI Wildcat] AT&T Globalyst 620/630 (NCR 3248/3348)",
.internal_name = "globalyst620",
.type = MACHINE_TYPE_SOCKET5,
.chipset = MACHINE_CHIPSET_VLSI_WILDCAT,
.init = machine_at_globalyst620_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK(CPU_Cx6x86),
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 2.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO,
.ram = {
.min = 4096,
.max = 196608,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_3,
.default_jumpered_ecp_dma = 3,
.kbc_device = &kbc_at_device,
.kbc_params = KBC_VEN_PHOENIX | 0x00012900, /* Guess */
.kbc_p1 = 0x00000cf0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &s3_phoenix_trio64_onboard_pci_device,
.snd_device = NULL,
.net_device = NULL
},
/* Socket 7 (Single Voltage) machines */
/* 430FX */
/* This has an AMIKey-2, which is type 'H'.
@@ -13736,6 +14009,53 @@ const machine_t machines[] = {
.net_device = NULL
},
/* VLSI Wildcat */
/* KBC firmware is unknown. No PS/2 port is present and no commands outside */
/* of the base AT KBC command set are used. */
{
.name = "[VLSI Wildcat] Zeos Pantera Wildcat",
.internal_name = "zeoswildcat",
.type = MACHINE_TYPE_SOCKET7_3V,
.chipset = MACHINE_CHIPSET_VLSI_WILDCAT,
.init = machine_at_zeoswildcat_init,
.p1_handler = machine_generic_p1_handler,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK(CPU_Cx6x86, CPU_PENTIUMMMX),
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 2.5
},
.bus_flags = MACHINE_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 4096,
.max = 393216,
.step = 4096
},
.nvrmask = 127,
.jumpered_ecp_dma = MACHINE_DMA_3,
.default_jumpered_ecp_dma = 3,
.kbc_device = &kbc_at_device,
.kbc_params = 0x00000000,
.kbc_p1 = 0x000004f0,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Socket 7 (Dual Voltage) machines */
/* ALi ALADDiN IV+ */
/* Has the ALi M1543 southbridge with on-chip KBC. */