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:
parent
d5f07a8594
commit
99ca11d148
10 changed files with 765 additions and 2 deletions
310
src/vt82c586b.c
Normal file
310
src/vt82c586b.c
Normal 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);
|
||||
}
|
||||
Loading…
Reference in a new issue