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
|
|
@ -465,6 +465,7 @@ enum
|
|||
ROM_XI8088,
|
||||
ROM_IBMPS2_M70_TYPE3,
|
||||
ROM_IBMPS2_M70_TYPE4,
|
||||
ROM_FIC_VA503P,
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
|
|
|||
|
|
@ -900,6 +900,14 @@ int loadbios()
|
|||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_FIC_VA503P:
|
||||
f = romfopen("fic_va503p/je4333.bin","rb");
|
||||
if (!f) break;
|
||||
romfread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
|
|
|
|||
18
src/model.c
18
src/model.c
|
|
@ -34,6 +34,7 @@
|
|||
#include "lpt.h"
|
||||
#include "mem.h"
|
||||
#include "mouse_ps2.h"
|
||||
#include "mvp3.h"
|
||||
#include "neat.h"
|
||||
#include "nmi.h"
|
||||
#include "nvr.h"
|
||||
|
|
@ -61,6 +62,8 @@
|
|||
#include "vid_pcjr.h"
|
||||
#include "vid_tandy.h"
|
||||
#include "vid_t1000.h"
|
||||
#include "vt82c586b.h"
|
||||
#include "w83877tf.h"
|
||||
#include "wd76c10.h"
|
||||
#include "xi8088.h"
|
||||
|
||||
|
|
@ -106,6 +109,7 @@ void at_pb520r_init();
|
|||
void at_pb570_init();
|
||||
void compaq_pip_init();
|
||||
void xt_xi8088_init();
|
||||
void at_mvp3_init();
|
||||
int model;
|
||||
|
||||
int AMSTRAD, AT, PCI, TANDY;
|
||||
|
|
@ -189,6 +193,8 @@ MODEL models[] =
|
|||
|
||||
{"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL},
|
||||
|
||||
{"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL},
|
||||
|
||||
{"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -659,6 +665,18 @@ void at_i430vx_init()
|
|||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
void at_mvp3_init()
|
||||
{
|
||||
at_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_slot(8);
|
||||
pci_slot(9);
|
||||
pci_slot(10);
|
||||
mvp3_init();
|
||||
vt82c586b_init(7, 8, 9, 10, 0);
|
||||
w83877tf_init();
|
||||
}
|
||||
|
||||
void model_init()
|
||||
{
|
||||
pclog("Initting as %s\n", model_getname());
|
||||
|
|
|
|||
219
src/mvp3.c
Normal file
219
src/mvp3.c
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "mvp3.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
uint8_t host_bridge_regs[256];
|
||||
uint8_t pci_bridge_regs[256];
|
||||
} mvp3;
|
||||
|
||||
static void mvp3_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
pclog("mvp3_map: addr=%08x size=%08x state=%i\n", addr, size, state);
|
||||
switch (state & 3)
|
||||
{
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static uint8_t mvp3_read(int func, int addr, void *priv)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case 0:
|
||||
return mvp3.host_bridge_regs[addr];
|
||||
|
||||
case 1:
|
||||
return mvp3.pci_bridge_regs[addr];
|
||||
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mvp3_host_bridge_write(int addr, uint8_t val)
|
||||
{
|
||||
/*Read-only addresses*/
|
||||
if ((addr < 4) || (addr >= 5 && addr < 7)
|
||||
|| (addr >= 8 && addr < 0xd)
|
||||
|| (addr >= 0xe && addr < 0x12)
|
||||
|| (addr >= 0x14 && addr < 0x50)
|
||||
|| (addr >= 0x79 && addr < 0x7e)
|
||||
|| (addr >= 0x85 && addr < 0x88)
|
||||
|| (addr >= 0x8c && addr < 0xa8)
|
||||
|| (addr >= 0xad && addr < 0xfd))
|
||||
return;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04: /*Command*/
|
||||
mvp3.host_bridge_regs[0x04] = (mvp3.host_bridge_regs[0x04] & ~0x40) | (val & 0x40);
|
||||
break;
|
||||
case 0x07: /*Status*/
|
||||
mvp3.host_bridge_regs[0x07] &= ~(val & 0xb0);
|
||||
break;
|
||||
|
||||
case 0x12: /*Graphics Aperture Base*/
|
||||
mvp3.host_bridge_regs[0x12] = (val & 0xf0);
|
||||
break;
|
||||
case 0x13: /*Graphics Aperture Base*/
|
||||
mvp3.host_bridge_regs[0x13] = val;
|
||||
break;
|
||||
|
||||
case 0x61: /*Shadow RAM Control 1*/
|
||||
if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x03)
|
||||
mvp3_map(0xc0000, 0x04000, val & 0x03);
|
||||
if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x0c)
|
||||
mvp3_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
|
||||
if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x30)
|
||||
mvp3_map(0xc8000, 0x04000, (val & 0x30) >> 4);
|
||||
if ((mvp3.host_bridge_regs[0x61] ^ val) & 0xc0)
|
||||
mvp3_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
|
||||
mvp3.host_bridge_regs[0x61] = val;
|
||||
return;
|
||||
case 0x62: /*Shadow RAM Control 2*/
|
||||
if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x03)
|
||||
mvp3_map(0xd0000, 0x04000, val & 0x03);
|
||||
if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x0c)
|
||||
mvp3_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
|
||||
if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x30)
|
||||
mvp3_map(0xd8000, 0x04000, (val & 0x30) >> 4);
|
||||
if ((mvp3.host_bridge_regs[0x62] ^ val) & 0xc0)
|
||||
mvp3_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
|
||||
mvp3.host_bridge_regs[0x62] = val;
|
||||
return;
|
||||
case 0x63: /*Shadow RAM Control 3*/
|
||||
if ((mvp3.host_bridge_regs[0x63] ^ val) & 0x30)
|
||||
mvp3_map(0xf0000, 0x10000, (val & 0x30) >> 4);
|
||||
if ((mvp3.host_bridge_regs[0x63] ^ val) & 0xc0)
|
||||
mvp3_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
|
||||
mvp3.host_bridge_regs[0x63] = val;
|
||||
// if (val == 0xb0)
|
||||
// output = 3;
|
||||
return;
|
||||
|
||||
default:
|
||||
mvp3.host_bridge_regs[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void mvp3_pci_bridge_write(int addr, uint8_t val)
|
||||
{
|
||||
/*Read-only addresses*/
|
||||
if ((addr < 4) || (addr >= 5 && addr < 7)
|
||||
|| (addr >= 8 && addr < 0x18)
|
||||
|| (addr == 0x1b)
|
||||
|| (addr >= 0x1e && addr < 0x20)
|
||||
|| (addr >= 0x28 && addr < 0x3e)
|
||||
|| (addr >= 0x43))
|
||||
return;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04: /*Command*/
|
||||
mvp3.pci_bridge_regs[0x04] = (mvp3.pci_bridge_regs[0x04] & ~0x47) | (val & 0x47);
|
||||
break;
|
||||
case 0x07: /*Status*/
|
||||
mvp3.pci_bridge_regs[0x07] &= ~(val & 0x30);
|
||||
break;
|
||||
|
||||
case 0x20: /*Memory Base*/
|
||||
mvp3.pci_bridge_regs[0x20] = val & 0xf0;
|
||||
break;
|
||||
case 0x22: /*Memory Limit*/
|
||||
mvp3.pci_bridge_regs[0x22] = val & 0xf0;
|
||||
break;
|
||||
case 0x24: /*Prefetchable Memory Base*/
|
||||
mvp3.pci_bridge_regs[0x24] = val & 0xf0;
|
||||
break;
|
||||
case 0x26: /*Prefetchable Memory Limit*/
|
||||
mvp3.pci_bridge_regs[0x26] = val & 0xf0;
|
||||
break;
|
||||
|
||||
default:
|
||||
mvp3.pci_bridge_regs[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mvp3_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case 0:
|
||||
mvp3_host_bridge_write(addr, val);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mvp3_pci_bridge_write(addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mvp3_init()
|
||||
{
|
||||
pci_add_specific(0, mvp3_read, mvp3_write, NULL);
|
||||
|
||||
memset(&mvp3, 0, sizeof(mvp3));
|
||||
mvp3.host_bridge_regs[0x00] = 0x06; mvp3.host_bridge_regs[0x01] = 0x11; /*VIA*/
|
||||
mvp3.host_bridge_regs[0x02] = 0x98; mvp3.host_bridge_regs[0x03] = 0x05; /*VT82C598MVP*/
|
||||
mvp3.host_bridge_regs[0x04] = 0x06; mvp3.host_bridge_regs[0x05] = 0x00;
|
||||
mvp3.host_bridge_regs[0x06] = 0x90; mvp3.host_bridge_regs[0x07] = 0x02;
|
||||
mvp3.host_bridge_regs[0x0b] = 0x06;
|
||||
mvp3.host_bridge_regs[0x10] = 0x08;
|
||||
mvp3.host_bridge_regs[0x34] = 0xa0;
|
||||
|
||||
mvp3.host_bridge_regs[0x5a] = 0x01;
|
||||
mvp3.host_bridge_regs[0x5b] = 0x01;
|
||||
mvp3.host_bridge_regs[0x5c] = 0x01;
|
||||
mvp3.host_bridge_regs[0x5d] = 0x01;
|
||||
mvp3.host_bridge_regs[0x5e] = 0x01;
|
||||
mvp3.host_bridge_regs[0x5f] = 0x01;
|
||||
|
||||
mvp3.host_bridge_regs[0x64] = 0xec;
|
||||
mvp3.host_bridge_regs[0x65] = 0xec;
|
||||
mvp3.host_bridge_regs[0x66] = 0xec;
|
||||
mvp3.host_bridge_regs[0x6b] = 0x01;
|
||||
|
||||
mvp3.host_bridge_regs[0xa0] = 0x02;
|
||||
mvp3.host_bridge_regs[0xa2] = 0x10;
|
||||
mvp3.host_bridge_regs[0xa4] = 0x03;
|
||||
mvp3.host_bridge_regs[0xa5] = 0x02;
|
||||
mvp3.host_bridge_regs[0xa6] = 0x00;
|
||||
mvp3.host_bridge_regs[0xa7] = 0x07;
|
||||
|
||||
mvp3.pci_bridge_regs[0x00] = 0x06; mvp3.pci_bridge_regs[0x01] = 0x11; /*VIA*/
|
||||
mvp3.pci_bridge_regs[0x02] = 0x98; mvp3.pci_bridge_regs[0x03] = 0x85; /*VT82C598MVP*/
|
||||
mvp3.pci_bridge_regs[0x04] = 0x07; mvp3.pci_bridge_regs[0x05] = 0x00;
|
||||
mvp3.pci_bridge_regs[0x06] = 0x20; mvp3.pci_bridge_regs[0x07] = 0x02;
|
||||
mvp3.pci_bridge_regs[0x0a] = 0x04;
|
||||
mvp3.pci_bridge_regs[0x0b] = 0x06;
|
||||
mvp3.pci_bridge_regs[0x0e] = 0x01;
|
||||
|
||||
mvp3.pci_bridge_regs[0x1c] = 0xf0;
|
||||
|
||||
mvp3.pci_bridge_regs[0x20] = 0xf0;
|
||||
mvp3.pci_bridge_regs[0x21] = 0xff;
|
||||
|
||||
mvp3.pci_bridge_regs[0x24] = 0xf0;
|
||||
mvp3.pci_bridge_regs[0x25] = 0xff;
|
||||
}
|
||||
1
src/mvp3.h
Normal file
1
src/mvp3.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void mvp3_init();
|
||||
|
|
@ -306,7 +306,8 @@ void loadnvr()
|
|||
case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break;
|
||||
case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break;
|
||||
|
||||
case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
if (!f)
|
||||
|
|
@ -396,7 +397,8 @@ void savenvr()
|
|||
case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); break;
|
||||
case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break;
|
||||
case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break;
|
||||
|
||||
case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
fwrite(nvrram,128,1,f);
|
||||
|
|
|
|||
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);
|
||||
}
|
||||
1
src/vt82c586b.h
Normal file
1
src/vt82c586b.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d);
|
||||
202
src/w83877tf.c
Normal file
202
src/w83877tf.c
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "fdc.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "serial.h"
|
||||
#include "w83877tf.h"
|
||||
|
||||
typedef struct w83877tf_t
|
||||
{
|
||||
int enable_regs;
|
||||
uint8_t key[2];
|
||||
int index;
|
||||
uint8_t regs[256];
|
||||
} w83877tf_t;
|
||||
|
||||
static w83877tf_t w83877tf_global;
|
||||
|
||||
static void w83877tf_write_25x(uint16_t port, uint8_t val, void *p);
|
||||
static uint8_t w83877tf_read_25x(uint16_t port, void *p);
|
||||
static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p);
|
||||
static uint8_t w83877tf_read_3fx(uint16_t port, void *p);
|
||||
|
||||
static void w83877tf_write_reg(w83877tf_t *w83877tf, int index, uint8_t val)
|
||||
{
|
||||
// pclog("w83877tf_write: index=%02x val=%02x\n", index, val);
|
||||
switch (index)
|
||||
{
|
||||
case 0x16:
|
||||
if (val == 2) /*Written by VA-503+ BIOS. Apparently should not change IO mapping*/
|
||||
return;
|
||||
|
||||
io_removehandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global);
|
||||
io_removehandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global);
|
||||
if (val & 0x01)
|
||||
io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global);
|
||||
else
|
||||
io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global);
|
||||
|
||||
if ((w83877tf->regs[0x16] & 4) && !(val & 4))
|
||||
{
|
||||
w83877tf->regs[0x20] = 0;
|
||||
w83877tf->regs[0x23] = 0;
|
||||
w83877tf->regs[0x24] = 0;
|
||||
w83877tf->regs[0x25] = 0;
|
||||
w83877tf->regs[0x26] = 0;
|
||||
w83877tf->regs[0x27] = 0;
|
||||
w83877tf->regs[0x28] = 0;
|
||||
w83877tf->regs[0x29] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
w83877tf->regs[index] = val;
|
||||
|
||||
|
||||
fdc_remove();
|
||||
if (w83877tf->regs[0x20] >= 0x40)
|
||||
fdc_add();
|
||||
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
if (w83877tf->regs[0x23] >= 0x40)
|
||||
lpt1_init(w83877tf->regs[0x23] << 2);
|
||||
|
||||
serial1_remove();
|
||||
if (w83877tf->regs[0x24] >= 0x40)
|
||||
serial1_set((w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4);
|
||||
|
||||
serial2_remove();
|
||||
if (w83877tf->regs[0x25] >= 0x40)
|
||||
serial2_set((w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf);
|
||||
|
||||
// pclog("LPT at %04x\n", w83877tf->regs[0x23] << 2);
|
||||
// pclog("Serial1 at %04x %i\n", (w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4);
|
||||
// pclog("Serial2 at %04x %i\n", (w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf);
|
||||
}
|
||||
|
||||
static uint8_t w83877tf_read_reg(w83877tf_t *w83877tf, int index)
|
||||
{
|
||||
switch (w83877tf->index)
|
||||
{
|
||||
case 0x09:
|
||||
return 0x0c; /*W83877TF ID*/
|
||||
}
|
||||
return w83877tf->regs[index];
|
||||
}
|
||||
|
||||
static void w83877tf_write_25x(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
w83877tf_t *w83877tf = (w83877tf_t *)p;
|
||||
|
||||
// pclog("w83877tf_write: port=%04x val=%02x\n", port, val);
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0x250: /*Enable register*/
|
||||
w83877tf->enable_regs = (val == 0x89) ? 1 : 0;
|
||||
break;
|
||||
case 0x251: /*Index*/
|
||||
if (w83877tf->enable_regs)
|
||||
w83877tf->index = val;
|
||||
break;
|
||||
case 0x252: /*Data*/
|
||||
if (w83877tf->enable_regs)
|
||||
w83877tf_write_reg(w83877tf, w83877tf->index, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t w83877tf_read_25x(uint16_t port, void *p)
|
||||
{
|
||||
w83877tf_t *w83877tf = (w83877tf_t *)p;
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0x251: /*Index*/
|
||||
if (w83877tf->enable_regs)
|
||||
return w83877tf->index;
|
||||
break;
|
||||
|
||||
case 0x252: /*Data*/
|
||||
if (w83877tf->enable_regs)
|
||||
return w83877tf_read_reg(w83877tf, w83877tf->index);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
w83877tf_t *w83877tf = (w83877tf_t *)p;
|
||||
|
||||
// pclog("w83877tf_write: port=%04x val=%02x\n", port, val);
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0x3f0: /*Enable/index register*/
|
||||
if (val == 0xaa)
|
||||
w83877tf->enable_regs = 0;
|
||||
else if (!w83877tf->enable_regs)
|
||||
{
|
||||
w83877tf->key[1] = w83877tf->key[0];
|
||||
w83877tf->key[0] = val;
|
||||
w83877tf->enable_regs = (w83877tf->key[0] == 0x87 && w83877tf->key[1] == 0x87);
|
||||
}
|
||||
else
|
||||
w83877tf->index = val;
|
||||
break;
|
||||
case 0x3f1: /*Data*/
|
||||
if (w83877tf->enable_regs)
|
||||
w83877tf_write_reg(w83877tf, w83877tf->index, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t w83877tf_read_3fx(uint16_t port, void *p)
|
||||
{
|
||||
w83877tf_t *w83877tf = (w83877tf_t *)p;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0x3f0: /*Index*/
|
||||
if (w83877tf->enable_regs)
|
||||
ret = w83877tf->index;
|
||||
break;
|
||||
|
||||
case 0x3f1: /*Data*/
|
||||
if (w83877tf->enable_regs)
|
||||
ret = w83877tf_read_reg(w83877tf, w83877tf->index);
|
||||
break;
|
||||
}
|
||||
|
||||
// pclog("w83877tf_read: port=%04x val=%02x\n", port, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void w83877tf_init()
|
||||
{
|
||||
memset(&w83877tf_global, 0, sizeof(w83877tf_t));
|
||||
|
||||
io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global);
|
||||
|
||||
/*Defaults*/
|
||||
w83877tf_global.regs[0x03] = 0x30;
|
||||
w83877tf_global.regs[0x09] = 0x0c;
|
||||
w83877tf_global.regs[0x0b] = 0x0c;
|
||||
w83877tf_global.regs[0x0c] = 0x28;
|
||||
w83877tf_global.regs[0x0d] = 0xa3;
|
||||
w83877tf_global.regs[0x16] = 0x04;
|
||||
w83877tf_global.regs[0x20] = 0xfc;
|
||||
w83877tf_global.regs[0x23] = 0xde;
|
||||
w83877tf_global.regs[0x24] = 0xfe;
|
||||
w83877tf_global.regs[0x25] = 0xbe;
|
||||
w83877tf_global.regs[0x26] = 0x23;
|
||||
w83877tf_global.regs[0x27] = 0x05;
|
||||
w83877tf_global.regs[0x28] = 0x43;
|
||||
w83877tf_global.regs[0x29] = 0x60;
|
||||
}
|
||||
1
src/w83877tf.h
Normal file
1
src/w83877tf.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void w83877tf_init();
|
||||
Loading…
Reference in a new issue