mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
Merge branch 'master' into feature/configurable_fdd_sound_emulation_timings
This commit is contained in:
@@ -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
644
src/chipset/vl82c59x.c
Normal 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[0], 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x64] & 0xAA, dev->pci_conf[0x64] & 0x55);
|
||||
}
|
||||
if (dev->pci_conf[0x65] & 0x55) {
|
||||
smram_enable(dev->smram[1], 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[2], 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x0A, dev->pci_conf[0x68] & 0x05);
|
||||
}
|
||||
if (dev->pci_conf[0x68] & 0x50) {
|
||||
smram_enable(dev->smram[3], 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[0]);
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[2]);
|
||||
smram_del(dev->smram[3]);
|
||||
|
||||
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[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
dev->smram[2] = smram_add();
|
||||
dev->smram[3] = 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
|
||||
};
|
||||
@@ -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
180
src/device/ast_nvr.c
Normal 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
198
src/device/ast_readout.c
Normal 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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -810,7 +810,7 @@ ide_set_signature(ide_t *ide)
|
||||
ide->tf->sector = 1;
|
||||
ide->tf->head = 0;
|
||||
ide->tf->secount = 1;
|
||||
ide->tf->cylinder = (ide->type == IDE_ATAPI_SHADOW) ? 0x0000 : ide_signatures[ide->type & ~IDE_SHADOW];
|
||||
ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW];
|
||||
|
||||
if (ide->type == IDE_HDD)
|
||||
ide->drive = 0;
|
||||
@@ -1579,7 +1579,7 @@ ide_reset_registers(ide_t *ide)
|
||||
ide->tf->atastat = DRDY_STAT | DSC_STAT;
|
||||
ide->tf->error = 1;
|
||||
ide->tf->secount = 1;
|
||||
ide->tf->cylinder = (ide->type == IDE_ATAPI_SHADOW) ? 0x0000 : ide_signatures[ide->type & ~IDE_SHADOW];
|
||||
ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW];
|
||||
ide->tf->sector = 1;
|
||||
ide->tf->head = 0;
|
||||
|
||||
@@ -2098,6 +2098,8 @@ ide_readb(uint16_t addr, void *priv)
|
||||
case 0x4: /* Cylinder low */
|
||||
if (ide->type == IDE_NONE)
|
||||
ret = 0x7f;
|
||||
else if (ide->type == IDE_ATAPI_SHADOW)
|
||||
ret = 0x00;
|
||||
else
|
||||
ret = ide->tf->cylinder & 0xff;
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
@@ -2109,6 +2111,8 @@ ide_readb(uint16_t addr, void *priv)
|
||||
case 0x5: /* Cylinder high */
|
||||
if (ide->type == IDE_NONE)
|
||||
ret = 0x7f;
|
||||
else if (ide->type == IDE_ATAPI_SHADOW)
|
||||
ret = 0x00;
|
||||
else
|
||||
ret = ide->tf->cylinder >> 8;
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -1940,6 +1940,16 @@ fdc_callback(void *priv)
|
||||
case 0x0f: /*Seek*/
|
||||
fdc->st0 = 0x20 | (fdc->params[0] & 3);
|
||||
fdc->stat = 0x10 | (1 << fdc->rw_drive);
|
||||
if (fdd_get_turbo(1 << fdc->rw_drive)) {
|
||||
if (fdc->flags & FDC_FLAG_PCJR) {
|
||||
fdc->fintr = 1;
|
||||
fdc->interrupt = -4;
|
||||
timer_set_delay_u64(&fdc->timer, 1024 * TIMER_USEC);
|
||||
} else {
|
||||
fdc->interrupt = -3;
|
||||
fdc_callback(fdc);
|
||||
}
|
||||
}
|
||||
// Interrupts and callbacks in the fdd callback function
|
||||
return;
|
||||
case 0x10: /*Version*/
|
||||
|
||||
@@ -385,31 +385,35 @@ fdd_seek(int drive, int track_diff)
|
||||
|
||||
fdd_changed[drive] = 0;
|
||||
|
||||
/* Trigger appropriate audio for track movements */
|
||||
int actual_track_diff = abs(old_track - fdd[drive].track);
|
||||
if (actual_track_diff == 1) {
|
||||
/* Single track movement */
|
||||
fdd_audio_play_single_track_step(drive, old_track, fdd[drive].track);
|
||||
} else if (actual_track_diff > 1) {
|
||||
/* Multi-track seek */
|
||||
fdd_audio_play_multi_track_seek(drive, old_track, fdd[drive].track);
|
||||
}
|
||||
|
||||
if (old_track + track_diff < 0) {
|
||||
if (fdd[drive].turbo)
|
||||
fdd_do_seek(drive, fdd[drive].track);
|
||||
return;
|
||||
else {
|
||||
/* Trigger appropriate audio for track movements */
|
||||
int actual_track_diff = abs(old_track - fdd[drive].track);
|
||||
if (actual_track_diff == 1) {
|
||||
/* Single track movement */
|
||||
fdd_audio_play_single_track_step(drive, old_track, fdd[drive].track);
|
||||
} else if (actual_track_diff > 1) {
|
||||
/* Multi-track seek */
|
||||
fdd_audio_play_multi_track_seek(drive, old_track, fdd[drive].track);
|
||||
}
|
||||
|
||||
if (old_track + track_diff < 0) {
|
||||
fdd_do_seek(drive, fdd[drive].track);
|
||||
return;
|
||||
}
|
||||
|
||||
fdd_seek_in_progress[drive] = 1;
|
||||
|
||||
if (!fdd_seek_timer[drive].callback) {
|
||||
timer_add(&(fdd_seek_timer[drive]), fdd_seek_complete_callback, &drives[drive], 0);
|
||||
}
|
||||
|
||||
double initial_seek_time = FDC_FLAG_PCJR & fdd_fdc->flags ? 40000.0 : 15000.0;
|
||||
double track_seek_time = FDC_FLAG_PCJR & fdd_fdc->flags ? 10000.0 : 6000.0;
|
||||
uint64_t seek_time_us = (initial_seek_time + (abs(actual_track_diff) * track_seek_time)) * TIMER_USEC;
|
||||
timer_set_delay_u64(&fdd_seek_timer[drive], seek_time_us);
|
||||
}
|
||||
|
||||
fdd_seek_in_progress[drive] = 1;
|
||||
|
||||
if (!fdd_seek_timer[drive].callback) {
|
||||
timer_add(&(fdd_seek_timer[drive]), fdd_seek_complete_callback, &drives[drive], 0);
|
||||
}
|
||||
|
||||
double initial_seek_time = FDC_FLAG_PCJR & fdd_fdc->flags ? 40000.0 : 15000.0;
|
||||
double track_seek_time = FDC_FLAG_PCJR & fdd_fdc->flags ? 10000.0 : 6000.0;
|
||||
uint64_t seek_time_us = (initial_seek_time + (abs(actual_track_diff) * track_seek_time)) * TIMER_USEC;
|
||||
timer_set_delay_u64(&fdd_seek_timer[drive], seek_time_us);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -387,7 +387,7 @@ fdd_audio_close(void)
|
||||
void
|
||||
fdd_audio_set_motor_enable(int drive, int motor_enable)
|
||||
{
|
||||
if (!fdd_sounds_enabled)
|
||||
if (!fdd_sounds_enabled || fdd_get_turbo(drive))
|
||||
return;
|
||||
|
||||
drive_audio_samples_t *samples = get_drive_samples(drive);
|
||||
@@ -421,7 +421,7 @@ fdd_audio_set_motor_enable(int drive, int motor_enable)
|
||||
void
|
||||
fdd_audio_play_single_track_step(int drive, int from_track, int to_track)
|
||||
{
|
||||
if (!fdd_sounds_enabled)
|
||||
if (!fdd_sounds_enabled || fdd_get_turbo(drive))
|
||||
return;
|
||||
|
||||
if (drive < 0 || drive >= FDD_NUM)
|
||||
@@ -436,7 +436,7 @@ fdd_audio_play_single_track_step(int drive, int from_track, int to_track)
|
||||
void
|
||||
fdd_audio_play_multi_track_seek(int drive, int from_track, int to_track)
|
||||
{
|
||||
if (!fdd_sounds_enabled)
|
||||
if (!fdd_sounds_enabled || fdd_get_turbo(drive))
|
||||
return;
|
||||
|
||||
if (drive < 0 || drive >= FDD_NUM)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/* fc=150Hz */
|
||||
static inline float
|
||||
adgold_highpass_iir(int c, int i, float NewSample)
|
||||
adgold_highpass_iir(int i, float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.98657437157334349000,
|
||||
@@ -19,76 +19,6 @@ adgold_highpass_iir(int c, int i, float NewSample)
|
||||
0.97261396931534050000
|
||||
};
|
||||
|
||||
static float y[2][2][NCoef + 1]; /* output samples */
|
||||
static float x[2][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for (n = NCoef; n > 0; n--) {
|
||||
x[c][i][n] = x[c][i][n - 1];
|
||||
y[c][i][n] = y[c][i][n - 1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[c][i][0] = NewSample;
|
||||
y[c][i][0] = ACoef[0] * x[c][i][0];
|
||||
for (n = 1; n <= NCoef; n++)
|
||||
y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n];
|
||||
|
||||
return y[c][i][0];
|
||||
}
|
||||
|
||||
/* fc=150Hz */
|
||||
static inline float
|
||||
adgold_lowpass_iir(int c, int i, float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.00009159473951071446,
|
||||
0.00018318947902142891,
|
||||
0.00009159473951071446
|
||||
};
|
||||
|
||||
float BCoef[NCoef + 1] = {
|
||||
1.00000000000000000000,
|
||||
-1.97223372919526560000,
|
||||
0.97261396931306277000
|
||||
};
|
||||
|
||||
static float y[2][2][NCoef + 1]; /* output samples */
|
||||
static float x[2][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for (n = NCoef; n > 0; n--) {
|
||||
x[c][i][n] = x[c][i][n - 1];
|
||||
y[c][i][n] = y[c][i][n - 1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[c][i][0] = NewSample;
|
||||
y[c][i][0] = ACoef[0] * x[c][i][0];
|
||||
for (n = 1; n <= NCoef; n++)
|
||||
y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n];
|
||||
|
||||
return y[c][i][0];
|
||||
}
|
||||
|
||||
/* fc=56Hz */
|
||||
static inline float
|
||||
adgold_pseudo_stereo_iir(int i, float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.00001409030866231767,
|
||||
0.00002818061732463533,
|
||||
0.00001409030866231767
|
||||
};
|
||||
|
||||
float BCoef[NCoef + 1] = {
|
||||
1.00000000000000000000,
|
||||
-1.98733021473466760000,
|
||||
0.98738361004063568000
|
||||
};
|
||||
|
||||
static float y[2][NCoef + 1]; /* output samples */
|
||||
static float x[2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
@@ -108,6 +38,76 @@ adgold_pseudo_stereo_iir(int i, float NewSample)
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
/* fc=150Hz */
|
||||
static inline float
|
||||
adgold_lowpass_iir(int i, float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.00009159473951071446,
|
||||
0.00018318947902142891,
|
||||
0.00009159473951071446
|
||||
};
|
||||
|
||||
float BCoef[NCoef + 1] = {
|
||||
1.00000000000000000000,
|
||||
-1.97223372919526560000,
|
||||
0.97261396931306277000
|
||||
};
|
||||
|
||||
static float y[2][NCoef + 1]; /* output samples */
|
||||
static float x[2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for (n = NCoef; n > 0; n--) {
|
||||
x[i][n] = x[i][n - 1];
|
||||
y[i][n] = y[i][n - 1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[i][0] = NewSample;
|
||||
y[i][0] = ACoef[0] * x[i][0];
|
||||
for (n = 1; n <= NCoef; n++)
|
||||
y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n];
|
||||
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
/* fc=56Hz */
|
||||
static inline float
|
||||
adgold_pseudo_stereo_iir(float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.00001409030866231767,
|
||||
0.00002818061732463533,
|
||||
0.00001409030866231767
|
||||
};
|
||||
|
||||
float BCoef[NCoef + 1] = {
|
||||
1.00000000000000000000,
|
||||
-1.98733021473466760000,
|
||||
0.98738361004063568000
|
||||
};
|
||||
|
||||
static float y[NCoef + 1]; /* output samples */
|
||||
static float x[NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for (n = NCoef; n > 0; n--) {
|
||||
x[n] = x[n - 1];
|
||||
y[n] = y[n - 1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[0] = NewSample;
|
||||
y[0] = ACoef[0] * x[0];
|
||||
for (n = 1; n <= NCoef; n++)
|
||||
y[0] += ACoef[n] * x[n] - BCoef[n] * y[n];
|
||||
|
||||
return y[0];
|
||||
}
|
||||
|
||||
/* fc=3.2kHz - probably incorrect */
|
||||
static inline float
|
||||
dss_iir(float NewSample)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -66,10 +66,10 @@ typedef struct ad1848_t {
|
||||
uint8_t enable : 1;
|
||||
uint8_t irq : 4;
|
||||
uint8_t dma : 3;
|
||||
uint8_t adpcm_ref;
|
||||
int8_t adpcm_step;
|
||||
int adpcm_predictor[2];
|
||||
int16_t adpcm_step_index[2];
|
||||
int freq;
|
||||
int adpcm_data;
|
||||
uint8_t adpcm_data;
|
||||
int adpcm_pos;
|
||||
|
||||
uint8_t dma_ff;
|
||||
|
||||
@@ -49,6 +49,9 @@ enum fm_type {
|
||||
FM_MAX = 26
|
||||
};
|
||||
|
||||
#define FM_TYPE_MASK 255
|
||||
#define FM_FORCE_48K 256
|
||||
|
||||
enum fm_driver {
|
||||
FM_DRV_NUKED = 0,
|
||||
FM_DRV_YMFM = 1,
|
||||
@@ -65,9 +68,11 @@ typedef struct fm_drv_t {
|
||||
void (*generate)(void *priv, int32_t *data, uint32_t num_samples); /* daughterboard only. */
|
||||
} fm_drv_t;
|
||||
|
||||
extern uint8_t fm_driver_get_ex(int chip_id, fm_drv_t *drv, int is_48k);
|
||||
extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv);
|
||||
|
||||
extern const fm_drv_t nuked_opl_drv;
|
||||
extern const fm_drv_t nuked_opl_drv_48k;
|
||||
extern const fm_drv_t ymfm_drv;
|
||||
extern const fm_drv_t esfmu_opl_drv;
|
||||
extern const fm_drv_t ymfm_opl2board_drv;
|
||||
|
||||
@@ -147,7 +147,7 @@ struct _opl3_chip {
|
||||
typedef struct {
|
||||
opl3_chip opl;
|
||||
int8_t flags;
|
||||
int8_t pad;
|
||||
int8_t is_48k;
|
||||
|
||||
uint16_t port;
|
||||
uint8_t status;
|
||||
@@ -159,6 +159,8 @@ typedef struct {
|
||||
|
||||
int pos;
|
||||
int32_t buffer[MUSICBUFLEN * 2];
|
||||
|
||||
int32_t *(*update)(void *priv);
|
||||
} nuked_drv_t;
|
||||
|
||||
enum {
|
||||
|
||||
@@ -19,18 +19,18 @@ typedef struct ym7128_t {
|
||||
int c1;
|
||||
int t[9];
|
||||
|
||||
int16_t filter_dat[2];
|
||||
int16_t prev_l[2];
|
||||
int16_t prev_r[2];
|
||||
int16_t filter_dat;
|
||||
int16_t prev_l;
|
||||
int16_t prev_r;
|
||||
|
||||
int16_t delay_buffer[2][2400];
|
||||
int delay_pos[2];
|
||||
int16_t delay_buffer[2400];
|
||||
int delay_pos;
|
||||
|
||||
int16_t last_samp;
|
||||
} ym7128_t;
|
||||
|
||||
void ym7128_init(ym7128_t *ym7128);
|
||||
void ym7128_write(ym7128_t *ym7128, uint8_t val);
|
||||
void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len);
|
||||
void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len);
|
||||
|
||||
#endif /*SOUND_YM7128_H*/
|
||||
|
||||
@@ -70,3 +70,36 @@ 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));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -56,9 +56,22 @@ ad1848_log(const char *fmt, ...)
|
||||
static int ad1848_vols_7bits[128];
|
||||
static double ad1848_vols_5bits_aux_gain[32];
|
||||
|
||||
/* Borrowed from snd_sb_dsp */
|
||||
extern int8_t scaleMap4[64];
|
||||
extern uint8_t adjustMap4[64];
|
||||
/* Borrowed from ffmpeg. */
|
||||
static const int8_t adpcm_index_table[16] = {
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
-1, -1, -1, -1, 2, 4, 6, 8
|
||||
};
|
||||
static const int16_t adpcm_step_table[89] = {
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
|
||||
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
|
||||
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
|
||||
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
|
||||
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
|
||||
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
|
||||
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
|
||||
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
|
||||
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
|
||||
};
|
||||
|
||||
void
|
||||
ad1848_setirq(ad1848_t *ad1848, int irq)
|
||||
@@ -311,6 +324,8 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 9:
|
||||
if (!ad1848->enable && (val & 0x41) == 0x01) {
|
||||
ad1848->adpcm_pos = 0;
|
||||
ad1848->adpcm_predictor[0] = ad1848->adpcm_predictor[1] = 0;
|
||||
ad1848->adpcm_step_index[0] = ad1848->adpcm_step_index[1] = 0;
|
||||
ad1848->dma_ff = 0;
|
||||
if (ad1848->timer_latch)
|
||||
timer_set_delay_u64(&ad1848->timer_count, ad1848->timer_latch);
|
||||
@@ -358,6 +373,11 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 17:
|
||||
if (val & 0x08)
|
||||
ad1848->adpcm_predictor[0] = ad1848->adpcm_predictor[1] = 0;
|
||||
break;
|
||||
|
||||
case 18 ... 19:
|
||||
if (ad1848->type >= AD1848_TYPE_CS4236B) {
|
||||
if (ad1848->type >= AD1848_TYPE_CS4235) {
|
||||
@@ -622,29 +642,33 @@ ad1848_dma_channel_read(ad1848_t *ad1848, int channel)
|
||||
}
|
||||
|
||||
static int16_t
|
||||
ad1848_process_adpcm(ad1848_t *ad1848)
|
||||
ad1848_process_adpcm(ad1848_t *ad1848, int channel)
|
||||
{
|
||||
int temp;
|
||||
if (ad1848->adpcm_pos++ & 1) {
|
||||
temp = (ad1848->adpcm_data & 0x0f) + ad1848->adpcm_step;
|
||||
temp = ad1848->adpcm_data >> 4;
|
||||
} else {
|
||||
ad1848->adpcm_data = (int) (ad1848_dma_channel_read(ad1848, ad1848->dma) & 0xffff);
|
||||
temp = (ad1848->adpcm_data >> 4) + ad1848->adpcm_step;
|
||||
ad1848->adpcm_data = ad1848_dma_channel_read(ad1848, ad1848->dma);
|
||||
temp = ad1848->adpcm_data & 0x0f;
|
||||
}
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
else if (temp > 63)
|
||||
temp = 63;
|
||||
|
||||
ad1848->adpcm_ref += scaleMap4[temp];
|
||||
if (ad1848->adpcm_ref > 0xff)
|
||||
ad1848->adpcm_ref = 0xff;
|
||||
else if (ad1848->adpcm_ref < 0x00)
|
||||
ad1848->adpcm_ref = 0x00;
|
||||
int step = adpcm_step_table[ad1848->adpcm_step_index[channel]];
|
||||
int step_index = ad1848->adpcm_step_index[channel] + adpcm_index_table[temp];
|
||||
if (step_index < 0)
|
||||
step_index = 0;
|
||||
else if (step_index > 88)
|
||||
step_index = 88;
|
||||
|
||||
ad1848->adpcm_step = (int8_t) ((ad1848->adpcm_step + adjustMap4[temp]) & 0xff);
|
||||
int diff = ((2 * (temp & 7) + 1) * step) >> 3;
|
||||
int predictor = ad1848->adpcm_predictor[channel] + ((temp & 8) ? -diff : diff);
|
||||
if (predictor < -32768)
|
||||
predictor = -32768;
|
||||
else if (predictor > 32767)
|
||||
predictor = 32767;
|
||||
ad1848->adpcm_predictor[channel] = predictor;
|
||||
ad1848->adpcm_step_index[channel] = step_index;
|
||||
|
||||
return (int16_t) ((ad1848->adpcm_ref ^ 0x80) << 8);
|
||||
return (int16_t) predictor;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -705,12 +729,12 @@ ad1848_poll(void *priv)
|
||||
/* 0x80 and 0x90 reserved */
|
||||
|
||||
case 0xa0: /* Mono, 4-bit ADPCM */
|
||||
ad1848->out_l = ad1848->out_r = ad1848_process_adpcm(ad1848);
|
||||
ad1848->out_l = ad1848->out_r = ad1848_process_adpcm(ad1848, 0);
|
||||
break;
|
||||
|
||||
case 0xb0: /* Stereo, 4-bit ADPCM */
|
||||
ad1848->out_l = ad1848_process_adpcm(ad1848);
|
||||
ad1848->out_r = ad1848_process_adpcm(ad1848);
|
||||
ad1848->out_l = ad1848_process_adpcm(ad1848, 0);
|
||||
ad1848->out_r = ad1848_process_adpcm(ad1848, 1);
|
||||
break;
|
||||
|
||||
case 0xc0: /* Mono, 16-bit PCM big endian */
|
||||
|
||||
@@ -82,8 +82,6 @@ typedef struct adgold_t {
|
||||
int treble;
|
||||
int bass;
|
||||
|
||||
int16_t samp_buffer[SOUNDBUFLEN * 2];
|
||||
int16_t opl_buffer[MUSICBUFLEN * 2];
|
||||
int16_t mma_buffer[2][SOUNDBUFLEN];
|
||||
|
||||
int pos;
|
||||
@@ -779,30 +777,37 @@ static void
|
||||
adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
adgold_t *adgold = (adgold_t *) priv;
|
||||
int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2);
|
||||
if (adgold_buffer == NULL)
|
||||
fatal("adgold_buffer = NULL");
|
||||
|
||||
int c;
|
||||
|
||||
int32_t *opl_buf = adgold->opl.update(adgold->opl.priv);
|
||||
adgold_update(adgold);
|
||||
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
adgold->samp_buffer[c] = ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4;
|
||||
adgold->samp_buffer[c + 1] = ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4;
|
||||
adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2;
|
||||
adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4;
|
||||
adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2;
|
||||
adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4;
|
||||
}
|
||||
|
||||
if (adgold->surround_enabled)
|
||||
ym7128_apply(&adgold->ym7128, adgold->samp_buffer, 0, len);
|
||||
ym7128_apply(&adgold->ym7128, adgold_buffer, len);
|
||||
|
||||
switch (adgold->adgold_38x_regs[0x8] & 6) {
|
||||
case 0:
|
||||
for (c = 0; c < len * 2; c++)
|
||||
adgold->samp_buffer[c] = 0;
|
||||
adgold_buffer[c] = 0;
|
||||
break;
|
||||
case 2: /*Left channel only*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->samp_buffer[c + 1] = adgold->samp_buffer[c];
|
||||
adgold_buffer[c + 1] = adgold_buffer[c];
|
||||
break;
|
||||
case 4: /*Right channel only*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->samp_buffer[c] = adgold->samp_buffer[c + 1];
|
||||
adgold_buffer[c] = adgold_buffer[c + 1];
|
||||
break;
|
||||
case 6: /*Left and right channels*/
|
||||
break;
|
||||
@@ -814,7 +819,7 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
switch (adgold->adgold_38x_regs[0x8] & 0x18) {
|
||||
case 0x00: /*Forced mono*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->samp_buffer[c] = adgold->samp_buffer[c + 1] = ((int32_t) adgold->samp_buffer[c] + (int32_t) adgold->samp_buffer[c + 1]) / 2;
|
||||
adgold_buffer[c] = adgold_buffer[c + 1] = ((int32_t) adgold_buffer[c] + (int32_t) adgold_buffer[c + 1]) / 2;
|
||||
break;
|
||||
case 0x08: /*Linear stereo*/
|
||||
break;
|
||||
@@ -822,17 +827,17 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
/*Filter left channel, leave right channel unchanged*/
|
||||
/*Filter cutoff is largely a guess*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->samp_buffer[c] += adgold_pseudo_stereo_iir(0, adgold->samp_buffer[c]);
|
||||
adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]);
|
||||
break;
|
||||
case 0x18: /*Spatial stereo*/
|
||||
/*Quite probably wrong, I only have the diagram in the TDA8425 datasheet
|
||||
and a very vague understanding of how op-amps work to go on*/
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
int16_t l = adgold->samp_buffer[c];
|
||||
int16_t r = adgold->samp_buffer[c + 1];
|
||||
int16_t l = adgold_buffer[c];
|
||||
int16_t r = adgold_buffer[c + 1];
|
||||
|
||||
adgold->samp_buffer[c] += (r / 3) + ((l * 2) / 3);
|
||||
adgold->samp_buffer[c + 1] += (l / 3) + ((r * 2) / 3);
|
||||
adgold_buffer[c] += (r / 3) + ((l * 2) / 3);
|
||||
adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -846,9 +851,9 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
int32_t highpass;
|
||||
|
||||
/*Output is deliberately halved to avoid clipping*/
|
||||
temp = ((int32_t) adgold->samp_buffer[c] * adgold->vol_l) >> 17;
|
||||
lowpass = adgold_lowpass_iir(0, 0, temp);
|
||||
highpass = adgold_highpass_iir(0, 0, temp);
|
||||
temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17;
|
||||
lowpass = adgold_lowpass_iir(0, temp);
|
||||
highpass = adgold_highpass_iir(0, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
@@ -863,118 +868,9 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
temp = 32767;
|
||||
buffer[c] += temp;
|
||||
|
||||
temp = ((int32_t) adgold->samp_buffer[c + 1] * adgold->vol_r) >> 17;
|
||||
lowpass = adgold_lowpass_iir(0, 1, temp);
|
||||
highpass = adgold_highpass_iir(0, 1, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14);
|
||||
if (adgold->treble > 6)
|
||||
temp += (highpass * treble_attenuation[adgold->treble]) >> 14;
|
||||
else if (adgold->treble < 6)
|
||||
temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14);
|
||||
if (temp < -32768)
|
||||
temp = -32768;
|
||||
if (temp > 32767)
|
||||
temp = 32767;
|
||||
buffer[c + 1] += temp;
|
||||
}
|
||||
|
||||
adgold->pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
adgold_get_music_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
adgold_t *adgold = (adgold_t *) priv;
|
||||
int c;
|
||||
|
||||
const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv);
|
||||
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
adgold->opl_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2;
|
||||
adgold->opl_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2;
|
||||
}
|
||||
|
||||
if (adgold->surround_enabled)
|
||||
ym7128_apply(&adgold->ym7128, adgold->opl_buffer, 1, len);
|
||||
|
||||
switch (adgold->adgold_38x_regs[0x8] & 6) {
|
||||
case 0:
|
||||
for (c = 0; c < len * 2; c++)
|
||||
adgold->opl_buffer[c] = 0;
|
||||
break;
|
||||
case 2: /*Left channel only*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->opl_buffer[c + 1] = adgold->opl_buffer[c];
|
||||
break;
|
||||
case 4: /*Right channel only*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->opl_buffer[c] = adgold->opl_buffer[c + 1];
|
||||
break;
|
||||
case 6: /*Left and right channels*/
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (adgold->adgold_38x_regs[0x8] & 0x18) {
|
||||
case 0x00: /*Forced mono*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->opl_buffer[c] = adgold->opl_buffer[c + 1] = ((int32_t) adgold->opl_buffer[c] + (int32_t) adgold->opl_buffer[c + 1]) / 2;
|
||||
break;
|
||||
case 0x08: /*Linear stereo*/
|
||||
break;
|
||||
case 0x10: /*Pseudo stereo*/
|
||||
/*Filter left channel, leave right channel unchanged*/
|
||||
/*Filter cutoff is largely a guess*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold->opl_buffer[c] += adgold_pseudo_stereo_iir(1, adgold->opl_buffer[c]);
|
||||
break;
|
||||
case 0x18: /*Spatial stereo*/
|
||||
/*Quite probably wrong, I only have the diagram in the TDA8425 datasheet
|
||||
and a very vague understanding of how op-amps work to go on*/
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
int16_t l = adgold->opl_buffer[c];
|
||||
int16_t r = adgold->opl_buffer[c + 1];
|
||||
|
||||
adgold->opl_buffer[c] += (r / 3) + ((l * 2) / 3);
|
||||
adgold->opl_buffer[c + 1] += (l / 3) + ((r * 2) / 3);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
int32_t temp;
|
||||
int32_t lowpass;
|
||||
int32_t highpass;
|
||||
|
||||
/*Output is deliberately halved to avoid clipping*/
|
||||
temp = ((int32_t) adgold->opl_buffer[c] * adgold->vol_l) >> 17;
|
||||
lowpass = adgold_lowpass_iir(1, 0, temp);
|
||||
highpass = adgold_highpass_iir(1, 0, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14);
|
||||
if (adgold->treble > 6)
|
||||
temp += (highpass * treble_attenuation[adgold->treble]) >> 14;
|
||||
else if (adgold->treble < 6)
|
||||
temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14);
|
||||
if (temp < -32768)
|
||||
temp = -32768;
|
||||
if (temp > 32767)
|
||||
temp = 32767;
|
||||
buffer[c] += temp;
|
||||
|
||||
temp = ((int32_t) adgold->opl_buffer[c + 1] * adgold->vol_r) >> 17;
|
||||
lowpass = adgold_lowpass_iir(1, 1, temp);
|
||||
highpass = adgold_highpass_iir(1, 1, temp);
|
||||
temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17;
|
||||
lowpass = adgold_lowpass_iir(1, temp);
|
||||
highpass = adgold_highpass_iir(1, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
@@ -991,6 +887,9 @@ adgold_get_music_buffer(int32_t *buffer, int len, void *priv)
|
||||
}
|
||||
|
||||
adgold->opl.reset_buffer(adgold->opl.priv);
|
||||
adgold->pos = 0;
|
||||
|
||||
free(adgold_buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1058,7 +957,7 @@ adgold_init(UNUSED(const device_t *info))
|
||||
adgold->surround_enabled = device_get_config_int("surround");
|
||||
adgold->gameport_enabled = device_get_config_int("gameport");
|
||||
|
||||
fm_driver_get(FM_YMF289B, &adgold->opl);
|
||||
fm_driver_get_ex(FM_YMF262, &adgold->opl, 1);
|
||||
if (adgold->surround_enabled)
|
||||
ym7128_init(&adgold->ym7128);
|
||||
|
||||
@@ -1149,7 +1048,6 @@ adgold_init(UNUSED(const device_t *info))
|
||||
timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1);
|
||||
|
||||
sound_add_handler(adgold_get_buffer, adgold);
|
||||
music_add_handler(adgold_get_music_buffer, adgold);
|
||||
|
||||
sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold);
|
||||
|
||||
|
||||
@@ -36,150 +36,152 @@
|
||||
static uint32_t fm_dev_inst[FM_DRV_MAX][FM_MAX];
|
||||
|
||||
uint8_t
|
||||
fm_driver_get(int chip_id, fm_drv_t *drv)
|
||||
fm_driver_get_ex(int chip_id, fm_drv_t *drv, int is_48k)
|
||||
{
|
||||
void *flag_48k = is_48k ? ((void *) FM_FORCE_48K) : NULL;
|
||||
|
||||
switch (chip_id) {
|
||||
case FM_YM2149: /* SSG */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2149_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2149_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3526: /* OPL */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym3526_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym3526_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_Y8950: /* MSX-Audio (OPL with ADPCM) */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&y8950_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&y8950_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3812: /* OPL2 */
|
||||
if (fm_driver == FM_DRV_NUKED) {
|
||||
*drv = nuked_opl_drv;
|
||||
drv->priv = device_add_inst(&ym3812_nuked_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
*drv = is_48k ? nuked_opl_drv_48k : nuked_opl_drv;
|
||||
drv->priv = device_add_inst_params(&ym3812_nuked_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
} else {
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym3812_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym3812_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
}
|
||||
break;
|
||||
|
||||
case FM_YMF262: /* OPL3 */
|
||||
if (fm_driver == FM_DRV_NUKED) {
|
||||
*drv = nuked_opl_drv;
|
||||
drv->priv = device_add_inst(&ymf262_nuked_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
*drv = is_48k ? nuked_opl_drv_48k : nuked_opl_drv;
|
||||
drv->priv = device_add_inst_params(&ymf262_nuked_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
} else {
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf262_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf262_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
}
|
||||
break;
|
||||
|
||||
case FM_YMF289B: /* OPL3-L */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf289b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf289b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF278B: /* OPL4 */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2413: /* OPLL */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2413_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2413_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2423: /* OPLL-X */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2423_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2423_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF281: /* OPLLP */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf281_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf281_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_DS1001: /* Konami VRC7 MMC */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ds1001_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ds1001_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2151: /* OPM */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2151_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2151_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2203: /* OPN */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2203_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2203_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2608: /* OPNA */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2608_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2608_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF288: /* OPN3L */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf288_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf288_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2610: /* OPNB */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2610_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2610_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2610B: /* OPNB2 */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2610b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2610b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2612: /* OPN2 */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2612_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2612_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3438: /* OPN2C */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym3438_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym3438_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF276: /* OPN2L */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf276_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf276_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2164: /* OPP */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2164_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2164_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3806: /* OPQ */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym3806_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym3806_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case FM_YMF271: /* OPX */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ymf271_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ymf271_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FM_YM2414: /* OPZ */
|
||||
*drv = ymfm_drv;
|
||||
drv->priv = device_add_inst(&ym2414_ymfm_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym2414_ymfm_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
case FM_ESFM:
|
||||
*drv = esfmu_opl_drv;
|
||||
drv->priv = device_add_inst(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
|
||||
#ifdef USE_LIBSERIALPORT
|
||||
case FM_OPL2BOARD:
|
||||
*drv = ymfm_opl2board_drv;
|
||||
drv->priv = device_add_inst(&ym_opl2board_device, fm_dev_inst[fm_driver][chip_id]++);
|
||||
drv->priv = device_add_inst_params(&ym_opl2board_device, fm_dev_inst[fm_driver][chip_id]++, flag_48k);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -189,3 +191,9 @@ fm_driver_get(int chip_id, fm_drv_t *drv)
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
uint8_t
|
||||
fm_driver_get(int chip_id, fm_drv_t *drv)
|
||||
{
|
||||
return fm_driver_get_ex(chip_id, drv, 0);
|
||||
}
|
||||
|
||||
@@ -1460,6 +1460,15 @@ OPL3_GenerateStream(opl3_chip *chip, int32_t *sndptr, uint32_t numsamples)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OPL3_GenerateResampledStream(opl3_chip *chip, int32_t *sndptr, uint32_t numsamples)
|
||||
{
|
||||
for (uint_fast32_t i = 0; i < numsamples; i++) {
|
||||
OPL3_GenerateResampled(chip, sndptr);
|
||||
sndptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nuked_timer_tick(nuked_drv_t *dev, int tmr)
|
||||
{
|
||||
@@ -1525,32 +1534,6 @@ nuked_drv_set_do_cycles(void *priv, int8_t do_cycles)
|
||||
dev->flags &= ~FLAG_CYCLES;
|
||||
}
|
||||
|
||||
static void *
|
||||
nuked_drv_init(const device_t *info)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) calloc(1, sizeof(nuked_drv_t));
|
||||
dev->flags = FLAG_CYCLES;
|
||||
if (info->local == FM_YMF262)
|
||||
dev->flags |= FLAG_OPL3;
|
||||
else
|
||||
dev->status = 0x06;
|
||||
|
||||
/* Initialize the NukedOPL object. */
|
||||
OPL3_Reset(&dev->opl, FREQ_49716);
|
||||
|
||||
timer_add(&dev->timers[0], nuked_timer_1, dev, 0);
|
||||
timer_add(&dev->timers[1], nuked_timer_2, dev, 0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
nuked_drv_close(void *priv)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) priv;
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static int32_t *
|
||||
nuked_drv_update(void *priv)
|
||||
{
|
||||
@@ -1560,8 +1543,8 @@ nuked_drv_update(void *priv)
|
||||
return dev->buffer;
|
||||
|
||||
OPL3_GenerateStream(&dev->opl,
|
||||
&dev->buffer[dev->pos * 2],
|
||||
music_pos_global - dev->pos);
|
||||
&dev->buffer[dev->pos * 2],
|
||||
music_pos_global - dev->pos);
|
||||
|
||||
for (; dev->pos < music_pos_global; dev->pos++) {
|
||||
dev->buffer[dev->pos * 2] /= 2;
|
||||
@@ -1571,6 +1554,26 @@ nuked_drv_update(void *priv)
|
||||
return dev->buffer;
|
||||
}
|
||||
|
||||
static int32_t *
|
||||
nuked_drv_update_48k(void *priv)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) priv;
|
||||
|
||||
if (dev->pos >= sound_pos_global)
|
||||
return dev->buffer;
|
||||
|
||||
OPL3_GenerateResampledStream(&dev->opl,
|
||||
&dev->buffer[dev->pos * 2],
|
||||
sound_pos_global - dev->pos);
|
||||
|
||||
for (; dev->pos < sound_pos_global; dev->pos++) {
|
||||
dev->buffer[dev->pos * 2] /= 2;
|
||||
dev->buffer[(dev->pos * 2) + 1] /= 2;
|
||||
}
|
||||
|
||||
return dev->buffer;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
nuked_drv_read(uint16_t port, void *priv)
|
||||
{
|
||||
@@ -1579,7 +1582,7 @@ nuked_drv_read(uint16_t port, void *priv)
|
||||
if (dev->flags & FLAG_CYCLES)
|
||||
cycles -= ((int) (isa_timing * 8));
|
||||
|
||||
nuked_drv_update(dev);
|
||||
dev->update(dev);
|
||||
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
@@ -1598,7 +1601,8 @@ static void
|
||||
nuked_drv_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) priv;
|
||||
nuked_drv_update(dev);
|
||||
|
||||
dev->update(dev);
|
||||
|
||||
if ((port & 0x0001) == 0x0001) {
|
||||
OPL3_WriteRegBuffered(&dev->opl, dev->port, val);
|
||||
@@ -1649,6 +1653,40 @@ nuked_drv_reset_buffer(void *priv)
|
||||
dev->pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nuked_drv_close(void *priv)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) priv;
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
nuked_drv_init(const device_t *info)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) calloc(1, sizeof(nuked_drv_t));
|
||||
dev->flags = FLAG_CYCLES;
|
||||
if ((info->local & FM_TYPE_MASK) == FM_YMF262)
|
||||
dev->flags |= FLAG_OPL3;
|
||||
else
|
||||
dev->status = 0x06;
|
||||
|
||||
dev->is_48k = !!(info->local & FM_FORCE_48K);
|
||||
|
||||
/* Initialize the NukedOPL object. */
|
||||
if (dev->is_48k) {
|
||||
dev->update = nuked_drv_update_48k;
|
||||
OPL3_Reset(&dev->opl, FREQ_48000);
|
||||
} else {
|
||||
dev->update = nuked_drv_update;
|
||||
OPL3_Reset(&dev->opl, FREQ_49716);
|
||||
}
|
||||
|
||||
timer_add(&dev->timers[0], nuked_timer_1, dev, 0);
|
||||
timer_add(&dev->timers[1], nuked_timer_2, dev, 0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t ym3812_nuked_device = {
|
||||
.name = "Yamaha YM3812 OPL2 (NUKED)",
|
||||
.internal_name = "ym3812_nuked",
|
||||
@@ -1686,3 +1724,13 @@ const fm_drv_t nuked_opl_drv = {
|
||||
.priv = NULL,
|
||||
.generate = NULL,
|
||||
};
|
||||
|
||||
const fm_drv_t nuked_opl_drv_48k = {
|
||||
.read = &nuked_drv_read,
|
||||
.write = &nuked_drv_write,
|
||||
.update = &nuked_drv_update_48k,
|
||||
.reset_buffer = &nuked_drv_reset_buffer,
|
||||
.set_do_cycles = &nuked_drv_set_do_cycles,
|
||||
.priv = NULL,
|
||||
.generate = NULL,
|
||||
};
|
||||
|
||||
@@ -56,11 +56,12 @@ enum {
|
||||
|
||||
class YMFMChipBase {
|
||||
public:
|
||||
YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate)
|
||||
YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate, int is_48k)
|
||||
: m_buf_pos(0)
|
||||
, m_flags(0)
|
||||
, m_type(type)
|
||||
, m_samplerate(samplerate)
|
||||
, m_48k(is_48k)
|
||||
{
|
||||
memset(m_buffer, 0, sizeof(m_buffer));
|
||||
}
|
||||
@@ -74,11 +75,13 @@ public:
|
||||
void set_do_cycles(int8_t do_cycles) { do_cycles ? m_flags |= FLAG_CYCLES : m_flags &= ~FLAG_CYCLES; }
|
||||
int32_t *buffer() const { return (int32_t *) m_buffer; }
|
||||
void reset_buffer() { m_buf_pos = 0; }
|
||||
int is_48k() const { return m_48k; }
|
||||
|
||||
virtual uint32_t sample_rate() const = 0;
|
||||
|
||||
virtual void write(uint16_t addr, uint8_t data) = 0;
|
||||
virtual void generate(int32_t *data, uint32_t num_samples) = 0;
|
||||
virtual void generate_resampled(int32_t *data, uint32_t num_samples) = 0;
|
||||
virtual int32_t *update() = 0;
|
||||
virtual uint8_t read(uint16_t addr) = 0;
|
||||
virtual void set_clock(uint32_t clock) = 0;
|
||||
@@ -90,17 +93,19 @@ protected:
|
||||
int8_t m_flags;
|
||||
fm_type m_type;
|
||||
uint32_t m_samplerate;
|
||||
int m_48k;
|
||||
};
|
||||
|
||||
template <typename ChipType>
|
||||
class YMFMChip : public YMFMChipBase, public ymfm::ymfm_interface {
|
||||
public:
|
||||
YMFMChip(uint32_t clock, fm_type type, uint32_t samplerate)
|
||||
: YMFMChipBase(clock, type, samplerate)
|
||||
YMFMChip(uint32_t clock, fm_type type, uint32_t samplerate, int m_48k)
|
||||
: YMFMChipBase(clock, type, samplerate, m_48k)
|
||||
, m_chip(*this)
|
||||
, m_clock(clock)
|
||||
, m_samplerate(samplerate)
|
||||
, m_samplecnt(0)
|
||||
, m_48k(0)
|
||||
{
|
||||
memset(m_samples, 0, sizeof(m_samples));
|
||||
memset(m_oldsamples, 0, sizeof(m_oldsamples));
|
||||
@@ -109,7 +114,10 @@ public:
|
||||
m_subtract[0] = 80.0;
|
||||
m_subtract[1] = 320.0;
|
||||
m_type = type;
|
||||
m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global;
|
||||
if (m_48k)
|
||||
m_buf_pos_global = &sound_pos_global;
|
||||
else
|
||||
m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global;
|
||||
|
||||
if (m_type == FM_YMF278B) {
|
||||
if (rom_load_linear("roms/sound/yamaha/yrw801.rom", 0, 0x200000, 0, m_yrw801) == 0) {
|
||||
@@ -176,14 +184,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
virtual void generate_resampled(int32_t *data, uint32_t num_samples) override
|
||||
{
|
||||
if ((m_samplerate == FREQ_49716) || (m_samplerate == FREQ_44100)) {
|
||||
generate(data, num_samples);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_samples; i++) {
|
||||
while (m_samplecnt >= m_rateratio) {
|
||||
m_oldsamples[0] = m_samples[0];
|
||||
@@ -217,14 +219,16 @@ public:
|
||||
m_samplecnt += 1 << RSM_FRAC;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual int32_t *update() override
|
||||
{
|
||||
if (m_buf_pos >= *m_buf_pos_global)
|
||||
return m_buffer;
|
||||
|
||||
generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos);
|
||||
if (m_48k)
|
||||
generate_resampled(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos);
|
||||
else
|
||||
generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos);
|
||||
|
||||
for (; m_buf_pos < *m_buf_pos_global; m_buf_pos++) {
|
||||
m_buffer[m_buf_pos * 2] /= 2;
|
||||
@@ -287,6 +291,8 @@ private:
|
||||
int32_t m_samplecnt;
|
||||
int32_t m_oldsamples[2];
|
||||
int32_t m_samples[2];
|
||||
|
||||
int m_48k;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
@@ -325,127 +331,128 @@ static void *
|
||||
ymfm_drv_init(const device_t *info)
|
||||
{
|
||||
YMFMChipBase *fm;
|
||||
int is_48k = !!(info->local & FM_FORCE_48K);
|
||||
|
||||
switch (info->local) {
|
||||
switch (info->local & FM_TYPE_MASK) {
|
||||
case FM_YM2149: /* OPL */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2149>(14318181, FM_YM2149, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2149>(14318181, FM_YM2149, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3526: /* OPL */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3526>(14318181, FM_YM3526, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3526>(14318181, FM_YM3526, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_Y8950: /* MSX-Audio (OPL with ADPCM) */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::y8950>(14318181, FM_Y8950, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::y8950>(14318181, FM_Y8950, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
default:
|
||||
case FM_YM3812: /* OPL2 */
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3812>(3579545, FM_YM3812, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3812>(3579545, FM_YM3812, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF262: /* OPL3 */
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf262>(14318181, FM_YMF262, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf262>(14318181, FM_YMF262, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF289B: /* OPL3-L */
|
||||
/* According to the datasheet, we should be using 33868800, but YMFM appears
|
||||
to cheat and does it using the same values as the YMF262. */
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf289b>(14318181, FM_YMF289B, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf289b>(14318181, FM_YMF289B, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF278B: /* OPL4 */
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf278b>(33868800, FM_YMF278B, FREQ_44100);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf278b>(33868800, FM_YMF278B, FREQ_44100, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2413: /* OPLL */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2413>(14318181, FM_YM2413, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2413>(14318181, FM_YM2413, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2423: /* OPLL-X */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2423>(14318181, FM_YM2423, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2423>(14318181, FM_YM2423, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF281: /* OPLLP */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf281>(14318181, FM_YMF281, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf281>(14318181, FM_YMF281, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_DS1001: /* Konami VRC7 MMC */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ds1001>(14318181, FM_DS1001, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ds1001>(14318181, FM_DS1001, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2151: /* OPM */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2151>(14318181, FM_YM2151, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2151>(14318181, FM_YM2151, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2203: /* OPN */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2203>(14318181, FM_YM2203, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2203>(14318181, FM_YM2203, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2608: /* OPNA */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2608>(14318181, FM_YM2608, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2608>(14318181, FM_YM2608, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF288: /* OPN3L */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf288>(14318181, FM_YMF288, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf288>(14318181, FM_YMF288, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2610: /* OPNB */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2610>(14318181, FM_YM2610, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2610>(14318181, FM_YM2610, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2610B: /* OPNB2 */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2610b>(14318181, FM_YM2610B, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2610b>(14318181, FM_YM2610B, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2612: /* OPN2 */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2612>(14318181, FM_YM2612, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2612>(14318181, FM_YM2612, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3438: /* OPN2C */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3438>(14318181, FM_YM3438, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3438>(14318181, FM_YM3438, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YMF276: /* OPN2L */
|
||||
// TODO: Check function call, rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf276>(14318181, FM_YMF276, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf276>(14318181, FM_YMF276, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM2164: /* OPP */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2164>(14318181, FM_YM2164, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2164>(14318181, FM_YM2164, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
case FM_YM3806: /* OPQ */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3806>(14318181, FM_YM3806, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3806>(14318181, FM_YM3806, FREQ_49716, is_48k);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case FM_YMF271: /* OPX */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf271>(14318181, FM_YMF271, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf271>(14318181, FM_YMF271, FREQ_49716, is_48k);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FM_YM2414: /* OPZ */
|
||||
// TODO: Check rates and frequency
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2414>(14318181, FM_YM2414, FREQ_49716);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym2414>(14318181, FM_YM2414, FREQ_49716, is_48k);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -523,8 +530,10 @@ ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples)
|
||||
{
|
||||
YMFMChipBase *drv = (YMFMChipBase *) priv;
|
||||
|
||||
// drv->generate_resampled(data, num_samples);
|
||||
drv->generate(data, num_samples);
|
||||
if (drv->is_48k())
|
||||
drv->generate_resampled(data, num_samples);
|
||||
else
|
||||
drv->generate(data, num_samples);
|
||||
}
|
||||
|
||||
const device_t ym2149_ymfm_device = {
|
||||
|
||||
@@ -111,10 +111,10 @@ ym7128_write(ym7128_t *ym7128, uint8_t val)
|
||||
ym7128->a0 = new_a0;
|
||||
}
|
||||
|
||||
#define GET_DELAY_SAMPLE(ym7128, offset) (((ym7128->delay_pos[i] - offset) < 0) ? ym7128->delay_buffer[i][(ym7128->delay_pos[i] - offset) + 2400] : ym7128->delay_buffer[i][ym7128->delay_pos[i] - offset])
|
||||
#define GET_DELAY_SAMPLE(ym7128, offset) (((ym7128->delay_pos - offset) < 0) ? ym7128->delay_buffer[(ym7128->delay_pos - offset) + 2400] : ym7128->delay_buffer[ym7128->delay_pos - offset])
|
||||
|
||||
void
|
||||
ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len)
|
||||
ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len)
|
||||
{
|
||||
for (int c = 0; c < len * 2; c += 4) {
|
||||
/*YM7128 samples a mono stream at ~24 kHz, so downsample*/
|
||||
@@ -125,13 +125,13 @@ ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len)
|
||||
int32_t samp_r = 0;
|
||||
|
||||
filter_temp = GET_DELAY_SAMPLE(ym7128, ym7128->t[0]);
|
||||
filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat[i] * ym7128->c1) >> 11);
|
||||
filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat * ym7128->c1) >> 11);
|
||||
filter_out = (filter_out * ym7128->vc) >> 16;
|
||||
|
||||
samp = (samp * ym7128->vm) >> 16;
|
||||
samp += filter_out;
|
||||
|
||||
ym7128->delay_buffer[i][ym7128->delay_pos[i]] = samp;
|
||||
ym7128->delay_buffer[ym7128->delay_pos] = samp;
|
||||
|
||||
for (uint8_t d = 0; d < 8; d++) {
|
||||
samp_l += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d + 1]) * ym7128->gl[d]) >> 16;
|
||||
@@ -141,17 +141,17 @@ ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int i, int len)
|
||||
samp_l = (samp_l * ym7128->vl * 2) >> 16;
|
||||
samp_r = (samp_r * ym7128->vr * 2) >> 16;
|
||||
|
||||
buffer[c] += (samp_l + (int32_t) ym7128->prev_l[i]) / 2;
|
||||
buffer[c + 1] += (samp_r + (int32_t) ym7128->prev_r[i]) / 2;
|
||||
buffer[c] += (samp_l + (int32_t) ym7128->prev_l) / 2;
|
||||
buffer[c + 1] += (samp_r + (int32_t) ym7128->prev_r) / 2;
|
||||
buffer[c + 2] += samp_l;
|
||||
buffer[c + 3] += samp_r;
|
||||
|
||||
ym7128->delay_pos[i]++;
|
||||
if (ym7128->delay_pos[i] >= 2400)
|
||||
ym7128->delay_pos[i] = 0;
|
||||
ym7128->delay_pos++;
|
||||
if (ym7128->delay_pos >= 2400)
|
||||
ym7128->delay_pos = 0;
|
||||
|
||||
ym7128->filter_dat[i] = filter_temp;
|
||||
ym7128->prev_l[i] = samp_l;
|
||||
ym7128->prev_r[i] = samp_r;
|
||||
ym7128->filter_dat = filter_temp;
|
||||
ym7128->prev_l = samp_l;
|
||||
ym7128->prev_r = samp_r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1967,9 +1967,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
if (val & 0x800)
|
||||
virge->streams.k1_horiz_scale |= ~0x7ff;
|
||||
|
||||
virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
|
||||
if ((val >> 16) & 0x800)
|
||||
virge->streams.k2_horiz_scale |= ~0x7ff;
|
||||
virge->streams.k2_horiz_scale = (val >> 16) & 0x3ff;
|
||||
if ((val >> 16) & 0x400)
|
||||
virge->streams.k2_horiz_scale |= ~0x3ff;
|
||||
|
||||
svga_recalctimings(svga);
|
||||
svga->fullchange = changeframecount;
|
||||
@@ -2025,9 +2025,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
virge->streams.k1_vert_scale |= ~0x7ff;
|
||||
break;
|
||||
case 0x81e4:
|
||||
virge->streams.k2_vert_scale = val & 0x7ff;
|
||||
if (val & 0x800)
|
||||
virge->streams.k2_vert_scale |= ~0x7ff;
|
||||
virge->streams.k2_vert_scale = val & 0x3ff;
|
||||
if (val & 0x400)
|
||||
virge->streams.k2_vert_scale |= ~0x3ff;
|
||||
break;
|
||||
case 0x81e8:
|
||||
virge->streams.dda_vert_accumulator = val & 0x7ff;
|
||||
|
||||
Reference in New Issue
Block a user