Added initial emulation of FIC VA-503+ (Super 7).

This includes preliminary emulation of the VIA MVP3 northbridge, VT82C586B 'PIPC' southbridge, and Winbond W83877TF SuperIO chip.
This commit is contained in:
SarahW 2018-12-02 12:38:31 +00:00
commit 99ca11d148
10 changed files with 765 additions and 2 deletions

310
src/vt82c586b.c Normal file
View file

@ -0,0 +1,310 @@
#include <string.h>
#include "ibm.h"
#include "io.h"
#include "mem.h"
#include "pci.h"
#include "x86.h"
#include "vt82c586b.h"
static struct
{
uint8_t pci_isa_bridge_regs[256];
uint8_t ide_regs[256];
uint8_t usb_regs[256];
uint8_t power_regs[256];
uint8_t sysctrl;
} vt82c586b;
static uint8_t vt82c586b_read(int func, int addr, void *priv)
{
switch (func)
{
case 0:
return vt82c586b.pci_isa_bridge_regs[addr];
case 1:
return vt82c586b.ide_regs[addr];
case 2:
return vt82c586b.usb_regs[addr];
case 3:
return vt82c586b.power_regs[addr];
default:
return 0xff;
}
}
static void vt82c586b_pci_isa_bridge_write(int addr, uint8_t val)
{
/*Read-only addresses*/
if ((addr < 4) || (addr == 5) || (addr == 6)
|| (addr >= 8 && addr < 0x40)
|| (addr == 0x49)
|| (addr == 0x4b)
|| (addr >= 0x51 && addr < 0x54)
|| (addr >= 0x5d && addr < 0x60)
|| (addr >= 0x68 && addr < 0x6a)
|| (addr >= 0x71))
return;
switch (addr)
{
case 4:
vt82c586b.pci_isa_bridge_regs[4] = (val & 8) | 7;
break;
case 6:
vt82c586b.pci_isa_bridge_regs[6] &= ~(val & 0xb0);
break;
case 0x47:
if ((val & 0x81) == 0x81)
resetx86();
vt82c586b.pci_isa_bridge_regs[0x47] = val & 0xfe;
break;
case 0x55:
if (!(val & 0xf0))
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTD, val >> 4);
vt82c586b.pci_isa_bridge_regs[0x55] = val;
break;
case 0x56:
if (!(val & 0xf0))
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA, val >> 4);
if (!(val & 0x0f))
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTB, val & 0xf);
vt82c586b.pci_isa_bridge_regs[0x56] = val;
break;
case 0x57:
if (!(val & 0xf0))
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTC, val >> 4);
vt82c586b.pci_isa_bridge_regs[0x57] = val;
break;
default:
vt82c586b.pci_isa_bridge_regs[addr] = val;
break;
}
}
static void vt82c586b_ide_write(int addr, uint8_t val)
{
/*Read-only addresses*/
if ((addr < 6) || (addr == 8)
|| (addr >= 0xa && addr < 0x0d)
|| (addr >= 0x0e && addr < 0x20)
|| (addr >= 0x22 && addr < 0x3c)
|| (addr >= 0x3d && addr < 0x40)
|| (addr >= 0x54 && addr < 0x60)
|| (addr >= 0x52 && addr < 0x68)
|| (addr >= 0x62))
return;
switch (addr)
{
case 4:
vt82c586b.ide_regs[4] = (val & 8) | 7;
break;
case 6:
vt82c586b.ide_regs[6] &= ~(val & 0xb0);
break;
case 9:
vt82c586b.ide_regs[9] = (vt82c586b.pci_isa_bridge_regs[9] & ~0x70) | 0x8a;
break;
case 0x20:
vt82c586b.ide_regs[0x20] = (val & ~0xf) | 1;
break;
default:
vt82c586b.ide_regs[addr] = val;
break;
}
}
static void vt82c586b_usb_write(int addr, uint8_t val)
{
/*Read-only addresses*/
if ((addr < 7) || (addr >= 8 && addr < 0xd)
|| (addr >= 0xe && addr < 0x20)
|| (addr >= 0x22 && addr < 0x3c)
|| (addr >= 0x3e && addr < 0x40)
|| (addr >= 0x42 && addr < 0x44)
|| (addr >= 0x46 && addr < 0xc0)
|| (addr >= 0xc2))
return;
switch (addr)
{
case 7:
vt82c586b.usb_regs[7] = val & 0x7f;
break;
case 0x20:
vt82c586b.usb_regs[0x20] = (val & ~0x1f) | 1;
break;
default:
vt82c586b.usb_regs[addr] = val;
break;
}
}
static void vt82c586b_power_write(int addr, uint8_t val)
{
/*Read-only addresses*/
if ((addr < 0xd) || (addr >= 0xe && addr < 0x40)
|| (addr == 0x43)
|| (addr == 0x48)
|| (addr >= 0x4a && addr < 0x50)
|| (addr >= 0x54))
return;
switch (addr)
{
default:
vt82c586b.power_regs[addr] = val;
break;
}
}
static void vt82c586b_write(int func, int addr, uint8_t val, void *priv)
{
switch (func)
{
case 0:
vt82c586b_pci_isa_bridge_write(addr, val);
break;
case 1:
vt82c586b_ide_write(addr, val);
break;
case 2:
vt82c586b_usb_write(addr, val);
break;
case 3:
vt82c586b_power_write(addr, val);
break;
}
}
uint8_t vt82c586b_read_sysctrl(uint16_t port, void *p)
{
return vt82c586b.sysctrl;
}
void vt82c586b_write_sysctrl(uint16_t port, uint8_t val, void *p)
{
if ((mem_a20_alt ^ val) & 2)
{
mem_a20_alt = val & 2;
mem_a20_recalc();
}
if ((~vt82c586b.sysctrl & val) & 1)
{
softresetx86();
cpu_set_edx();
}
vt82c586b.sysctrl = val;
}
void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
{
pci_add_specific(card, vt82c586b_read, vt82c586b_write, NULL);
io_sethandler(0x0092, 0x0001, vt82c586b_read_sysctrl, NULL, NULL, vt82c586b_write_sysctrl, NULL, NULL, NULL);
memset(&vt82c586b, 0, sizeof(vt82c586b));
vt82c586b.pci_isa_bridge_regs[0x00] = 0x06; vt82c586b.pci_isa_bridge_regs[0x01] = 0x11; /*VIA*/
vt82c586b.pci_isa_bridge_regs[0x02] = 0x86; vt82c586b.pci_isa_bridge_regs[0x03] = 0x05; /*VT82C586B*/
vt82c586b.pci_isa_bridge_regs[0x04] = 0x0f; vt82c586b.pci_isa_bridge_regs[0x05] = 0x00;
vt82c586b.pci_isa_bridge_regs[0x06] = 0x00; vt82c586b.pci_isa_bridge_regs[0x07] = 0x02;
vt82c586b.pci_isa_bridge_regs[0x0a] = 0x01;
vt82c586b.pci_isa_bridge_regs[0x0b] = 0x06;
vt82c586b.pci_isa_bridge_regs[0x0e] = 0x80;
/*ISA bus control*/
vt82c586b.pci_isa_bridge_regs[0x48] = 0x01;
vt82c586b.pci_isa_bridge_regs[0x4a] = 0x04;
vt82c586b.pci_isa_bridge_regs[0x4f] = 0x03;
/*Plug and Play control*/
vt82c586b.pci_isa_bridge_regs[0x50] = 0x24;
vt82c586b.pci_isa_bridge_regs[0x59] = 0x04;
vt82c586b.ide_regs[0x00] = 0x06; vt82c586b.ide_regs[0x01] = 0x11; /*VIA*/
vt82c586b.ide_regs[0x02] = 0x71; vt82c586b.ide_regs[0x03] = 0x05;
vt82c586b.ide_regs[0x04] = 0x80; vt82c586b.ide_regs[0x05] = 0x00;
vt82c586b.ide_regs[0x06] = 0x80; vt82c586b.ide_regs[0x07] = 0x02;
vt82c586b.ide_regs[0x09] = 0x85;
vt82c586b.ide_regs[0x0a] = 0x01;
vt82c586b.ide_regs[0x0b] = 0x01;
vt82c586b.ide_regs[0x10] = 0xf1; vt82c586b.ide_regs[0x11] = 0x01;
vt82c586b.ide_regs[0x14] = 0xf5; vt82c586b.ide_regs[0x15] = 0x03;
vt82c586b.ide_regs[0x18] = 0x71; vt82c586b.ide_regs[0x19] = 0x01;
vt82c586b.ide_regs[0x1c] = 0x75; vt82c586b.ide_regs[0x1d] = 0x03;
vt82c586b.ide_regs[0x20] = 0x01; vt82c586b.ide_regs[0x21] = 0xcc;
vt82c586b.ide_regs[0x3c] = 0x0e;
vt82c586b.ide_regs[0x40] = 0x08;
vt82c586b.ide_regs[0x41] = 0x02;
vt82c586b.ide_regs[0x42] = 0x09;
vt82c586b.ide_regs[0x43] = 0x3a;
vt82c586b.ide_regs[0x44] = 0x68;
vt82c586b.ide_regs[0x46] = 0xc0;
vt82c586b.ide_regs[0x48] = 0xa8;
vt82c586b.ide_regs[0x49] = 0xa8;
vt82c586b.ide_regs[0x4a] = 0xa8;
vt82c586b.ide_regs[0x4b] = 0xa8;
vt82c586b.ide_regs[0x4c] = 0xff;
vt82c586b.ide_regs[0x4e] = 0xff;
vt82c586b.ide_regs[0x4f] = 0xff;
vt82c586b.ide_regs[0x50] = 0x03;
vt82c586b.ide_regs[0x51] = 0x03;
vt82c586b.ide_regs[0x52] = 0x03;
vt82c586b.ide_regs[0x53] = 0x03;
vt82c586b.ide_regs[0x61] = 0x02;
vt82c586b.ide_regs[0x68] = 0x02;
vt82c586b.usb_regs[0x00] = 0x06; vt82c586b.usb_regs[0x01] = 0x11; /*VIA*/
vt82c586b.usb_regs[0x02] = 0x38; vt82c586b.usb_regs[0x03] = 0x30;
vt82c586b.usb_regs[0x04] = 0x00; vt82c586b.usb_regs[0x05] = 0x00;
vt82c586b.usb_regs[0x06] = 0x00; vt82c586b.usb_regs[0x07] = 0x02;
vt82c586b.usb_regs[0x0a] = 0x03;
vt82c586b.usb_regs[0x0b] = 0x0c;
vt82c586b.usb_regs[0x0d] = 0x16;
vt82c586b.usb_regs[0x20] = 0x01;
vt82c586b.usb_regs[0x21] = 0x03;
vt82c586b.usb_regs[0x3d] = 0x04;
vt82c586b.usb_regs[0x60] = 0x10;
vt82c586b.usb_regs[0xc1] = 0x20;
vt82c586b.power_regs[0x00] = 0x06; vt82c586b.power_regs[0x01] = 0x11; /*VIA*/
vt82c586b.power_regs[0x02] = 0x40; vt82c586b.power_regs[0x03] = 0x30;
vt82c586b.power_regs[0x04] = 0x00; vt82c586b.power_regs[0x05] = 0x00;
vt82c586b.power_regs[0x06] = 0x80; vt82c586b.power_regs[0x07] = 0x02;
vt82c586b.power_regs[0x08] = 0x10; /*Production version (3041)*/
vt82c586b.power_regs[0x48] = 0x01;
if (pci_a)
pci_set_card_routing(pci_a, PCI_INTA);
if (pci_b)
pci_set_card_routing(pci_b, PCI_INTB);
if (pci_c)
pci_set_card_routing(pci_c, PCI_INTC);
if (pci_d)
pci_set_card_routing(pci_d, PCI_INTD);
}