Merge pull request #1027 from richardg867/master
Implement VIA 686A/B southbridges
This commit is contained in:
14
src/acpi.c
14
src/acpi.c
@@ -1135,11 +1135,21 @@ acpi_reset(void *priv)
|
|||||||
|
|
||||||
memset(&dev->regs, 0x00, sizeof(acpi_regs_t));
|
memset(&dev->regs, 0x00, sizeof(acpi_regs_t));
|
||||||
dev->regs.gpireg[0] = 0xff; dev->regs.gpireg[1] = 0xff;
|
dev->regs.gpireg[0] = 0xff; dev->regs.gpireg[1] = 0xff;
|
||||||
dev->regs.gpireg[2] = 0xf3; /* SMSC: Bit 2: 80-conductor cable on primary IDE (0 = yes, 1 = no), Bit 3: on secondary IDE. */
|
/* SMSC SLC90E66 machines:
|
||||||
|
- Bit 3: 80-conductor cable on secondary IDE channel (active low)
|
||||||
|
- Bit 2: 80-conductor cable on primary IDE channel (active low) */
|
||||||
|
dev->regs.gpireg[2] = 0xf3;
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
dev->regs.gporeg[i] = dev->gporeg_default[i];
|
dev->regs.gporeg[i] = dev->gporeg_default[i];
|
||||||
if (dev->vendor == VEN_VIA_596B)
|
if (dev->vendor == VEN_VIA_596B) {
|
||||||
dev->regs.gpo_val = 0x7fffffff;
|
dev->regs.gpo_val = 0x7fffffff;
|
||||||
|
/* FIC VA-503A:
|
||||||
|
- Bit 11: ATX power (active high)
|
||||||
|
- Bit 4: 80-conductor cable on primary IDE channel (active low)
|
||||||
|
- Bit 3: 80-conductor cable on secondary IDE channel (active low)
|
||||||
|
- Bit 2: password cleared (active low) */
|
||||||
|
dev->regs.gpi_val = 0xffffffe7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,8 @@
|
|||||||
#include <86box/machine.h>
|
#include <86box/machine.h>
|
||||||
#include <86box/smbus_piix4.h>
|
#include <86box/smbus_piix4.h>
|
||||||
#include <86box/chipset.h>
|
#include <86box/chipset.h>
|
||||||
|
#include <86box/sio.h>
|
||||||
|
#include <86box/hwm.h>
|
||||||
|
|
||||||
|
|
||||||
/* Most revision numbers (PCI-ISA bridge or otherwise) were lifted from PCI device
|
/* Most revision numbers (PCI-ISA bridge or otherwise) were lifted from PCI device
|
||||||
@@ -135,7 +137,7 @@ pipc_reset_hard(void *priv)
|
|||||||
dev->pci_isa_regs[0x4a] = 0x04;
|
dev->pci_isa_regs[0x4a] = 0x04;
|
||||||
dev->pci_isa_regs[0x4f] = 0x03;
|
dev->pci_isa_regs[0x4f] = 0x03;
|
||||||
|
|
||||||
dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x2d : 0x24;
|
dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; /* 686A/B default value does not line up with default bits */
|
||||||
dev->pci_isa_regs[0x59] = 0x04;
|
dev->pci_isa_regs[0x59] = 0x04;
|
||||||
if (dev->local >= VIA_PIPC_686A)
|
if (dev->local >= VIA_PIPC_686A)
|
||||||
dev->pci_isa_regs[0x5a] = dev->pci_isa_regs[0x5f] = 0x04;
|
dev->pci_isa_regs[0x5a] = dev->pci_isa_regs[0x5f] = 0x04;
|
||||||
@@ -180,8 +182,7 @@ pipc_reset_hard(void *priv)
|
|||||||
dev->ide_regs[0x4c] = 0xff;
|
dev->ide_regs[0x4c] = 0xff;
|
||||||
dev->ide_regs[0x4e] = 0xff;
|
dev->ide_regs[0x4e] = 0xff;
|
||||||
dev->ide_regs[0x4f] = 0xff;
|
dev->ide_regs[0x4f] = 0xff;
|
||||||
dev->ide_regs[0x50] = 0x03; dev->ide_regs[0x51] = 0x03;
|
dev->ide_regs[0x50] = dev->ide_regs[0x51] = dev->ide_regs[0x52] = dev->ide_regs[0x53] = (dev->local >= VIA_PIPC_686A) ? 0x07 : 0x03;
|
||||||
dev->ide_regs[0x52] = 0x03; dev->ide_regs[0x53] = 0x03;
|
|
||||||
if (dev->local >= VIA_PIPC_596A)
|
if (dev->local >= VIA_PIPC_596A)
|
||||||
dev->ide_regs[0x54] = 0x06;
|
dev->ide_regs[0x54] = 0x06;
|
||||||
|
|
||||||
@@ -271,6 +272,9 @@ pipc_reset_hard(void *priv)
|
|||||||
dev->power_regs[0x42] = 0x40; /* external suspend-related pin, must be set */
|
dev->power_regs[0x42] = 0x40; /* external suspend-related pin, must be set */
|
||||||
dev->power_regs[0x48] = 0x01;
|
dev->power_regs[0x48] = 0x01;
|
||||||
|
|
||||||
|
if (dev->local >= VIA_PIPC_686A)
|
||||||
|
dev->power_regs[0x70] = 0x01;
|
||||||
|
|
||||||
if (dev->local == VIA_PIPC_596A)
|
if (dev->local == VIA_PIPC_596A)
|
||||||
dev->power_regs[0x80] = 0x01;
|
dev->power_regs[0x80] = 0x01;
|
||||||
else if (dev->local >= VIA_PIPC_596B)
|
else if (dev->local >= VIA_PIPC_596B)
|
||||||
@@ -411,8 +415,14 @@ pipc_read(int func, int addr, void *priv)
|
|||||||
ret = dev->ide_regs[addr];
|
ret = dev->ide_regs[addr];
|
||||||
else if ((func < pm_func) && !((func == 2) ? (dev->pci_isa_regs[0x48] & 0x04) : (dev->pci_isa_regs[0x85] & 0x10))) /* USB */
|
else if ((func < pm_func) && !((func == 2) ? (dev->pci_isa_regs[0x48] & 0x04) : (dev->pci_isa_regs[0x85] & 0x10))) /* USB */
|
||||||
ret = dev->usb_regs[func - 2][addr];
|
ret = dev->usb_regs[func - 2][addr];
|
||||||
else if (func == pm_func) /* Power */
|
else if (func == pm_func) { /* Power */
|
||||||
ret = dev->power_regs[addr];
|
ret = dev->power_regs[addr];
|
||||||
|
if (addr == 0x42) {
|
||||||
|
ret &= ~0x10;
|
||||||
|
if (dev->nvr->regs[0x0d] & 0x80)
|
||||||
|
ret |= 0x10;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ((func <= (pm_func + 2)) && !(dev->pci_isa_regs[0x85] & ((func == (pm_func + 1)) ? 0x04 : 0x08))) /* AC97 / MC97 */
|
else if ((func <= (pm_func + 2)) && !(dev->pci_isa_regs[0x85] & ((func == (pm_func + 1)) ? 0x04 : 0x08))) /* AC97 / MC97 */
|
||||||
ret = dev->ac97_regs[func - pm_func - 1][addr];
|
ret = dev->ac97_regs[func - pm_func - 1][addr];
|
||||||
|
|
||||||
@@ -446,6 +456,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
pipc_t *dev = (pipc_t *) priv;
|
pipc_t *dev = (pipc_t *) priv;
|
||||||
int c;
|
int c;
|
||||||
uint8_t pm_func = dev->usb[1] ? 4 : 3;
|
uint8_t pm_func = dev->usb[1] ? 4 : 3;
|
||||||
|
void *subdev;
|
||||||
|
|
||||||
if (func > dev->max_func)
|
if (func > dev->max_func)
|
||||||
return;
|
return;
|
||||||
@@ -488,6 +499,13 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
nvr_update_io_mapping(dev);
|
nvr_update_io_mapping(dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x50: case 0x51: case 0x52: case 0x85:
|
||||||
|
dev->pci_isa_regs[addr] = val;
|
||||||
|
/* Forward Super I/O-related registers to sio_vt82c686.c */
|
||||||
|
if ((subdev = device_get_priv(&via_vt82c686_sio_device)))
|
||||||
|
vt82c686_sio_write(addr, val, subdev);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x54:
|
case 0x54:
|
||||||
pci_set_irq_level(PCI_INTA, !(val & 8));
|
pci_set_irq_level(PCI_INTA, !(val & 8));
|
||||||
pci_set_irq_level(PCI_INTB, !(val & 4));
|
pci_set_irq_level(PCI_INTB, !(val & 4));
|
||||||
@@ -551,10 +569,6 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
dev->pci_isa_regs[addr] &= ~(val);
|
dev->pci_isa_regs[addr] &= ~(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x85:
|
|
||||||
dev->pci_isa_regs[addr] = val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dev->pci_isa_regs[addr] = val;
|
dev->pci_isa_regs[addr] = val;
|
||||||
break;
|
break;
|
||||||
@@ -707,10 +721,21 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
acpi_update_io_mapping(dev->acpi, c, dev->power_regs[0x41] & 0x80);
|
acpi_update_io_mapping(dev->acpi, c, dev->power_regs[0x41] & 0x80);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x42:
|
||||||
|
dev->power_regs[addr] = val & 0x0f;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x61: case 0x62: case 0x63:
|
case 0x61: case 0x62: case 0x63:
|
||||||
dev->power_regs[(addr - 0x58)] = val;
|
dev->power_regs[(addr - 0x58)] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x70: case 0x71: case 0x74:
|
||||||
|
dev->power_regs[addr] = val;
|
||||||
|
/* Forward hardware monitor-related registers to hwm_vt82c686.c */
|
||||||
|
if ((subdev = device_get_priv(&via_vt82c686_hwm_device)))
|
||||||
|
vt82c686_hwm_write(addr, val, subdev);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x80: case 0x81: case 0x84: /* 596(A) has the SMBus I/O base here instead. Enable bit is assumed. */
|
case 0x80: case 0x81: case 0x84: /* 596(A) has the SMBus I/O base here instead. Enable bit is assumed. */
|
||||||
dev->power_regs[addr] = val;
|
dev->power_regs[addr] = val;
|
||||||
smbus_piix4_remap(dev->smbus, (dev->power_regs[0x81] << 8) | (dev->power_regs[0x80] & 0xf0), dev->power_regs[0x84] & 0x01);
|
smbus_piix4_remap(dev->smbus, (dev->power_regs[0x81] << 8) | (dev->power_regs[0x80] & 0xf0), dev->power_regs[0x84] & 0x01);
|
||||||
@@ -804,14 +829,15 @@ pipc_init(const device_t *info)
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pipc_close(void *p)
|
pipc_close(void *p)
|
||||||
{
|
{
|
||||||
pipc_t *pipc = (pipc_t *) p;
|
pipc_t *dev = (pipc_t *) p;
|
||||||
|
|
||||||
pipc_log("PIPC: close()\n");
|
pipc_log("PIPC: close()\n");
|
||||||
|
|
||||||
free(pipc);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -857,3 +883,33 @@ const device_t via_vt82c596b_device =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const device_t via_vt82c686a_device =
|
||||||
|
{
|
||||||
|
"VIA VT82C686A",
|
||||||
|
DEVICE_PCI,
|
||||||
|
VIA_PIPC_686A,
|
||||||
|
pipc_init,
|
||||||
|
pipc_close,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const device_t via_vt82c686b_device =
|
||||||
|
{
|
||||||
|
"VIA VT82C686B",
|
||||||
|
DEVICE_PCI,
|
||||||
|
VIA_PIPC_686B,
|
||||||
|
pipc_init,
|
||||||
|
pipc_close,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|||||||
180
src/device/hwm_vt82c686.c
Normal file
180
src/device/hwm_vt82c686.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.
|
||||||
|
*
|
||||||
|
* Emulation of the VIA VT82C686A/B integrated hardware monitor.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Author: RichardG, <richardg867@gmail.com>
|
||||||
|
*
|
||||||
|
* Copyright 2020 RichardG.
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define HAVE_STDARG_H
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <86box/86box.h>
|
||||||
|
#include <86box/device.h>
|
||||||
|
#include <86box/io.h>
|
||||||
|
#include "cpu.h"
|
||||||
|
#include <86box/smbus.h>
|
||||||
|
#include <86box/hwm.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
|
||||||
|
#define VT82C686_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0)
|
||||||
|
/* Temperature formula from source comments in Linux's via686a.c driver */
|
||||||
|
#define VT82C686_TEMP_TO_REG(t) (-1.160370e-10*(t*t*t*t*t*t) + 3.193693e-08*(t*t*t*t*t) - 1.464447e-06*(t*t*t*t) - 2.525453e-04*(t*t*t) + 1.424593e-02*(t*t) + 2.148941e+00*t + 7.275808e+01)
|
||||||
|
#define VT82C686_VOLTAGE_TO_REG(v) ((v) >> 4)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
hwm_values_t *values;
|
||||||
|
device_t *lm75[2];
|
||||||
|
|
||||||
|
uint8_t enable;
|
||||||
|
uint16_t io_base;
|
||||||
|
uint8_t regs[80];
|
||||||
|
} vt82c686_t;
|
||||||
|
|
||||||
|
|
||||||
|
static void vt82c686_reset(vt82c686_t *dev, uint8_t initialization);
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
vt82c686_read(uint16_t addr, void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
return dev->regs[addr - dev->io_base];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_write(uint16_t port, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
uint8_t reg = port - dev->io_base;
|
||||||
|
|
||||||
|
if ((reg == 0x41) || (reg == 0x42) || (reg == 0x45) || (reg == 0x46) || (reg == 0x48) || (reg == 0x4a) || (reg >= 0x4c))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (reg) {
|
||||||
|
case 0x40:
|
||||||
|
if (val & 0x80)
|
||||||
|
vt82c686_reset(dev, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x47:
|
||||||
|
val &= 0xf0;
|
||||||
|
/* update FAN1/FAN2 values to match the new divisor */
|
||||||
|
dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3));
|
||||||
|
dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->regs[reg] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Writes to hardware monitor-related configuration space registers
|
||||||
|
of the VT82C686 power management function are sent here by via_pipc.c */
|
||||||
|
void
|
||||||
|
vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
|
||||||
|
if (dev->io_base)
|
||||||
|
io_removehandler(dev->io_base, 0x0050,
|
||||||
|
vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev);
|
||||||
|
|
||||||
|
switch (addr) {
|
||||||
|
case 0x70:
|
||||||
|
dev->io_base &= 0xff00;
|
||||||
|
dev->io_base |= val & 0x80;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x71:
|
||||||
|
dev->io_base &= 0x00ff;
|
||||||
|
dev->io_base |= val << 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x74:
|
||||||
|
dev->enable = val & 0x01;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->enable && dev->io_base)
|
||||||
|
io_sethandler(dev->io_base, 0x0050,
|
||||||
|
vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_reset(vt82c686_t *dev, uint8_t initialization)
|
||||||
|
{
|
||||||
|
memset(dev->regs, 0, 80);
|
||||||
|
|
||||||
|
dev->regs[0x1f] = VT82C686_TEMP_TO_REG(dev->values->temperatures[2]);
|
||||||
|
dev->regs[0x20] = VT82C686_TEMP_TO_REG(dev->values->temperatures[0]);
|
||||||
|
dev->regs[0x21] = VT82C686_TEMP_TO_REG(dev->values->temperatures[1]);
|
||||||
|
|
||||||
|
dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0]);
|
||||||
|
dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1]);
|
||||||
|
dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2]);
|
||||||
|
dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3]);
|
||||||
|
dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4]);
|
||||||
|
|
||||||
|
dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 2);
|
||||||
|
dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 2);
|
||||||
|
|
||||||
|
dev->regs[0x40] = 0x08;
|
||||||
|
dev->regs[0x47] = 0x50;
|
||||||
|
dev->regs[0x49] = (dev->values->temperatures[2] & 0x3) << 6;
|
||||||
|
dev->regs[0x49] |= (dev->values->temperatures[1] & 0x3) << 4;
|
||||||
|
dev->regs[0x4b] = (dev->values->temperatures[0] & 0x3) << 6;
|
||||||
|
dev->regs[0x4b] |= 0x15;
|
||||||
|
|
||||||
|
if (!initialization)
|
||||||
|
vt82c686_hwm_write(0x85, 0x00, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_close(void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
vt82c686_init(const device_t *info)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t));
|
||||||
|
memset(dev, 0, sizeof(vt82c686_t));
|
||||||
|
|
||||||
|
dev->values = hwm_get_values();
|
||||||
|
|
||||||
|
vt82c686_reset(dev, 0);
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const device_t via_vt82c686_hwm_device = {
|
||||||
|
"VIA VT82C686 Integrated Hardware Monitor",
|
||||||
|
DEVICE_ISA,
|
||||||
|
0,
|
||||||
|
vt82c686_init, vt82c686_close, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -412,7 +412,7 @@ ide_get_max(ide_t *ide, int type)
|
|||||||
return -1;
|
return -1;
|
||||||
case TYPE_UDMA: /* UDMA */
|
case TYPE_UDMA: /* UDMA */
|
||||||
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
|
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
|
||||||
return 4 /*2*/;
|
return 5;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
@@ -620,6 +620,9 @@ ide_identify(ide_t *ide)
|
|||||||
ide->buffer[88] |= d;
|
ide->buffer[88] |= d;
|
||||||
ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]);
|
ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (max_udma >= 4)
|
||||||
|
ide->buffer[93] = 0x6000; /* Drive reports 80-conductor cable */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2013,7 +2013,7 @@ mo_get_max(int ide_has_dma, int type)
|
|||||||
ret = ide_has_dma ? 1 : -1;
|
ret = ide_has_dma ? 1 : -1;
|
||||||
break;
|
break;
|
||||||
case TYPE_UDMA:
|
case TYPE_UDMA:
|
||||||
ret = ide_has_dma ? 4 /*2*/ : -1;
|
ret = ide_has_dma ? 5 : -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2242,7 +2242,7 @@ zip_get_max(int ide_has_dma, int type)
|
|||||||
ret = ide_has_dma ? 1 : -1;
|
ret = ide_has_dma ? 1 : -1;
|
||||||
break;
|
break;
|
||||||
case TYPE_UDMA:
|
case TYPE_UDMA:
|
||||||
ret = ide_has_dma ? 4 /*2*/ : -1;
|
ret = ide_has_dma ? 5 : -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ extern const device_t via_apro_device;
|
|||||||
extern const device_t via_vt82c586b_device;
|
extern const device_t via_vt82c586b_device;
|
||||||
extern const device_t via_vt82c596_device;
|
extern const device_t via_vt82c596_device;
|
||||||
extern const device_t via_vt82c596b_device;
|
extern const device_t via_vt82c596b_device;
|
||||||
|
extern const device_t via_vt82c686a_device;
|
||||||
|
extern const device_t via_vt82c686b_device;
|
||||||
|
|
||||||
/* VLSI */
|
/* VLSI */
|
||||||
extern const device_t vl82c480_device;
|
extern const device_t vl82c480_device;
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ extern void lm75_remap(lm75_t *dev, uint8_t addr);
|
|||||||
extern uint8_t lm75_read(lm75_t *dev, uint8_t reg);
|
extern uint8_t lm75_read(lm75_t *dev, uint8_t reg);
|
||||||
extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val);
|
extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val);
|
||||||
|
|
||||||
|
extern void vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv);
|
||||||
|
|
||||||
|
|
||||||
extern const device_t lm75_1_4a_device;
|
extern const device_t lm75_1_4a_device;
|
||||||
extern const device_t lm75_w83781d_device;
|
extern const device_t lm75_w83781d_device;
|
||||||
@@ -59,5 +61,7 @@ extern const device_t as99127f_rev2_device;
|
|||||||
extern const device_t gl518sm_2c_device;
|
extern const device_t gl518sm_2c_device;
|
||||||
extern const device_t gl518sm_2d_device;
|
extern const device_t gl518sm_2d_device;
|
||||||
|
|
||||||
|
extern const device_t via_vt82c686_hwm_device;
|
||||||
|
|
||||||
|
|
||||||
#endif /*EMU_HWM_H*/
|
#endif /*EMU_HWM_H*/
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ extern const device_t *at_pb640_get_device(void);
|
|||||||
/* m_at_super7_ss7.c */
|
/* m_at_super7_ss7.c */
|
||||||
extern int machine_at_ax59pro_init(const machine_t *);
|
extern int machine_at_ax59pro_init(const machine_t *);
|
||||||
extern int machine_at_mvp3_init(const machine_t *);
|
extern int machine_at_mvp3_init(const machine_t *);
|
||||||
|
extern int machine_at_ficva503a_init(const machine_t *);
|
||||||
|
|
||||||
/* m_at_socket8.c */
|
/* m_at_socket8.c */
|
||||||
extern int machine_at_686nx_init(const machine_t *);
|
extern int machine_at_686nx_init(const machine_t *);
|
||||||
@@ -425,7 +426,7 @@ extern int machine_at_ax6bc_init(const machine_t *);
|
|||||||
extern int machine_at_atc6310bxii_init(const machine_t *);
|
extern int machine_at_atc6310bxii_init(const machine_t *);
|
||||||
extern int machine_at_tsunamiatx_init(const machine_t *);
|
extern int machine_at_tsunamiatx_init(const machine_t *);
|
||||||
extern int machine_at_p6sba_init(const machine_t *);
|
extern int machine_at_p6sba_init(const machine_t *);
|
||||||
extern int machine_at_ka6100_init(const machine_t *);
|
extern int machine_at_ficka6100_init(const machine_t *);
|
||||||
|
|
||||||
#ifdef EMU_DEVICE_H
|
#ifdef EMU_DEVICE_H
|
||||||
extern const device_t *at_tsunamiatx_get_device(void);
|
extern const device_t *at_tsunamiatx_get_device(void);
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
# define EMU_SIO_H
|
# define EMU_SIO_H
|
||||||
|
|
||||||
|
|
||||||
|
extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv);
|
||||||
|
|
||||||
|
|
||||||
extern const device_t acc3221_device;
|
extern const device_t acc3221_device;
|
||||||
extern const device_t f82c710_device;
|
extern const device_t f82c710_device;
|
||||||
extern const device_t fdc37c661_device;
|
extern const device_t fdc37c661_device;
|
||||||
@@ -39,6 +42,7 @@ extern const device_t pc97307_device;
|
|||||||
extern const device_t ps1_m2133_sio;
|
extern const device_t ps1_m2133_sio;
|
||||||
extern const device_t sio_detect_device;
|
extern const device_t sio_detect_device;
|
||||||
extern const device_t um8669f_device;
|
extern const device_t um8669f_device;
|
||||||
|
extern const device_t via_vt82c686_sio_device;
|
||||||
extern const device_t w83787f_device;
|
extern const device_t w83787f_device;
|
||||||
extern const device_t w83877f_device;
|
extern const device_t w83877f_device;
|
||||||
extern const device_t w83877f_president_device;
|
extern const device_t w83877f_president_device;
|
||||||
|
|||||||
@@ -575,11 +575,11 @@ at_tsunamiatx_get_device(void)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
machine_at_ka6100_init(const machine_t *model)
|
machine_at_ficka6100_init(const machine_t *model)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = bios_load_linear(L"roms/machines/ka6100/610011ex.bin",
|
ret = bios_load_linear(L"roms/machines/ficka6100/610011ex.bin",
|
||||||
0x000e0000, 131072, 0);
|
0x000e0000, 131072, 0);
|
||||||
|
|
||||||
if (bios_only || !ret)
|
if (bios_only || !ret)
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ machine_at_ax59pro_init(const machine_t *model)
|
|||||||
device_add(&keyboard_ps2_pci_device);
|
device_add(&keyboard_ps2_pci_device);
|
||||||
device_add(&w83877tf_device);
|
device_add(&w83877tf_device);
|
||||||
device_add(&sst_flash_39sf020_device);
|
device_add(&sst_flash_39sf020_device);
|
||||||
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
|
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,89 @@ machine_at_mvp3_init(const machine_t *model)
|
|||||||
device_add(&keyboard_ps2_pci_device);
|
device_add(&keyboard_ps2_pci_device);
|
||||||
device_add(&w83877tf_device);
|
device_add(&w83877tf_device);
|
||||||
device_add(&sst_flash_39sf010_device);
|
device_add(&sst_flash_39sf010_device);
|
||||||
spd_register(SPD_TYPE_SDRAM, 0x3, 512);
|
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
machine_at_ficva503a_init(const machine_t *model)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bios_load_linear(L"roms/machines/ficva503a/jo4116.bin",
|
||||||
|
0x000c0000, 262144, 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4);
|
||||||
|
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||||
|
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||||
|
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||||
|
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||||
|
pci_register_slot(0x01, PCI_CARD_SPECIAL, 1, 2, 3, 4);
|
||||||
|
|
||||||
|
device_add(&via_mvp3_device);
|
||||||
|
device_add(&via_vt82c686a_device);
|
||||||
|
device_add(&keyboard_ps2_pci_device);
|
||||||
|
device_add(&via_vt82c686_sio_device);
|
||||||
|
device_add(&sst_flash_39sf020_device);
|
||||||
|
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||||
|
|
||||||
|
hwm_values_t machine_hwm = {
|
||||||
|
{ /* fan speeds */
|
||||||
|
3000, /* CPUFAN1 */
|
||||||
|
3000 /* ChassisFAN */
|
||||||
|
}, { /* temperatures */
|
||||||
|
32, /* CPU */
|
||||||
|
32, /* System */
|
||||||
|
0 /* unused */
|
||||||
|
}, { /* voltages */
|
||||||
|
3300, /* Vcore (3.3V by default) */
|
||||||
|
2500, /* 2.5V (unused) */
|
||||||
|
3300, /* 3.3V */
|
||||||
|
RESISTOR_DIVIDER(5000, 9, 16), /* 5V (divider values bruteforced) */
|
||||||
|
RESISTOR_DIVIDER(12000, 28, 10) /* 12V (28K/10K divider applies to W83781D but is close enough) */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V).
|
||||||
|
Pentium MMX: 2.8 V.
|
||||||
|
AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233.
|
||||||
|
AMD K6 Model 7: 2.2 V. */
|
||||||
|
switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) {
|
||||||
|
case CPU_WINCHIP:
|
||||||
|
case CPU_WINCHIP2:
|
||||||
|
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
|
||||||
|
case CPU_Cx6x86:
|
||||||
|
#endif
|
||||||
|
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
|
||||||
|
case CPU_K5:
|
||||||
|
case CPU_5K86:
|
||||||
|
#endif
|
||||||
|
machine_hwm.voltages[0] = 3500;
|
||||||
|
break;
|
||||||
|
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
|
||||||
|
case CPU_Cx6x86MX:
|
||||||
|
machine_hwm.voltages[0] = 2900;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case CPU_PENTIUMMMX:
|
||||||
|
machine_hwm.voltages[0] = 2800;
|
||||||
|
break;
|
||||||
|
case CPU_K6:
|
||||||
|
case CPU_K6_2:
|
||||||
|
machine_hwm.voltages[0] = 2200;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
machine_hwm.voltages[0] *= 1.32; /* multiplier bruteforced */
|
||||||
|
hwm_set_values(machine_hwm);
|
||||||
|
device_add(&via_vt82c686_hwm_device);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -333,6 +333,7 @@ const machine_t machines[] = {
|
|||||||
/* Apollo MVP3 */
|
/* Apollo MVP3 */
|
||||||
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
|
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
|
||||||
{ "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_mvp3_init, NULL },
|
{ "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_mvp3_init, NULL },
|
||||||
|
{ "[VIA MVP3] FIC VA-503A", "ficva503a", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ficva503a_init, NULL },
|
||||||
|
|
||||||
/* Socket 8 machines */
|
/* Socket 8 machines */
|
||||||
/* 440FX */
|
/* 440FX */
|
||||||
@@ -365,7 +366,7 @@ const machine_t machines[] = {
|
|||||||
{ "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL },
|
{ "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL },
|
||||||
{ "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device },
|
{ "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device },
|
||||||
{ "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL },
|
{ "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL },
|
||||||
{ "[VIA Apollo Pro] FIC KA-6100", "ka6100", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ka6100_init, NULL },
|
{ "[VIA Apollo Pro] FIC KA-6100", "ficka6100", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ficka6100_init, NULL },
|
||||||
|
|
||||||
/* Slot 2 machines(Including Slot 1/2 Hybrids) */
|
/* Slot 2 machines(Including Slot 1/2 Hybrids) */
|
||||||
/* 440GX */
|
/* 440GX */
|
||||||
|
|||||||
10
src/nvr_at.c
10
src/nvr_at.c
@@ -580,7 +580,17 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RTC_REGC: /* R/O */
|
case RTC_REGC: /* R/O */
|
||||||
|
break;
|
||||||
|
|
||||||
case RTC_REGD: /* R/O */
|
case RTC_REGD: /* R/O */
|
||||||
|
/* VT82C686A/B have an ACPI register bit controlled by 0D bit 7.
|
||||||
|
This is overwritten on read, but testing shows BIOSes will
|
||||||
|
immediately check the ACPI register after writing to this. */
|
||||||
|
if (local->cent == RTC_CENTURY_VIA) {
|
||||||
|
nvr->regs[RTC_REGD] &= ~0x80;
|
||||||
|
if (val & 0x80)
|
||||||
|
nvr->regs[RTC_REGD] |= 0x80;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2e:
|
case 0x2e:
|
||||||
|
|||||||
@@ -2601,7 +2601,7 @@ scsi_cdrom_get_max(int ide_has_dma, int type)
|
|||||||
ret = ide_has_dma ? 2 : -1;
|
ret = ide_has_dma ? 2 : -1;
|
||||||
break;
|
break;
|
||||||
case TYPE_UDMA:
|
case TYPE_UDMA:
|
||||||
ret = ide_has_dma ? 4 /*2*/ : -1;
|
ret = ide_has_dma ? 5 : -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|||||||
272
src/sio/sio_vt82c686.c
Normal file
272
src/sio/sio_vt82c686.c
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
|
* running old operating systems and software designed for IBM
|
||||||
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
|
* system designs based on the PCI bus.
|
||||||
|
*
|
||||||
|
* This file is part of the 86Box distribution.
|
||||||
|
*
|
||||||
|
* Emulation of the VIA VT82C686A/B integrated Super I/O.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Author: RichardG, <richardg867@gmail.com>
|
||||||
|
* Copyright 2020 RichardG.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <86box/86box.h>
|
||||||
|
#include <86box/device.h>
|
||||||
|
#include <86box/io.h>
|
||||||
|
#include <86box/timer.h>
|
||||||
|
#include <86box/pci.h>
|
||||||
|
#include <86box/mem.h>
|
||||||
|
#include <86box/rom.h>
|
||||||
|
#include <86box/lpt.h>
|
||||||
|
#include <86box/serial.h>
|
||||||
|
#include <86box/fdd.h>
|
||||||
|
#include <86box/fdc.h>
|
||||||
|
#include <86box/sio.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t config_enable, cur_reg, regs[32],
|
||||||
|
fdc_dma, fdc_irq, uart_irq[2], lpt_dma, lpt_irq;
|
||||||
|
fdc_t *fdc;
|
||||||
|
serial_t *uart[2];
|
||||||
|
} vt82c686_t;
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
get_lpt_length(vt82c686_t *dev)
|
||||||
|
{
|
||||||
|
uint8_t length = 4;
|
||||||
|
|
||||||
|
if ((dev->regs[0x02] & 0x03) == 0x2)
|
||||||
|
length = 8;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_fdc_handler(vt82c686_t *dev)
|
||||||
|
{
|
||||||
|
uint16_t io_base = (dev->regs[0x03] & 0xfc) << 2;
|
||||||
|
|
||||||
|
fdc_remove(dev->fdc);
|
||||||
|
|
||||||
|
if (dev->regs[0x02] & 0x10)
|
||||||
|
fdc_set_base(dev->fdc, io_base);
|
||||||
|
|
||||||
|
fdc_set_irq(dev->fdc, dev->fdc_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_lpt_handler(vt82c686_t *dev)
|
||||||
|
{
|
||||||
|
uint16_t io_mask, io_base = dev->regs[0x06] << 2;
|
||||||
|
int io_len = get_lpt_length(dev);
|
||||||
|
io_base &= (0xff8 | io_len);
|
||||||
|
io_mask = 0x3fc;
|
||||||
|
if (io_len == 8)
|
||||||
|
io_mask = 0x3f8;
|
||||||
|
|
||||||
|
lpt1_remove();
|
||||||
|
|
||||||
|
if (((dev->regs[0x02] & 0x03) != 0x03) && (io_base >= 0x100) && (io_base <= io_mask))
|
||||||
|
lpt1_init(io_base);
|
||||||
|
|
||||||
|
lpt1_irq(dev->lpt_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_serial_handler(vt82c686_t *dev, int uart)
|
||||||
|
{
|
||||||
|
serial_remove(dev->uart[uart]);
|
||||||
|
|
||||||
|
if (dev->regs[0x02] & (uart ? 0x08 : 0x04))
|
||||||
|
serial_setup(dev->uart[uart], (dev->regs[0x07 + uart] & 0xfe) << 2, dev->uart_irq[uart]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_write(uint16_t port, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
|
||||||
|
if (!dev->config_enable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(port & 1)) {
|
||||||
|
/* Registers start at 0xE0 but we cut them down to start at 0x00. */
|
||||||
|
dev->cur_reg = (val & 0x1f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read-only registers */
|
||||||
|
if ((dev->cur_reg < 0x02) || (dev->cur_reg == 0x04) || (dev->cur_reg == 0x05) || ((dev->cur_reg >= 0xe9) && (dev->cur_reg < 0xee)) ||
|
||||||
|
(dev->cur_reg == 0xf3) || (dev->cur_reg == 0xf5) || (dev->cur_reg == 0xf7) || (dev->cur_reg >= 0xf9))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (dev->cur_reg) {
|
||||||
|
case 0x02:
|
||||||
|
dev->regs[dev->cur_reg] = val;
|
||||||
|
vt82c686_lpt_handler(dev);
|
||||||
|
vt82c686_serial_handler(dev, 0);
|
||||||
|
vt82c686_serial_handler(dev, 1);
|
||||||
|
vt82c686_fdc_handler(dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x03:
|
||||||
|
dev->regs[dev->cur_reg] = val;
|
||||||
|
vt82c686_fdc_handler(dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x06:
|
||||||
|
dev->regs[dev->cur_reg] = val;
|
||||||
|
vt82c686_lpt_handler(dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x07:
|
||||||
|
dev->regs[dev->cur_reg] = val;
|
||||||
|
vt82c686_serial_handler(dev, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x08:
|
||||||
|
dev->regs[dev->cur_reg] = val;
|
||||||
|
vt82c686_serial_handler(dev, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dev->regs[dev->cur_reg] = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
vt82c686_read(uint16_t port, void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
|
if (!(port & 1))
|
||||||
|
ret = dev->cur_reg | 0xe0;
|
||||||
|
else
|
||||||
|
ret = dev->regs[dev->cur_reg];
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Writes to Super I/O-related configuration space registers
|
||||||
|
of the VT82C686 PCI-ISA bridge are sent here by via_pipc.c */
|
||||||
|
void
|
||||||
|
vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
|
||||||
|
switch (addr) {
|
||||||
|
case 0x50:
|
||||||
|
dev->fdc_dma = val & 0x03;
|
||||||
|
vt82c686_fdc_handler(dev);
|
||||||
|
dev->lpt_dma = (val >> 2) & 0x03;
|
||||||
|
vt82c686_lpt_handler(dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x51:
|
||||||
|
dev->fdc_irq = val & 0x0f;
|
||||||
|
vt82c686_fdc_handler(dev);
|
||||||
|
dev->lpt_irq = val >> 4;
|
||||||
|
vt82c686_lpt_handler(dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x52:
|
||||||
|
dev->uart_irq[0] = val & 0x0f;
|
||||||
|
vt82c686_serial_handler(dev, 0);
|
||||||
|
dev->uart_irq[1] = val >> 4;
|
||||||
|
vt82c686_serial_handler(dev, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x85:
|
||||||
|
io_removehandler(0x3f0, 0x0002,
|
||||||
|
vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev);
|
||||||
|
if (val & 0x01)
|
||||||
|
io_sethandler(0x3f0, 0x0002,
|
||||||
|
vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev);
|
||||||
|
|
||||||
|
dev->config_enable = val & 0x02;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_reset(vt82c686_t *dev)
|
||||||
|
{
|
||||||
|
memset(dev->regs, 0, 20);
|
||||||
|
|
||||||
|
dev->regs[0x00] = 0x3c;
|
||||||
|
dev->regs[0x02] = 0x03;
|
||||||
|
dev->regs[0x03] = 0xfc;
|
||||||
|
dev->regs[0x06] = 0xde;
|
||||||
|
dev->regs[0x07] = 0xfe;
|
||||||
|
dev->regs[0x08] = 0xbe;
|
||||||
|
|
||||||
|
fdc_reset(dev->fdc);
|
||||||
|
|
||||||
|
serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
|
||||||
|
serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ);
|
||||||
|
|
||||||
|
vt82c686_lpt_handler(dev);
|
||||||
|
vt82c686_serial_handler(dev, 0);
|
||||||
|
vt82c686_serial_handler(dev, 1);
|
||||||
|
vt82c686_fdc_handler(dev);
|
||||||
|
|
||||||
|
vt82c686_sio_write(0x85, 0x00, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vt82c686_close(void *priv)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
vt82c686_init(const device_t *info)
|
||||||
|
{
|
||||||
|
vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t));
|
||||||
|
memset(dev, 0, sizeof(vt82c686_t));
|
||||||
|
|
||||||
|
dev->fdc = device_add(&fdc_at_smc_device);
|
||||||
|
dev->fdc_dma = 2;
|
||||||
|
|
||||||
|
dev->uart[0] = device_add_inst(&ns16550_device, 1);
|
||||||
|
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||||
|
|
||||||
|
dev->lpt_dma = 3;
|
||||||
|
|
||||||
|
vt82c686_reset(dev);
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const device_t via_vt82c686_sio_device = {
|
||||||
|
"VIA VT82C686 Integrated Super I/O",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
vt82c686_init, vt82c686_close, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -56,6 +56,11 @@ uhci_reg_read(uint16_t addr, void *p)
|
|||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
switch (addr & 0x1f) {
|
switch (addr & 0x1f) {
|
||||||
|
case 0x02:
|
||||||
|
/* Status */
|
||||||
|
ret = 0x00;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||||
/* Port status */
|
/* Port status */
|
||||||
ret = 0x00;
|
ret = 0x00;
|
||||||
|
|||||||
@@ -660,7 +660,7 @@ MCHOBJ := machine.o machine_table.o \
|
|||||||
m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \
|
m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \
|
||||||
m_at_misc.o
|
m_at_misc.o
|
||||||
|
|
||||||
DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o vpc2007.o \
|
DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o vpc2007.o \
|
||||||
smbus.o smbus_piix4.o \
|
smbus.o smbus_piix4.o \
|
||||||
keyboard.o \
|
keyboard.o \
|
||||||
keyboard_xt.o keyboard_at.o \
|
keyboard_xt.o keyboard_at.o \
|
||||||
@@ -675,7 +675,8 @@ SIOOBJ := sio_acc3221.o \
|
|||||||
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \
|
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \
|
||||||
sio_w83787f.o \
|
sio_w83787f.o \
|
||||||
sio_w83877f.o sio_w83977f.o \
|
sio_w83877f.o sio_w83977f.o \
|
||||||
sio_um8669f.o
|
sio_um8669f.o \
|
||||||
|
sio_vt82c686.o
|
||||||
|
|
||||||
FDDOBJ := fdd.o fdc.o fdc_pii15xb.o \
|
FDDOBJ := fdd.o fdc.o fdc_pii15xb.o \
|
||||||
fdi2raw.o \
|
fdi2raw.o \
|
||||||
|
|||||||
Reference in New Issue
Block a user