clang-format in src/chipset/
This commit is contained in:
@@ -30,76 +30,70 @@
|
||||
#include <86box/rom.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int enabled;
|
||||
uint32_t virt, phys;
|
||||
int enabled;
|
||||
uint32_t virt, phys;
|
||||
} ems_page_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, access;
|
||||
uint16_t ems_io_base;
|
||||
uint32_t ems_window_base;
|
||||
uint8_t ems_page_regs[4],
|
||||
regs[256];
|
||||
ems_page_t ems_pages[4];
|
||||
mem_mapping_t ems_mappings[4];
|
||||
uint8_t index, access;
|
||||
uint16_t ems_io_base;
|
||||
uint32_t ems_window_base;
|
||||
uint8_t ems_page_regs[4],
|
||||
regs[256];
|
||||
ems_page_t ems_pages[4];
|
||||
mem_mapping_t ems_mappings[4];
|
||||
} ct_82c100_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_CT_82C100_LOG
|
||||
int ct_82c100_do_log = ENABLE_CT82C100_LOG;
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ct_82c100_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ct_82c100_log(fmt, ...)
|
||||
# define ct_82c100_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_ems_pages_recalc(ct_82c100_t *dev)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
uint32_t page_base;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
page_base = dev->ems_window_base + (i << 14);
|
||||
if ((i == 1) || (i == 2))
|
||||
page_base ^= 0xc000;
|
||||
if (dev->ems_page_regs[i] & 0x80) {
|
||||
dev->ems_pages[i].virt = page_base;
|
||||
dev->ems_pages[i].phys = 0xa0000 + (((uint32_t) (dev->ems_page_regs[i] & 0x7f)) << 14);
|
||||
ct_82c100_log("Enabling EMS page %i: %08X-%08X -> %08X-%08X\n", i,
|
||||
dev->ems_pages[i].virt, dev->ems_pages[i].virt + 0x00003fff,
|
||||
dev->ems_pages[i].phys, dev->ems_pages[i].phys + 0x00003fff);
|
||||
mem_mapping_set_addr(&(dev->ems_mappings[i]), dev->ems_pages[i].virt, 0x4000);
|
||||
mem_mapping_set_exec(&(dev->ems_mappings[i]), &(ram[dev->ems_pages[i].phys]));
|
||||
mem_set_mem_state_both(page_base, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
ct_82c100_log("Disabling EMS page %i\n", i);
|
||||
mem_mapping_disable(&(dev->ems_mappings[i]));
|
||||
mem_set_mem_state_both(page_base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
page_base = dev->ems_window_base + (i << 14);
|
||||
if ((i == 1) || (i == 2))
|
||||
page_base ^= 0xc000;
|
||||
if (dev->ems_page_regs[i] & 0x80) {
|
||||
dev->ems_pages[i].virt = page_base;
|
||||
dev->ems_pages[i].phys = 0xa0000 + (((uint32_t) (dev->ems_page_regs[i] & 0x7f)) << 14);
|
||||
ct_82c100_log("Enabling EMS page %i: %08X-%08X -> %08X-%08X\n", i,
|
||||
dev->ems_pages[i].virt, dev->ems_pages[i].virt + 0x00003fff,
|
||||
dev->ems_pages[i].phys, dev->ems_pages[i].phys + 0x00003fff);
|
||||
mem_mapping_set_addr(&(dev->ems_mappings[i]), dev->ems_pages[i].virt, 0x4000);
|
||||
mem_mapping_set_exec(&(dev->ems_mappings[i]), &(ram[dev->ems_pages[i].phys]));
|
||||
mem_set_mem_state_both(page_base, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
ct_82c100_log("Disabling EMS page %i\n", i);
|
||||
mem_mapping_disable(&(dev->ems_mappings[i]));
|
||||
mem_set_mem_state_both(page_base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_ems_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -110,36 +104,34 @@ ct_82c100_ems_out(uint16_t port, uint8_t val, void *priv)
|
||||
ct_82c100_ems_pages_recalc(dev);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ct_82c100_ems_in(uint16_t port, void *priv)
|
||||
{
|
||||
ct_82c100_t *dev = (ct_82c100_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->ems_page_regs[port >> 14];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_ems_update(ct_82c100_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ct_82c100_log("Disabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14));
|
||||
io_handler(0, dev->ems_io_base + (i << 14), 1,
|
||||
ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev);
|
||||
ct_82c100_log("Disabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14));
|
||||
io_handler(0, dev->ems_io_base + (i << 14), 1,
|
||||
ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->ems_io_base = 0x0208 + (dev->regs[0x4c] & 0xf0);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ct_82c100_log("Enabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14));
|
||||
io_handler(1, dev->ems_io_base + (i << 14), 1,
|
||||
ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev);
|
||||
ct_82c100_log("Enabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14));
|
||||
io_handler(1, dev->ems_io_base + (i << 14), 1,
|
||||
ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->ems_window_base = 0xc0000 + (((uint32_t) (dev->regs[0x4c] & 0x0f)) << 14);
|
||||
@@ -147,7 +139,6 @@ ct_82c100_ems_update(ct_82c100_t *dev)
|
||||
ct_82c100_ems_pages_recalc(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_reset(void *priv)
|
||||
{
|
||||
@@ -161,7 +152,7 @@ ct_82c100_reset(void *priv)
|
||||
dev->index = dev->access = 0x00;
|
||||
|
||||
/* INTERNAL CONFIGURATION/CONTROL REGISTERS */
|
||||
dev->regs[0x40] = 0x01; /* Defaults to 8086/V30 mode. */
|
||||
dev->regs[0x40] = 0x01; /* Defaults to 8086/V30 mode. */
|
||||
dev->regs[0x43] = 0x30;
|
||||
dev->regs[0x48] = 0x01;
|
||||
|
||||
@@ -171,188 +162,183 @@ ct_82c100_reset(void *priv)
|
||||
/* ADDITIONAL I/O REGISTERS */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
ct_82c100_t *dev = (ct_82c100_t *) priv;
|
||||
|
||||
if (port == 0x0022) {
|
||||
dev->index = val;
|
||||
dev->access = 1;
|
||||
dev->index = val;
|
||||
dev->access = 1;
|
||||
} else if (port == 0x0023) {
|
||||
if (dev->access) {
|
||||
switch (dev->index) {
|
||||
/* INTERNAL CONFIGURATION/CONTROL REGISTERS */
|
||||
case 0x40:
|
||||
dev->regs[0x40] = val & 0xc7;
|
||||
/* TODO: Clock stuff - needs CPU speed change functionality that's
|
||||
going to be implemented in 86box v4.0.
|
||||
Bit 0 is 0 for 8088/V20 and 1 for 8086/V30. */
|
||||
break;
|
||||
case 0x41:
|
||||
dev->regs[0x41] = val & 0xed;
|
||||
/* TODO: Where is the Software Reset Function that's enabled by
|
||||
setting bit 6 to 1? */
|
||||
break;
|
||||
case 0x42:
|
||||
dev->regs[0x42] = val & 0x01;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->regs[0x43] = val;
|
||||
break;
|
||||
case 0x44:
|
||||
dev->regs[0x44] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0xffffff00) | ((uint32_t) val);
|
||||
break;
|
||||
case 0x45:
|
||||
dev->regs[0x45] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0xffff00ff) | (((uint32_t) val) << 8);
|
||||
break;
|
||||
case 0x46:
|
||||
dev->regs[0x46] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0xff00ffff) | (((uint32_t) val) << 16);
|
||||
break;
|
||||
case 0x47:
|
||||
dev->regs[0x47] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0x00ffffff) | (((uint32_t) val) << 24);
|
||||
break;
|
||||
case 0x48: case 0x49:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x4b:
|
||||
dev->regs[0x4b] = val;
|
||||
use_custom_nmi_vector = !!(val & 0x40);
|
||||
break;
|
||||
case 0x4c:
|
||||
ct_82c100_log("CS4C: %02X\n", val);
|
||||
dev->regs[0x4c] = val;
|
||||
ct_82c100_ems_update(dev);
|
||||
break;
|
||||
}
|
||||
dev->access = 0;
|
||||
}
|
||||
if (dev->access) {
|
||||
switch (dev->index) {
|
||||
/* INTERNAL CONFIGURATION/CONTROL REGISTERS */
|
||||
case 0x40:
|
||||
dev->regs[0x40] = val & 0xc7;
|
||||
/* TODO: Clock stuff - needs CPU speed change functionality that's
|
||||
going to be implemented in 86box v4.0.
|
||||
Bit 0 is 0 for 8088/V20 and 1 for 8086/V30. */
|
||||
break;
|
||||
case 0x41:
|
||||
dev->regs[0x41] = val & 0xed;
|
||||
/* TODO: Where is the Software Reset Function that's enabled by
|
||||
setting bit 6 to 1? */
|
||||
break;
|
||||
case 0x42:
|
||||
dev->regs[0x42] = val & 0x01;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->regs[0x43] = val;
|
||||
break;
|
||||
case 0x44:
|
||||
dev->regs[0x44] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0xffffff00) | ((uint32_t) val);
|
||||
break;
|
||||
case 0x45:
|
||||
dev->regs[0x45] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0xffff00ff) | (((uint32_t) val) << 8);
|
||||
break;
|
||||
case 0x46:
|
||||
dev->regs[0x46] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0xff00ffff) | (((uint32_t) val) << 16);
|
||||
break;
|
||||
case 0x47:
|
||||
dev->regs[0x47] = val;
|
||||
custom_nmi_vector = (custom_nmi_vector & 0x00ffffff) | (((uint32_t) val) << 24);
|
||||
break;
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x4b:
|
||||
dev->regs[0x4b] = val;
|
||||
use_custom_nmi_vector = !!(val & 0x40);
|
||||
break;
|
||||
case 0x4c:
|
||||
ct_82c100_log("CS4C: %02X\n", val);
|
||||
dev->regs[0x4c] = val;
|
||||
ct_82c100_ems_update(dev);
|
||||
break;
|
||||
}
|
||||
dev->access = 0;
|
||||
}
|
||||
} else if (port == 0x72)
|
||||
dev->regs[0x72] = val & 0x7e;
|
||||
dev->regs[0x72] = val & 0x7e;
|
||||
else if (port == 0x7e)
|
||||
dev->regs[0x7e] = val;
|
||||
dev->regs[0x7e] = val;
|
||||
else if (port == 0x7f) {
|
||||
/* Bit 3 is Software Controlled Reset, asserted if set. Will be
|
||||
done in the feature/machine_and_kb branch using hardresetx86(). */
|
||||
dev->regs[0x7f] = val;
|
||||
if ((dev->regs[0x41] & 0x40) && (val & 0x08)) {
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
ct_82c100_reset(dev);
|
||||
}
|
||||
/* Bit 3 is Software Controlled Reset, asserted if set. Will be
|
||||
done in the feature/machine_and_kb branch using hardresetx86(). */
|
||||
dev->regs[0x7f] = val;
|
||||
if ((dev->regs[0x41] & 0x40) && (val & 0x08)) {
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
ct_82c100_reset(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ct_82c100_in(uint16_t port, void *priv)
|
||||
{
|
||||
ct_82c100_t *dev = (ct_82c100_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port == 0x0022)
|
||||
ret = dev->index;
|
||||
ret = dev->index;
|
||||
else if (port == 0x0023) {
|
||||
if (dev->access) {
|
||||
switch (dev->index) {
|
||||
/* INTERNAL CONFIGURATION/CONTROL REGISTERS */
|
||||
case 0x40 ... 0x49:
|
||||
case 0x4b: case 0x4c:
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
}
|
||||
dev->access = 0;
|
||||
}
|
||||
if (dev->access) {
|
||||
switch (dev->index) {
|
||||
/* INTERNAL CONFIGURATION/CONTROL REGISTERS */
|
||||
case 0x40 ... 0x49:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
}
|
||||
dev->access = 0;
|
||||
}
|
||||
} else if (port == 0x72)
|
||||
ret = dev->regs[0x72];
|
||||
ret = dev->regs[0x72];
|
||||
else if (port == 0x7e)
|
||||
ret = dev->regs[0x7e];
|
||||
ret = dev->regs[0x7e];
|
||||
else if (port == 0x7f)
|
||||
ret = dev->regs[0x7f];
|
||||
ret = dev->regs[0x7f];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
mem_read_emsb(uint32_t addr, void *priv)
|
||||
{
|
||||
ems_page_t *page = (ems_page_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ems_page_t *page = (ems_page_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
#ifdef ENABLE_CT_82C100_LOG
|
||||
uint32_t old_addr = addr;
|
||||
#endif
|
||||
|
||||
addr = addr - page->virt + page->phys;
|
||||
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ret = ram[addr];
|
||||
if (addr < ((uint32_t) mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
ct_82c100_log("mem_read_emsb(%08X = %08X): %02X\n", old_addr, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
mem_read_emsw(uint32_t addr, void *priv)
|
||||
{
|
||||
ems_page_t *page = (ems_page_t *)priv;
|
||||
uint16_t ret = 0xffff;
|
||||
ems_page_t *page = (ems_page_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
#ifdef ENABLE_CT_82C100_LOG
|
||||
uint32_t old_addr = addr;
|
||||
#endif
|
||||
|
||||
addr = addr - page->virt + page->phys;
|
||||
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ret = *(uint16_t *)&ram[addr];
|
||||
if (addr < ((uint32_t) mem_size << 10))
|
||||
ret = *(uint16_t *) &ram[addr];
|
||||
|
||||
ct_82c100_log("mem_read_emsw(%08X = %08X): %04X\n", old_addr, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_emsb(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ems_page_t *page = (ems_page_t *)priv;
|
||||
ems_page_t *page = (ems_page_t *) priv;
|
||||
#ifdef ENABLE_CT_82C100_LOG
|
||||
uint32_t old_addr = addr;
|
||||
#endif
|
||||
|
||||
addr = addr - page->virt + page->phys;
|
||||
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ram[addr] = val;
|
||||
if (addr < ((uint32_t) mem_size << 10))
|
||||
ram[addr] = val;
|
||||
|
||||
ct_82c100_log("mem_write_emsb(%08X = %08X, %02X)\n", old_addr, addr, val);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_emsw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ems_page_t *page = (ems_page_t *)priv;
|
||||
ems_page_t *page = (ems_page_t *) priv;
|
||||
#ifdef ENABLE_CT_82C100_LOG
|
||||
uint32_t old_addr = addr;
|
||||
#endif
|
||||
|
||||
addr = addr - page->virt + page->phys;
|
||||
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
*(uint16_t *)&ram[addr] = val;
|
||||
if (addr < ((uint32_t) mem_size << 10))
|
||||
*(uint16_t *) &ram[addr] = val;
|
||||
|
||||
ct_82c100_log("mem_write_emsw(%08X = %08X, %04X)\n", old_addr, addr, val);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ct_82c100_close(void *priv)
|
||||
{
|
||||
@@ -361,51 +347,49 @@ ct_82c100_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ct_82c100_init(const device_t *info)
|
||||
{
|
||||
ct_82c100_t *dev;
|
||||
uint32_t i;
|
||||
uint32_t i;
|
||||
|
||||
dev = (ct_82c100_t *)malloc(sizeof(ct_82c100_t));
|
||||
dev = (ct_82c100_t *) malloc(sizeof(ct_82c100_t));
|
||||
memset(dev, 0x00, sizeof(ct_82c100_t));
|
||||
|
||||
ct_82c100_reset(dev);
|
||||
|
||||
io_sethandler(0x0022, 2,
|
||||
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
|
||||
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
|
||||
io_sethandler(0x0072, 1,
|
||||
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
|
||||
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
|
||||
io_sethandler(0x007e, 2,
|
||||
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
|
||||
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
mem_mapping_add(&(dev->ems_mappings[i]), (i + 28) << 14, 0x04000,
|
||||
mem_read_emsb, mem_read_emsw, NULL,
|
||||
mem_write_emsb, mem_write_emsw, NULL,
|
||||
ram + 0xa0000 + (i << 14), MEM_MAPPING_INTERNAL, &dev->ems_pages[i]);
|
||||
mem_mapping_disable(&(dev->ems_mappings[i]));
|
||||
mem_mapping_add(&(dev->ems_mappings[i]), (i + 28) << 14, 0x04000,
|
||||
mem_read_emsb, mem_read_emsw, NULL,
|
||||
mem_write_emsb, mem_write_emsw, NULL,
|
||||
ram + 0xa0000 + (i << 14), MEM_MAPPING_INTERNAL, &dev->ems_pages[i]);
|
||||
mem_mapping_disable(&(dev->ems_mappings[i]));
|
||||
}
|
||||
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return(dev);
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t ct_82c100_device = {
|
||||
.name = "C&T 82C100",
|
||||
.name = "C&T 82C100",
|
||||
.internal_name = "ct_82c100",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ct_82c100_init,
|
||||
.close = ct_82c100_close,
|
||||
.reset = ct_82c100_reset,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ct_82c100_init,
|
||||
.close = ct_82c100_close,
|
||||
.reset = ct_82c100_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define ENABLED_SHADOW (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL))
|
||||
#define ENABLED_SHADOW (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL))
|
||||
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
#define SHADOW_ADDR ((i <= 1) ? (0xc0000 + (i << 15)) : (0xd0000 + ((i - 2) << 16)))
|
||||
#define SHADOW_SIZE ((i <= 1) ? 0x8000 : 0x10000)
|
||||
#define SHADOW_RECALC ((dev->regs[0x02] & (1 << i)) ? ENABLED_SHADOW : DISABLED_SHADOW)
|
||||
#define SHADOW_ADDR ((i <= 1) ? (0xc0000 + (i << 15)) : (0xd0000 + ((i - 2) << 16)))
|
||||
#define SHADOW_SIZE ((i <= 1) ? 0x8000 : 0x10000)
|
||||
#define SHADOW_RECALC ((dev->regs[0x02] & (1 << i)) ? ENABLED_SHADOW : DISABLED_SHADOW)
|
||||
|
||||
#ifdef ENABLE_ACC2168_LOG
|
||||
int acc2168_do_log = ENABLE_ACC2168_LOG;
|
||||
@@ -46,17 +46,16 @@ acc2168_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (acc2168_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define acc2168_log(fmt, ...)
|
||||
# define acc2168_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct acc2168_t
|
||||
{
|
||||
typedef struct acc2168_t {
|
||||
uint8_t reg_idx, regs[256];
|
||||
} acc2168_t;
|
||||
|
||||
@@ -70,104 +69,101 @@ acc2168_shadow_recalc(acc2168_t *dev)
|
||||
static void
|
||||
acc2168_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)p;
|
||||
acc2168_t *dev = (acc2168_t *) p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0xf2:
|
||||
dev->reg_idx = val;
|
||||
break;
|
||||
case 0xf3:
|
||||
acc2168_log("ACC2168: dev->regs[%02x] = %02x\n", dev->reg_idx, val);
|
||||
switch (dev->reg_idx)
|
||||
{
|
||||
case 0x00:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
switch (addr) {
|
||||
case 0xf2:
|
||||
dev->reg_idx = val;
|
||||
break;
|
||||
case 0xf3:
|
||||
acc2168_log("ACC2168: dev->regs[%02x] = %02x\n", dev->reg_idx, val);
|
||||
switch (dev->reg_idx) {
|
||||
case 0x00:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
dev->regs[dev->reg_idx] = val & 0xd3;
|
||||
cpu_update_waitstates();
|
||||
case 0x01:
|
||||
dev->regs[dev->reg_idx] = val & 0xd3;
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
dev->regs[dev->reg_idx] = val & 0x7f;
|
||||
acc2168_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
dev->regs[dev->reg_idx] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
dev->regs[dev->reg_idx] = val & 0xf3;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
dev->regs[dev->reg_idx] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
dev->regs[dev->reg_idx] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
dev->regs[dev->reg_idx] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->regs[dev->reg_idx] = val & 0xbb;
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
dev->regs[dev->reg_idx] = val & 0x77;
|
||||
break;
|
||||
|
||||
case 0x19:
|
||||
dev->regs[dev->reg_idx] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x1a:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
cpu_cache_int_enabled = !(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x1b:
|
||||
dev->regs[dev->reg_idx] = val & 0xef;
|
||||
break;
|
||||
|
||||
default: /* ACC 2168 has way more registers which we haven't documented */
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
dev->regs[dev->reg_idx] = val & 0x7f;
|
||||
acc2168_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
dev->regs[dev->reg_idx] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
dev->regs[dev->reg_idx] = val & 0xf3;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
dev->regs[dev->reg_idx] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
dev->regs[dev->reg_idx] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
dev->regs[dev->reg_idx] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->regs[dev->reg_idx] = val & 0xbb;
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
dev->regs[dev->reg_idx] = val & 0x77;
|
||||
break;
|
||||
|
||||
case 0x19:
|
||||
dev->regs[dev->reg_idx] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x1a:
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
cpu_cache_int_enabled = !(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x1b:
|
||||
dev->regs[dev->reg_idx] = val & 0xef;
|
||||
break;
|
||||
|
||||
default: /* ACC 2168 has way more registers which we haven't documented */
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
acc2168_read(uint16_t addr, void *p)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)p;
|
||||
acc2168_t *dev = (acc2168_t *) p;
|
||||
|
||||
return (addr == 0xf3) ? dev->regs[dev->reg_idx] : dev->reg_idx;
|
||||
}
|
||||
@@ -175,7 +171,7 @@ acc2168_read(uint16_t addr, void *p)
|
||||
static void
|
||||
acc2168_close(void *priv)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)priv;
|
||||
acc2168_t *dev = (acc2168_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -183,7 +179,7 @@ acc2168_close(void *priv)
|
||||
static void *
|
||||
acc2168_init(const device_t *info)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)malloc(sizeof(acc2168_t));
|
||||
acc2168_t *dev = (acc2168_t *) malloc(sizeof(acc2168_t));
|
||||
memset(dev, 0, sizeof(acc2168_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
@@ -193,15 +189,15 @@ acc2168_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t acc2168_device = {
|
||||
.name = "ACC 2046/2168",
|
||||
.name = "ACC 2046/2168",
|
||||
.internal_name = "acc2168",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = acc2168_init,
|
||||
.close = acc2168_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = acc2168_init,
|
||||
.close = acc2168_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -64,12 +64,12 @@
|
||||
Register 20h:
|
||||
Bits 2-1-0: Bus Clock Speed
|
||||
0 0 0: 7.1519Mhz (ATCLK2)
|
||||
0 0 1: CLK2IN/4
|
||||
0 1 0: CLK2IN/5
|
||||
0 1 1: CLK2IN/6
|
||||
1 0 0: CLK2IN/8
|
||||
1 0 1: CLK2IN/10
|
||||
1 1 0: CLK2IN/12
|
||||
0 0 1: CLK2IN/4
|
||||
0 1 0: CLK2IN/5
|
||||
0 1 1: CLK2IN/6
|
||||
1 0 0: CLK2IN/8
|
||||
1 0 1: CLK2IN/10
|
||||
1 1 0: CLK2IN/12
|
||||
|
||||
*/
|
||||
|
||||
@@ -94,13 +94,11 @@
|
||||
#include <86box/smram.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define GREEN dev->is_g /* Is G Variant */
|
||||
|
||||
#define GREEN dev->is_g /* Is G Variant */
|
||||
|
||||
#ifdef ENABLE_ALI1429_LOG
|
||||
int ali1429_do_log = ENABLE_ALI1429_LOG;
|
||||
|
||||
|
||||
static void
|
||||
ali1429_log(const char *fmt, ...)
|
||||
{
|
||||
@@ -113,27 +111,25 @@ ali1429_log(const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1429_log(fmt, ...)
|
||||
# define ali1429_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t is_g, index, cfg_locked, reg_57h,
|
||||
regs[90];
|
||||
uint8_t is_g, index, cfg_locked, reg_57h,
|
||||
regs[90];
|
||||
} ali1429_t;
|
||||
|
||||
|
||||
static void
|
||||
ali1429_shadow_recalc(ali1429_t *dev)
|
||||
{
|
||||
uint32_t base, i, can_write, can_read;
|
||||
|
||||
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
|
||||
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
|
||||
shadowbios_write = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x02);
|
||||
|
||||
can_write = (dev->regs[0x14] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
@@ -147,147 +143,149 @@ ali1429_shadow_recalc(ali1429_t *dev)
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)priv;
|
||||
ali1429_t *dev = (ali1429_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
case 0x23:
|
||||
#ifdef ENABLE_ALI1429_LOG
|
||||
if (dev->index != 0x03)
|
||||
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
if (dev->index != 0x03)
|
||||
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
#endif
|
||||
|
||||
if (dev->index == 0x03)
|
||||
dev->cfg_locked = !(val == 0xc5);
|
||||
if (dev->index == 0x03)
|
||||
dev->cfg_locked = !(val == 0xc5);
|
||||
|
||||
if (!dev->cfg_locked) {
|
||||
/* Common M1429 Registers */
|
||||
switch (dev->index) {
|
||||
case 0x10: case 0x11:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
if (!dev->cfg_locked) {
|
||||
/* Common M1429 Registers */
|
||||
switch (dev->index) {
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->regs[dev->index] = val;
|
||||
if(val & 4)
|
||||
mem_remap_top(128);
|
||||
else
|
||||
mem_remap_top(0);
|
||||
break;
|
||||
case 0x12:
|
||||
dev->regs[dev->index] = val;
|
||||
if (val & 4)
|
||||
mem_remap_top(128);
|
||||
else
|
||||
mem_remap_top(0);
|
||||
break;
|
||||
|
||||
case 0x13: case 0x14:
|
||||
dev->regs[dev->index] = val;
|
||||
ali1429_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
dev->regs[dev->index] = val;
|
||||
ali1429_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x15: case 0x16:
|
||||
case 0x17:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
dev->regs[dev->index] = (val & 0x8f) | 0x20;
|
||||
cpu_cache_ext_enabled = !!(val & 2);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x18:
|
||||
dev->regs[dev->index] = (val & 0x8f) | 0x20;
|
||||
cpu_cache_ext_enabled = !!(val & 2);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x19: case 0x1a:
|
||||
case 0x1e:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x19:
|
||||
case 0x1a:
|
||||
case 0x1e:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = val;
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
switch(val & 7) {
|
||||
case 0: case 7: /* Illegal */
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
switch (val & 7) {
|
||||
case 0:
|
||||
case 7: /* Illegal */
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
case 3:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
case 4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 10);
|
||||
break;
|
||||
case 5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 10);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 12);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 12);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x21 ... 0x27:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
case 0x21 ... 0x27:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
/* M1429G Only Registers */
|
||||
if (GREEN) {
|
||||
switch (dev->index) {
|
||||
case 0x30 ... 0x41:
|
||||
case 0x43: case 0x45:
|
||||
case 0x4a:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
/* M1429G Only Registers */
|
||||
if (GREEN) {
|
||||
switch (dev->index) {
|
||||
case 0x30 ... 0x41:
|
||||
case 0x43:
|
||||
case 0x45:
|
||||
case 0x4a:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->reg_57h = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x57:
|
||||
dev->reg_57h = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1429_read(uint16_t addr, void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ali1429_t *dev = (ali1429_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if ((addr == 0x23) && (dev->index >= 0x10) && (dev->index <= 0x4a))
|
||||
ret = dev->regs[dev->index];
|
||||
ret = dev->regs[dev->index];
|
||||
else if ((addr == 0x23) && (dev->index == 0x57))
|
||||
ret = dev->reg_57h;
|
||||
ret = dev->reg_57h;
|
||||
else if (addr == 0x22)
|
||||
ret = dev->index;
|
||||
ret = dev->index;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_close(void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)priv;
|
||||
ali1429_t *dev = (ali1429_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_defaults(ali1429_t *dev)
|
||||
{
|
||||
@@ -306,28 +304,27 @@ ali1429_defaults(ali1429_t *dev)
|
||||
|
||||
/* M1429G Default Registers */
|
||||
if (GREEN) {
|
||||
dev->regs[0x31] = 0x88;
|
||||
dev->regs[0x32] = 0xc0;
|
||||
dev->regs[0x38] = 0xe5;
|
||||
dev->regs[0x40] = 0xe3;
|
||||
dev->regs[0x41] = 2;
|
||||
dev->regs[0x45] = 0x80;
|
||||
dev->regs[0x31] = 0x88;
|
||||
dev->regs[0x32] = 0xc0;
|
||||
dev->regs[0x38] = 0xe5;
|
||||
dev->regs[0x40] = 0xe3;
|
||||
dev->regs[0x41] = 2;
|
||||
dev->regs[0x45] = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1429_init(const device_t *info)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)malloc(sizeof(ali1429_t));
|
||||
ali1429_t *dev = (ali1429_t *) malloc(sizeof(ali1429_t));
|
||||
memset(dev, 0, sizeof(ali1429_t));
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
GREEN = info->local;
|
||||
GREEN = info->local;
|
||||
|
||||
/* M1429 Ports:
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
|
||||
|
||||
@@ -339,29 +336,29 @@ ali1429_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t ali1429_device = {
|
||||
.name = "ALi M1429",
|
||||
.name = "ALi M1429",
|
||||
.internal_name = "ali1429",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ali1429_init,
|
||||
.close = ali1429_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ali1429_init,
|
||||
.close = ali1429_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ali1429g_device = {
|
||||
.name = "ALi M1429G",
|
||||
.name = "ALi M1429G",
|
||||
.internal_name = "ali1429g",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = ali1429_init,
|
||||
.close = ali1429_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = ali1429_init,
|
||||
.close = ali1429_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -40,10 +40,8 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
|
||||
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
|
||||
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
|
||||
#ifdef ENABLE_ALI1489_LOG
|
||||
int ali1489_do_log = ENABLE_ALI1489_LOG;
|
||||
@@ -52,30 +50,26 @@ ali1489_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1489_do_log)
|
||||
{
|
||||
if (ali1489_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1489_log(fmt, ...)
|
||||
# define ali1489_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, ide_index, ide_chip_id, pci_slot,
|
||||
regs[256], pci_conf[256], ide_regs[256];
|
||||
uint8_t index, ide_index, ide_chip_id, pci_slot,
|
||||
regs[256], pci_conf[256], ide_regs[256];
|
||||
|
||||
port_92_t * port_92;
|
||||
smram_t * smram;
|
||||
port_92_t *port_92;
|
||||
smram_t *smram;
|
||||
} ali1489_t;
|
||||
|
||||
|
||||
static void ali1489_ide_handler(ali1489_t *dev);
|
||||
|
||||
static void ali1489_ide_handler(ali1489_t *dev);
|
||||
|
||||
static void
|
||||
ali1489_shadow_recalc(ali1489_t *dev)
|
||||
@@ -85,33 +79,32 @@ ali1489_shadow_recalc(ali1489_t *dev)
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (dev->regs[0x13] & (1 << i)) {
|
||||
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
|
||||
0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE);
|
||||
} else {
|
||||
ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14));
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DISABLED_SHADOW);
|
||||
}
|
||||
if (dev->regs[0x13] & (1 << i)) {
|
||||
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
|
||||
0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE);
|
||||
} else {
|
||||
ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14));
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DISABLED_SHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (dev->regs[0x14] & (1 << i)) {
|
||||
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
|
||||
0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE);
|
||||
shadowbios |= !!(dev->regs[0x14] & 0x10);
|
||||
shadowbios_write |= !!(dev->regs[0x14] & 0x20);
|
||||
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
|
||||
0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE);
|
||||
shadowbios |= !!(dev->regs[0x14] & 0x10);
|
||||
shadowbios_write |= !!(dev->regs[0x14] & 0x20);
|
||||
} else {
|
||||
ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xe0000 + (i << 15), 0xe7fff + (i << 15));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DISABLED_SHADOW);
|
||||
}
|
||||
ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xe0000 + (i << 15), 0xe7fff + (i << 15));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DISABLED_SHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_smram_recalc(ali1489_t *dev)
|
||||
{
|
||||
@@ -120,27 +113,26 @@ ali1489_smram_recalc(ali1489_t *dev)
|
||||
smram_disable(dev->smram);
|
||||
|
||||
switch (dev->regs[0x19] & 0x30) {
|
||||
case 0x10:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, (dev->regs[0x19] & 0x08), 1);
|
||||
break;
|
||||
case 0x20:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x10000, (dev->regs[0x19] & 0x08), 1);
|
||||
break;
|
||||
case 0x30:
|
||||
if ((dev->regs[0x35] & 0xc0) == 0x80)
|
||||
smram_enable(dev->smram, 0x68000, 0xa8000, 0x08000, (dev->regs[0x19] & 0x08), 1);
|
||||
else
|
||||
smram_enable(dev->smram, 0x38000, 0xa8000, 0x08000, (dev->regs[0x19] & 0x08), 1);
|
||||
break;
|
||||
case 0x10:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, (dev->regs[0x19] & 0x08), 1);
|
||||
break;
|
||||
case 0x20:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x10000, (dev->regs[0x19] & 0x08), 1);
|
||||
break;
|
||||
case 0x30:
|
||||
if ((dev->regs[0x35] & 0xc0) == 0x80)
|
||||
smram_enable(dev->smram, 0x68000, 0xa8000, 0x08000, (dev->regs[0x19] & 0x08), 1);
|
||||
else
|
||||
smram_enable(dev->smram, 0x38000, 0xa8000, 0x08000, (dev->regs[0x19] & 0x08), 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((dev->regs[0x19] & 0x31) == 0x11) {
|
||||
/* If SMRAM is enabled and bit 0 is set, code still goes to DRAM. */
|
||||
mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02);
|
||||
/* If SMRAM is enabled and bit 0 is set, code still goes to DRAM. */
|
||||
mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_defaults(ali1489_t *dev)
|
||||
{
|
||||
@@ -197,9 +189,9 @@ ali1489_defaults(ali1489_t *dev)
|
||||
|
||||
picintc(1 << 10);
|
||||
picintc(1 << 15);
|
||||
nmi = 0;
|
||||
nmi = 0;
|
||||
smi_line = 0;
|
||||
in_smm = 0;
|
||||
in_smm = 0;
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
@@ -209,214 +201,212 @@ ali1489_defaults(ali1489_t *dev)
|
||||
ali1489_ide_handler(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
uint8_t old, irq;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
uint8_t old, irq;
|
||||
const uint8_t irq_array[16] = { 0, 3, 4, 7, 0, 0, 0, 0, 9, 10, 5, 6, 11, 12, 14, 15 };
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
/* Check if the configuration registers are unlocked */
|
||||
if (dev->regs[0x03] == 0xc5) {
|
||||
switch (dev->index) {
|
||||
case 0x03: /* Lock Register */
|
||||
case 0x10: /* DRAM Configuration Register I */
|
||||
case 0x11: /* DRAM Configuration Register II */
|
||||
case 0x12: /* ROM Function Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
/* Check if the configuration registers are unlocked */
|
||||
if (dev->regs[0x03] == 0xc5) {
|
||||
switch (dev->index) {
|
||||
case 0x03: /* Lock Register */
|
||||
case 0x10: /* DRAM Configuration Register I */
|
||||
case 0x11: /* DRAM Configuration Register II */
|
||||
case 0x12: /* ROM Function Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x13: /* Shadow Region Register */
|
||||
case 0x14: /* Shadow Control Register */
|
||||
if (dev->index == 0x14)
|
||||
dev->regs[dev->index] = (val & 0xbf);
|
||||
else
|
||||
dev->regs[dev->index] = val;
|
||||
case 0x13: /* Shadow Region Register */
|
||||
case 0x14: /* Shadow Control Register */
|
||||
if (dev->index == 0x14)
|
||||
dev->regs[dev->index] = (val & 0xbf);
|
||||
else
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
ali1489_shadow_recalc(dev);
|
||||
ali1489_smram_recalc(dev);
|
||||
break;
|
||||
ali1489_shadow_recalc(dev);
|
||||
ali1489_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x15: /* Cycle Check Point Control Register */
|
||||
dev->regs[dev->index] = (val & 0xf1);
|
||||
break;
|
||||
case 0x15: /* Cycle Check Point Control Register */
|
||||
dev->regs[dev->index] = (val & 0xf1);
|
||||
break;
|
||||
|
||||
case 0x16: /* Cache Control Register I */
|
||||
dev->regs[dev->index] = val;
|
||||
cpu_cache_int_enabled = (val & 0x01);
|
||||
cpu_cache_ext_enabled = (val & 0x02);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x17: /* Cache Control Register II */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x16: /* Cache Control Register I */
|
||||
dev->regs[dev->index] = val;
|
||||
cpu_cache_int_enabled = (val & 0x01);
|
||||
cpu_cache_ext_enabled = (val & 0x02);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x17: /* Cache Control Register II */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x19: /* SMM Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
ali1489_smram_recalc(dev);
|
||||
break;
|
||||
case 0x19: /* SMM Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
ali1489_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x1a: /* EDO DRAM Configuration Register */
|
||||
case 0x1b: /* DRAM Timing Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x1c: /* Memory Data Buffer Direction Control Register */
|
||||
dev->regs[dev->index] = val & 0x1f;
|
||||
break;
|
||||
case 0x1a: /* EDO DRAM Configuration Register */
|
||||
case 0x1b: /* DRAM Timing Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x1c: /* Memory Data Buffer Direction Control Register */
|
||||
dev->regs[dev->index] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x1e: /* Linear Wrapped Burst Order Mode Control Register */
|
||||
dev->regs[dev->index] = (val & 0x40);
|
||||
break;
|
||||
case 0x1e: /* Linear Wrapped Burst Order Mode Control Register */
|
||||
dev->regs[dev->index] = (val & 0x40);
|
||||
break;
|
||||
|
||||
case 0x20: /* CPU to PCI Buffer Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x21: /* DEVSELJ Check Point Setting Register */
|
||||
dev->regs[dev->index] = (val & 0xbb) | 0x04;
|
||||
break;
|
||||
case 0x22: /* PCI to CPU W/R Buffer Configuration Register */
|
||||
dev->regs[dev->index] = (val & 0xfd);
|
||||
break;
|
||||
case 0x20: /* CPU to PCI Buffer Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x21: /* DEVSELJ Check Point Setting Register */
|
||||
dev->regs[dev->index] = (val & 0xbb) | 0x04;
|
||||
break;
|
||||
case 0x22: /* PCI to CPU W/R Buffer Configuration Register */
|
||||
dev->regs[dev->index] = (val & 0xfd);
|
||||
break;
|
||||
|
||||
case 0x25: /* GP/MEM Address Definition Register I */
|
||||
case 0x26: /* GP/MEM Address Definition Register II */
|
||||
case 0x27: /* GP/MEM Address Definition Register III */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x28: /* PCI Arbiter Control Register */
|
||||
dev->regs[dev->index] = val & 0x3f;
|
||||
break;
|
||||
case 0x25: /* GP/MEM Address Definition Register I */
|
||||
case 0x26: /* GP/MEM Address Definition Register II */
|
||||
case 0x27: /* GP/MEM Address Definition Register III */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x28: /* PCI Arbiter Control Register */
|
||||
dev->regs[dev->index] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x29: /* System Clock Register */
|
||||
dev->regs[dev->index] = val;
|
||||
case 0x29: /* System Clock Register */
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x10)
|
||||
port_92_add(dev->port_92);
|
||||
break;
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x10)
|
||||
port_92_add(dev->port_92);
|
||||
break;
|
||||
|
||||
case 0x2a: /* I/O Recovery Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x2a: /* I/O Recovery Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x2b: /* Turbo Function Register */
|
||||
dev->regs[dev->index] = (val & 0xbf) | 0x40;
|
||||
break;
|
||||
case 0x2b: /* Turbo Function Register */
|
||||
dev->regs[dev->index] = (val & 0xbf) | 0x40;
|
||||
break;
|
||||
|
||||
case 0x30: /* Power Management Unit Control Register */
|
||||
old = dev->regs[dev->index];
|
||||
dev->regs[dev->index] = val;
|
||||
case 0x30: /* Power Management Unit Control Register */
|
||||
old = dev->regs[dev->index];
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
if (((val & 0x14) == 0x14) && !(old & 0x08) && (val & 0x08)) {
|
||||
switch (dev->regs[0x35] & 0x30) {
|
||||
case 0x00:
|
||||
smi_raise();
|
||||
break;
|
||||
case 0x10:
|
||||
nmi_raise();
|
||||
break;
|
||||
case 0x20:
|
||||
picint(1 << 15);
|
||||
break;
|
||||
case 0x30:
|
||||
picint(1 << 10);
|
||||
break;
|
||||
}
|
||||
dev->regs[0x35] |= 0x0e;
|
||||
} else if (!(val & 0x10))
|
||||
dev->regs[0x35] &= ~0x0f;
|
||||
break;
|
||||
if (((val & 0x14) == 0x14) && !(old & 0x08) && (val & 0x08)) {
|
||||
switch (dev->regs[0x35] & 0x30) {
|
||||
case 0x00:
|
||||
smi_raise();
|
||||
break;
|
||||
case 0x10:
|
||||
nmi_raise();
|
||||
break;
|
||||
case 0x20:
|
||||
picint(1 << 15);
|
||||
break;
|
||||
case 0x30:
|
||||
picint(1 << 10);
|
||||
break;
|
||||
}
|
||||
dev->regs[0x35] |= 0x0e;
|
||||
} else if (!(val & 0x10))
|
||||
dev->regs[0x35] &= ~0x0f;
|
||||
break;
|
||||
|
||||
case 0x31: /* Mode Timer Monitoring Events Selection Register I */
|
||||
case 0x32: /* Mode Timer Monitoring Events Selection Register II */
|
||||
case 0x33: /* SMI Triggered Events Selection Register I */
|
||||
case 0x34: /* SMI Triggered Events Selection Register II */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x31: /* Mode Timer Monitoring Events Selection Register I */
|
||||
case 0x32: /* Mode Timer Monitoring Events Selection Register II */
|
||||
case 0x33: /* SMI Triggered Events Selection Register I */
|
||||
case 0x34: /* SMI Triggered Events Selection Register II */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x35: /* SMI Status Register */
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0x0f) | (val & 0xf0);
|
||||
break;
|
||||
case 0x35: /* SMI Status Register */
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0x0f) | (val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x36: /* IRQ Channel Group Selected Control Register I */
|
||||
dev->regs[dev->index] = (val & 0xe5);
|
||||
break;
|
||||
case 0x37: /* IRQ Channel Group Selected Control Register II */
|
||||
dev->regs[dev->index] = (val & 0xef);
|
||||
break;
|
||||
case 0x36: /* IRQ Channel Group Selected Control Register I */
|
||||
dev->regs[dev->index] = (val & 0xe5);
|
||||
break;
|
||||
case 0x37: /* IRQ Channel Group Selected Control Register II */
|
||||
dev->regs[dev->index] = (val & 0xef);
|
||||
break;
|
||||
|
||||
case 0x38: /* DRQ Channel Selected Control Register */
|
||||
case 0x39: /* Mode Timer Setting Register */
|
||||
case 0x3a: /* Input_device Timer Setting Register */
|
||||
case 0x3b: /* GP/MEM Timer Setting Register */
|
||||
case 0x3c: /* LED Flash Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x38: /* DRQ Channel Selected Control Register */
|
||||
case 0x39: /* Mode Timer Setting Register */
|
||||
case 0x3a: /* Input_device Timer Setting Register */
|
||||
case 0x3b: /* GP/MEM Timer Setting Register */
|
||||
case 0x3c: /* LED Flash Control Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x3d: /* Miscellaneous Register I */
|
||||
dev->regs[dev->index] = (val & 0x07);
|
||||
break;
|
||||
case 0x3d: /* Miscellaneous Register I */
|
||||
dev->regs[dev->index] = (val & 0x07);
|
||||
break;
|
||||
|
||||
case 0x40: /* Clock Generator Control Feature Register */
|
||||
dev->regs[dev->index] = (val & 0x3f);
|
||||
break;
|
||||
case 0x41: /* Power Control Output Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x40: /* Clock Generator Control Feature Register */
|
||||
dev->regs[dev->index] = (val & 0x3f);
|
||||
break;
|
||||
case 0x41: /* Power Control Output Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x42: /* PCI INTx Routing Table Mapping Register I */
|
||||
irq = irq_array[val & 0x0f];
|
||||
pci_set_irq_routing(PCI_INTA, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
irq = irq_array[(val & 0xf0) >> 4];
|
||||
pci_set_irq_routing(PCI_INTB, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x42: /* PCI INTx Routing Table Mapping Register I */
|
||||
irq = irq_array[val & 0x0f];
|
||||
pci_set_irq_routing(PCI_INTA, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
irq = irq_array[(val & 0xf0) >> 4];
|
||||
pci_set_irq_routing(PCI_INTB, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x43: /* PCI INTx Routing Table Mapping Register II */
|
||||
irq = irq_array[val & 0x0f];
|
||||
pci_set_irq_routing(PCI_INTC, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
irq = irq_array[(val & 0xf0) >> 4];
|
||||
pci_set_irq_routing(PCI_INTD, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x43: /* PCI INTx Routing Table Mapping Register II */
|
||||
irq = irq_array[val & 0x0f];
|
||||
pci_set_irq_routing(PCI_INTC, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
irq = irq_array[(val & 0xf0) >> 4];
|
||||
pci_set_irq_routing(PCI_INTD, (irq != 0) ? irq : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x44: /* PCI INTx Sensitivity Register */
|
||||
/* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
case 0x44: /* PCI INTx Sensitivity Register */
|
||||
/* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->index != 0x03) {
|
||||
ali1489_log("M1489: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
}
|
||||
} else if (dev->index == 0x03)
|
||||
dev->regs[dev->index] = val;
|
||||
if (dev->index != 0x03) {
|
||||
ali1489_log("M1489: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
}
|
||||
} else if (dev->index == 0x03)
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1489_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x23:
|
||||
/* Avoid conflict with Cyrix CPU registers */
|
||||
if (((dev->index == 0x20) || (dev->index >= 0xc0)) && cpu_iscyrix)
|
||||
ret = 0xff;
|
||||
else if (dev->index == 0x3f)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
case 0x23:
|
||||
/* Avoid conflict with Cyrix CPU registers */
|
||||
if (((dev->index == 0x20) || (dev->index >= 0xc0)) && cpu_iscyrix)
|
||||
ret = 0xff;
|
||||
else if (dev->index == 0x3f)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
}
|
||||
|
||||
ali1489_log("M1489: dev->regs[%02x] (%02x)\n", dev->index, ret);
|
||||
@@ -424,155 +414,147 @@ ali1489_read(uint16_t addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
|
||||
ali1489_log("M1489-PCI: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
/* Dummy PCI Config */
|
||||
case 0x04:
|
||||
dev->pci_conf[0x04] = val & 0x7f;
|
||||
break;
|
||||
/* Dummy PCI Config */
|
||||
case 0x04:
|
||||
dev->pci_conf[0x04] = val & 0x7f;
|
||||
break;
|
||||
|
||||
/* Dummy PCI Status */
|
||||
case 0x07:
|
||||
dev->pci_conf[0x07] &= ~(val & 0xb8);
|
||||
break;
|
||||
/* Dummy PCI Status */
|
||||
case 0x07:
|
||||
dev->pci_conf[0x07] &= ~(val & 0xb8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1489_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
ali1489_log("M1489-PCI: dev->pci_conf[%02x] (%02x)\n", addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_ide_handler(ali1489_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
if (dev->ide_regs[0x01] & 0x01) {
|
||||
ide_pri_enable();
|
||||
if (!(dev->ide_regs[0x35] & 0x40))
|
||||
ide_sec_enable();
|
||||
ide_pri_enable();
|
||||
if (!(dev->ide_regs[0x35] & 0x40))
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_ide_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0xf4: /* Usually it writes 30h here */
|
||||
dev->ide_chip_id = val;
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0xf4: /* Usually it writes 30h here */
|
||||
dev->ide_chip_id = val;
|
||||
break;
|
||||
|
||||
case 0xf8:
|
||||
dev->ide_index = val;
|
||||
break;
|
||||
case 0xf8:
|
||||
dev->ide_index = val;
|
||||
break;
|
||||
|
||||
case 0xfc:
|
||||
if (dev->ide_chip_id != 0x30)
|
||||
break;
|
||||
case 0xfc:
|
||||
if (dev->ide_chip_id != 0x30)
|
||||
break;
|
||||
|
||||
switch(dev->ide_index) {
|
||||
case 0x01: /* IDE Configuration Register */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x8f;
|
||||
ali1489_ide_handler(dev);
|
||||
break;
|
||||
case 0x02: /* DBA Data Byte Cative Count for IDE-1 */
|
||||
case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */
|
||||
case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */
|
||||
case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */
|
||||
case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */
|
||||
case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */
|
||||
case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */
|
||||
case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */
|
||||
case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */
|
||||
case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */
|
||||
case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */
|
||||
case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */
|
||||
case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */
|
||||
case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */
|
||||
case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */
|
||||
case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */
|
||||
case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */
|
||||
case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */
|
||||
case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */
|
||||
case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x1f;
|
||||
break;
|
||||
case 0x07: /* Buffer Mode Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val;
|
||||
break;
|
||||
case 0x09: /* IDEPE1 IDE Port Enable Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0xc3;
|
||||
break;
|
||||
case 0x0a: /* Buffer Mode Register 2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x4f;
|
||||
break;
|
||||
case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */
|
||||
case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */
|
||||
case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */
|
||||
case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x03;
|
||||
break;
|
||||
case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */
|
||||
case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */
|
||||
case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
|
||||
case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x1f;
|
||||
break;
|
||||
case 0x35: /* IDEPE3 IDE Port Enable Register 3 */
|
||||
dev->ide_regs[dev->ide_index] = val;
|
||||
ali1489_ide_handler(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
switch (dev->ide_index) {
|
||||
case 0x01: /* IDE Configuration Register */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x8f;
|
||||
ali1489_ide_handler(dev);
|
||||
break;
|
||||
case 0x02: /* DBA Data Byte Cative Count for IDE-1 */
|
||||
case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */
|
||||
case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */
|
||||
case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */
|
||||
case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */
|
||||
case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */
|
||||
case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */
|
||||
case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */
|
||||
case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */
|
||||
case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */
|
||||
case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */
|
||||
case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */
|
||||
case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */
|
||||
case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */
|
||||
case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */
|
||||
case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */
|
||||
case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */
|
||||
case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */
|
||||
case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */
|
||||
case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x1f;
|
||||
break;
|
||||
case 0x07: /* Buffer Mode Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val;
|
||||
break;
|
||||
case 0x09: /* IDEPE1 IDE Port Enable Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0xc3;
|
||||
break;
|
||||
case 0x0a: /* Buffer Mode Register 2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x4f;
|
||||
break;
|
||||
case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */
|
||||
case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */
|
||||
case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */
|
||||
case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x03;
|
||||
break;
|
||||
case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */
|
||||
case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */
|
||||
case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
|
||||
case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x1f;
|
||||
break;
|
||||
case 0x35: /* IDEPE3 IDE Port Enable Register 3 */
|
||||
dev->ide_regs[dev->ide_index] = val;
|
||||
ali1489_ide_handler(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1489_ide_read(uint16_t addr, void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0xf4:
|
||||
ret = dev->ide_chip_id;
|
||||
break;
|
||||
case 0xfc:
|
||||
ret = dev->ide_regs[dev->ide_index];
|
||||
ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret);
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0xf4:
|
||||
ret = dev->ide_chip_id;
|
||||
break;
|
||||
case 0xfc:
|
||||
ret = dev->ide_regs[dev->ide_index];
|
||||
ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_reset(void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
@@ -582,21 +564,19 @@ ali1489_reset(void *priv)
|
||||
ali1489_defaults(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1489_close(void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)priv;
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1489_init(const device_t *info)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *)malloc(sizeof(ali1489_t));
|
||||
ali1489_t *dev = (ali1489_t *) malloc(sizeof(ali1489_t));
|
||||
memset(dev, 0, sizeof(ali1489_t));
|
||||
|
||||
/* M1487/M1489
|
||||
@@ -619,7 +599,7 @@ ali1489_init(const device_t *info)
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
dev->smram = smram_add();
|
||||
dev->smram = smram_add();
|
||||
|
||||
ali1489_defaults(dev);
|
||||
|
||||
@@ -627,15 +607,15 @@ ali1489_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t ali1489_device = {
|
||||
.name = "ALi M1489",
|
||||
.name = "ALi M1489",
|
||||
.internal_name = "ali1489",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ali1489_init,
|
||||
.close = ali1489_close,
|
||||
.reset = ali1489_reset,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ali1489_init,
|
||||
.close = ali1489_close,
|
||||
.reset = ali1489_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -34,15 +34,12 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct ali1531_t
|
||||
{
|
||||
typedef struct ali1531_t {
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
} ali1531_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI1531_LOG
|
||||
int ali1531_do_log = ENABLE_ALI1531_LOG;
|
||||
static void
|
||||
@@ -50,262 +47,263 @@ ali1531_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1531_do_log)
|
||||
{
|
||||
if (ali1531_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1531_log(fmt, ...)
|
||||
# define ali1531_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ali1531_smram_recalc(uint8_t val, ali1531_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 1) {
|
||||
switch (val & 0x0c) {
|
||||
case 0x00:
|
||||
ali1531_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02);
|
||||
break;
|
||||
case 0x04:
|
||||
ali1531_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02);
|
||||
break;
|
||||
case 0x08:
|
||||
ali1531_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02);
|
||||
break;
|
||||
}
|
||||
switch (val & 0x0c) {
|
||||
case 0x00:
|
||||
ali1531_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02);
|
||||
break;
|
||||
case 0x04:
|
||||
ali1531_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02);
|
||||
break;
|
||||
case 0x08:
|
||||
ali1531_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_shadow_recalc(int cur_reg, ali1531_t *dev)
|
||||
{
|
||||
int i, bit, r_reg, w_reg;
|
||||
int i, bit, r_reg, w_reg;
|
||||
uint32_t base, flags = 0;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
bit = i & 7;
|
||||
r_reg = 0x4c + (i >> 3);
|
||||
w_reg = 0x4e + (i >> 3);
|
||||
base = 0x000c0000 + (i << 14);
|
||||
bit = i & 7;
|
||||
r_reg = 0x4c + (i >> 3);
|
||||
w_reg = 0x4e + (i >> 3);
|
||||
|
||||
flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[r_reg] & (1 << bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[w_reg] & (1 << bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[r_reg] & (1 << bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[w_reg] & (1 << bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
|
||||
ali1531_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E');
|
||||
ali1531_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00004000, flags);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
ali1531_t *dev = (ali1531_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf8);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf8);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x2c: /* Subsystem Vendor ID */
|
||||
case 0x2d:
|
||||
case 0x2e:
|
||||
case 0x2f:
|
||||
if (dev->pci_conf[0x70] & 0x08)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x2c: /* Subsystem Vendor ID */
|
||||
case 0x2d:
|
||||
case 0x2e:
|
||||
case 0x2f:
|
||||
if (dev->pci_conf[0x70] & 0x08)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0xf1;
|
||||
break;
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0xf1;
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = (val & 0xd6) | 0x08;
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = (val & 0xd6) | 0x08;
|
||||
break;
|
||||
|
||||
case 0x42: /* L2 Cache */
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
cpu_cache_ext_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x42: /* L2 Cache */
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
cpu_cache_ext_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x43: /* L1 Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_int_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x43: /* L1 Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_int_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
|
||||
if (mem_size > 0xe00000)
|
||||
mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
if (mem_size > 0xe00000)
|
||||
mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
if (mem_size > 0xf00000)
|
||||
mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
if (mem_size > 0xf00000)
|
||||
mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
flushmmucache_nopc();
|
||||
break;
|
||||
flushmmucache_nopc();
|
||||
break;
|
||||
|
||||
case 0x48: /* SMRAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_smram_recalc(val, dev);
|
||||
break;
|
||||
case 0x48: /* SMRAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_smram_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val & 0x73;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val & 0x73;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4c ... 0x4f: /* Shadow RAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_shadow_recalc(val, dev);
|
||||
break;
|
||||
case 0x4c ... 0x4f: /* Shadow RAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x54:
|
||||
case 0x55: case 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x57: /* H2PO */
|
||||
dev->pci_conf[addr] = val & 0x60;
|
||||
/* Find where the Shut-down Special cycle is initiated. */
|
||||
// if (!(val & 0x20))
|
||||
// outb(0x92, 0x01);
|
||||
break;
|
||||
case 0x57: /* H2PO */
|
||||
dev->pci_conf[addr] = val & 0x60;
|
||||
/* Find where the Shut-down Special cycle is initiated. */
|
||||
// if (!(val & 0x20))
|
||||
// outb(0x92, 0x01);
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0x86;
|
||||
break;
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0x86;
|
||||
break;
|
||||
|
||||
case 0x59: case 0x5a:
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0x4f;
|
||||
break;
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0x4f;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val & 0x53;
|
||||
break;
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val & 0x53;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x6f: /* DRB's */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
case 0x60 ... 0x6f: /* DRB's */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
|
||||
case 0x70: case 0x71:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x72:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x72:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
dev->pci_conf[addr] = val & 0x2b;
|
||||
break;
|
||||
case 0x74:
|
||||
dev->pci_conf[addr] = val & 0x2b;
|
||||
break;
|
||||
|
||||
case 0x76: case 0x77:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val & 0x84;
|
||||
break;
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val & 0x84;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0x81;
|
||||
break;
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0x81;
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0x10;
|
||||
break;
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0x10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1531_read(int func, int addr, void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ali1531_t *dev = (ali1531_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_reset(void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
int i;
|
||||
ali1531_t *dev = (ali1531_t *) priv;
|
||||
int i;
|
||||
|
||||
/* Default Registers */
|
||||
dev->pci_conf[0x00] = 0xb9;
|
||||
@@ -342,29 +340,27 @@ ali1531_reset(void *priv)
|
||||
ali1531_write(0, 0x48, 0x00, dev);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ali1531_write(0, 0x4c + i, 0x00, dev);
|
||||
ali1531_write(0, 0x4c + i, 0x00, dev);
|
||||
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
ali1531_write(0, 0x60 + i, 0x08, dev);
|
||||
ali1531_write(0, 0x61 + i, 0x40, dev);
|
||||
ali1531_write(0, 0x60 + i, 0x08, dev);
|
||||
ali1531_write(0, 0x61 + i, 0x40, dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_close(void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
ali1531_t *dev = (ali1531_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1531_init(const device_t *info)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)malloc(sizeof(ali1531_t));
|
||||
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
|
||||
memset(dev, 0, sizeof(ali1531_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev);
|
||||
@@ -377,15 +373,15 @@ ali1531_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t ali1531_device = {
|
||||
.name = "ALi M1531 CPU-to-PCI Bridge",
|
||||
.name = "ALi M1531 CPU-to-PCI Bridge",
|
||||
.internal_name = "ali1531",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = ali1531_init,
|
||||
.close = ali1531_close,
|
||||
.reset = ali1531_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = ali1531_init,
|
||||
.close = ali1531_close,
|
||||
.reset = ali1531_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -31,15 +31,12 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct ali1621_t {
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
typedef struct ali1621_t
|
||||
{
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t * smram[2];
|
||||
smram_t *smram[2];
|
||||
} ali1621_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI1621_LOG
|
||||
int ali1621_do_log = ENABLE_ALI1621_LOG;
|
||||
static void
|
||||
@@ -47,51 +44,49 @@ ali1621_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1621_do_log)
|
||||
{
|
||||
if (ali1621_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1621_log(fmt, ...)
|
||||
# define ali1621_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Table translated to a more sensible format:
|
||||
Read cycles:
|
||||
SMREN SMM Mode Code Data
|
||||
0 X X PCI PCI
|
||||
1 0 Close PCI PCI
|
||||
1 0 Lock PCI PCI
|
||||
1 0 Protect PCI PCI
|
||||
1 0 Open DRAM DRAM
|
||||
1 1 Open DRAM DRAM
|
||||
1 1 Protect DRAM DRAM
|
||||
1 1 Close DRAM PCI
|
||||
1 1 Lock DRAM PCI
|
||||
Read cycles:
|
||||
SMREN SMM Mode Code Data
|
||||
0 X X PCI PCI
|
||||
1 0 Close PCI PCI
|
||||
1 0 Lock PCI PCI
|
||||
1 0 Protect PCI PCI
|
||||
1 0 Open DRAM DRAM
|
||||
1 1 Open DRAM DRAM
|
||||
1 1 Protect DRAM DRAM
|
||||
1 1 Close DRAM PCI
|
||||
1 1 Lock DRAM PCI
|
||||
|
||||
Write cycles:
|
||||
SMWEN SMM Mode Data
|
||||
0 X X PCI
|
||||
1 0 Close PCI
|
||||
1 0 Lock PCI
|
||||
1 0 Protect PCI
|
||||
1 0 Open DRAM
|
||||
1 1 Open DRAM
|
||||
1 1 Protect DRAM
|
||||
1 1 Close PCI
|
||||
1 1 Lock PCI
|
||||
Write cycles:
|
||||
SMWEN SMM Mode Data
|
||||
0 X X PCI
|
||||
1 0 Close PCI
|
||||
1 0 Lock PCI
|
||||
1 0 Protect PCI
|
||||
1 0 Open DRAM
|
||||
1 1 Open DRAM
|
||||
1 1 Protect DRAM
|
||||
1 1 Close PCI
|
||||
1 1 Lock PCI
|
||||
|
||||
Explanation of the modes based above:
|
||||
If SM*EN = 0, SMRAM is entirely disabled, otherwise:
|
||||
If mode is Close or Lock, then SMRAM always goes to PCI outside SMM,
|
||||
and data to PCI, code to DRAM in SMM;
|
||||
If mode is Protect, then SMRAM always goes to PCI outside SMM and
|
||||
DRAM in SMM;
|
||||
If mode is Open, then SMRAM always goes to DRAM.
|
||||
Read and write are enabled separately.
|
||||
Explanation of the modes based above:
|
||||
If SM*EN = 0, SMRAM is entirely disabled, otherwise:
|
||||
If mode is Close or Lock, then SMRAM always goes to PCI outside SMM,
|
||||
and data to PCI, code to DRAM in SMM;
|
||||
If mode is Protect, then SMRAM always goes to PCI outside SMM and
|
||||
DRAM in SMM;
|
||||
If mode is Open, then SMRAM always goes to DRAM.
|
||||
Read and write are enabled separately.
|
||||
*/
|
||||
static void
|
||||
ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
|
||||
@@ -101,486 +96,486 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 0xc0) {
|
||||
/* SMRAM 0: A0000-BFFFF */
|
||||
if (val & 0x80) {
|
||||
access_smm = ACCESS_SMRAM_X;
|
||||
/* SMRAM 0: A0000-BFFFF */
|
||||
if (val & 0x80) {
|
||||
access_smm = ACCESS_SMRAM_X;
|
||||
|
||||
switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal = ACCESS_SMRAM_RX;
|
||||
/* FALLTHROUGH */
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal = ACCESS_SMRAM_RX;
|
||||
/* FALLTHROUGH */
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (val & 0x40) switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal |= ACCESS_SMRAM_W;
|
||||
/* FALLTHROUGH */
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_W;
|
||||
break;
|
||||
}
|
||||
if (val & 0x40)
|
||||
switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal |= ACCESS_SMRAM_W;
|
||||
/* FALLTHROUGH */
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_W;
|
||||
break;
|
||||
}
|
||||
|
||||
smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30));
|
||||
smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30));
|
||||
|
||||
mem_set_access(ACCESS_NORMAL, 3, 0xa0000, 0x20000, access_normal);
|
||||
mem_set_access(ACCESS_SMM, 3, 0xa0000, 0x20000, access_smm);
|
||||
mem_set_access(ACCESS_NORMAL, 3, 0xa0000, 0x20000, access_normal);
|
||||
mem_set_access(ACCESS_SMM, 3, 0xa0000, 0x20000, access_smm);
|
||||
}
|
||||
|
||||
if (val & 0x08)
|
||||
smram_enable(dev->smram[1], 0x38000, 0xa8000, 0x08000, 0, 1);
|
||||
smram_enable(dev->smram[1], 0x38000, 0xa8000, 0x08000, 0, 1);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_shadow_recalc(int cur_reg, ali1621_t *dev)
|
||||
{
|
||||
int i, r_bit, w_bit, reg;
|
||||
int i, r_bit, w_bit, reg;
|
||||
uint32_t base, flags = 0;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* C0000-EFFFF */
|
||||
for (i = 0; i < 12; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
r_bit = (i << 1) + 4;
|
||||
reg = 0x84;
|
||||
if (r_bit > 23) {
|
||||
r_bit &= 7;
|
||||
reg += 3;
|
||||
} else if (r_bit > 15) {
|
||||
r_bit &= 7;
|
||||
reg += 2;
|
||||
} else if (r_bit > 7) {
|
||||
r_bit &= 7;
|
||||
reg++;
|
||||
}
|
||||
w_bit = r_bit + 1;
|
||||
base = 0x000c0000 + (i << 14);
|
||||
r_bit = (i << 1) + 4;
|
||||
reg = 0x84;
|
||||
if (r_bit > 23) {
|
||||
r_bit &= 7;
|
||||
reg += 3;
|
||||
} else if (r_bit > 15) {
|
||||
r_bit &= 7;
|
||||
reg += 2;
|
||||
} else if (r_bit > 7) {
|
||||
r_bit &= 7;
|
||||
reg++;
|
||||
}
|
||||
w_bit = r_bit + 1;
|
||||
|
||||
flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
|
||||
ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E');
|
||||
ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00004000, flags);
|
||||
}
|
||||
|
||||
/* F0000-FFFFF */
|
||||
base = 0x000f0000;
|
||||
base = 0x000f0000;
|
||||
r_bit = 4;
|
||||
w_bit = 5;
|
||||
reg = 0x87;
|
||||
reg = 0x87;
|
||||
|
||||
flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios |= 1;
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios_write |= 1;
|
||||
shadowbios_write |= 1;
|
||||
|
||||
ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x0000ffff,
|
||||
(dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E');
|
||||
(dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00010000, flags);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_mask_bar(ali1621_t *dev)
|
||||
{
|
||||
uint32_t bar, mask;
|
||||
|
||||
switch (dev->pci_conf[0xbc] & 0x0f) {
|
||||
case 0x00:
|
||||
default:
|
||||
mask = 0x00000000;
|
||||
break;
|
||||
case 0x01:
|
||||
mask = 0xfff00000;
|
||||
break;
|
||||
case 0x02:
|
||||
mask = 0xffe00000;
|
||||
break;
|
||||
case 0x03:
|
||||
mask = 0xffc00000;
|
||||
break;
|
||||
case 0x04:
|
||||
mask = 0xff800000;
|
||||
break;
|
||||
case 0x06:
|
||||
mask = 0xff000000;
|
||||
break;
|
||||
case 0x07:
|
||||
mask = 0xfe000000;
|
||||
break;
|
||||
case 0x08:
|
||||
mask = 0xfc000000;
|
||||
break;
|
||||
case 0x09:
|
||||
mask = 0xf8000000;
|
||||
break;
|
||||
case 0x0a:
|
||||
mask = 0xf0000000;
|
||||
break;
|
||||
case 0x00:
|
||||
default:
|
||||
mask = 0x00000000;
|
||||
break;
|
||||
case 0x01:
|
||||
mask = 0xfff00000;
|
||||
break;
|
||||
case 0x02:
|
||||
mask = 0xffe00000;
|
||||
break;
|
||||
case 0x03:
|
||||
mask = 0xffc00000;
|
||||
break;
|
||||
case 0x04:
|
||||
mask = 0xff800000;
|
||||
break;
|
||||
case 0x06:
|
||||
mask = 0xff000000;
|
||||
break;
|
||||
case 0x07:
|
||||
mask = 0xfe000000;
|
||||
break;
|
||||
case 0x08:
|
||||
mask = 0xfc000000;
|
||||
break;
|
||||
case 0x09:
|
||||
mask = 0xf8000000;
|
||||
break;
|
||||
case 0x0a:
|
||||
mask = 0xf0000000;
|
||||
break;
|
||||
}
|
||||
|
||||
bar = ((dev->pci_conf[0x13] << 24) | (dev->pci_conf[0x12] << 16)) & mask;
|
||||
bar = ((dev->pci_conf[0x13] << 24) | (dev->pci_conf[0x12] << 16)) & mask;
|
||||
dev->pci_conf[0x12] = (bar >> 16) & 0xff;
|
||||
dev->pci_conf[0x13] = (bar >> 24) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
ali1621_t *dev = (ali1621_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->pci_conf[0x12] = (val & 0xc0);
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[0x13] = val;
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0x12:
|
||||
dev->pci_conf[0x12] = (val & 0xc0);
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[0x13] = val;
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
|
||||
case 0x34:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x34:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x42:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x42:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x48:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4b:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x4b:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x9f;
|
||||
break;
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x9f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val & 0xb4;
|
||||
break;
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val & 0xb4;
|
||||
break;
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->pci_conf[addr] = val & 0x08;
|
||||
break;
|
||||
case 0x57:
|
||||
dev->pci_conf[addr] = val & 0x08;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x62:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x62:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
dev->pci_conf[addr] = val & 0xb7;
|
||||
break;
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x64:
|
||||
dev->pci_conf[addr] = val & 0xb7;
|
||||
break;
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] &= ~(val & 0x33);
|
||||
break;
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] &= ~(val & 0x33);
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x67:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6c ... 0x7b:
|
||||
/* Bits 22:20 = DRAM Row size:
|
||||
- 000: 4 MB;
|
||||
- 001: 8 MB;
|
||||
- 010: 16 MB;
|
||||
- 011: 32 MB;
|
||||
- 100: 64 MB;
|
||||
- 101: 128 MB;
|
||||
- 110: 256 MB;
|
||||
- 111: Reserved. */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_ali1621(dev->pci_conf, 0x6c, 0x7b);
|
||||
break;
|
||||
case 0x6c ... 0x7b:
|
||||
/* Bits 22:20 = DRAM Row size:
|
||||
- 000: 4 MB;
|
||||
- 001: 8 MB;
|
||||
- 010: 16 MB;
|
||||
- 011: 32 MB;
|
||||
- 100: 64 MB;
|
||||
- 101: 128 MB;
|
||||
- 110: 256 MB;
|
||||
- 111: Reserved. */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_ali1621(dev->pci_conf, 0x6c, 0x7b);
|
||||
break;
|
||||
|
||||
case 0x7c ... 0x7f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x7c ... 0x7f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
break;
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
ali1621_smram_recalc(val & 0xfc, dev);
|
||||
break;
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
ali1621_smram_recalc(val & 0xfc, dev);
|
||||
break;
|
||||
|
||||
case 0x84 ... 0x87:
|
||||
if (addr == 0x87)
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
else
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1621_shadow_recalc(val, dev);
|
||||
break;
|
||||
case 0x84 ... 0x87:
|
||||
if (addr == 0x87)
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
else
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1621_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x88: case 0x89:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x8a:
|
||||
dev->pci_conf[addr] = val & 0xc5;
|
||||
break;
|
||||
case 0x8b:
|
||||
dev->pci_conf[addr] = val & 0xbf;
|
||||
break;
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x8a:
|
||||
dev->pci_conf[addr] = val & 0xc5;
|
||||
break;
|
||||
case 0x8b:
|
||||
dev->pci_conf[addr] = val & 0xbf;
|
||||
break;
|
||||
|
||||
case 0x8c ... 0x8f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x8c ... 0x8f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x91:
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
case 0x90:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x91:
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x94 ... 0x97:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x94 ... 0x97:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x98 ... 0x9b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x98 ... 0x9b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9c ... 0x9f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x9c ... 0x9f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa0: case 0xa1:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xa0:
|
||||
case 0xa1:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xbc:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0xbd:
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0xbe: case 0xbf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xbc:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0xbd:
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0xbe:
|
||||
case 0xbf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
dev->pci_conf[addr] = val & 0xb1;
|
||||
break;
|
||||
case 0xc0:
|
||||
dev->pci_conf[addr] = val & 0xb1;
|
||||
break;
|
||||
|
||||
case 0xc4 ... 0xc7:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xc4 ... 0xc7:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xc8:
|
||||
dev->pci_conf[addr] = val & 0x8c;
|
||||
break;
|
||||
case 0xc9:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xca:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0xcb:
|
||||
dev->pci_conf[addr] = val & 0x87;
|
||||
break;
|
||||
case 0xc8:
|
||||
dev->pci_conf[addr] = val & 0x8c;
|
||||
break;
|
||||
case 0xc9:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xca:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0xcb:
|
||||
dev->pci_conf[addr] = val & 0x87;
|
||||
break;
|
||||
|
||||
case 0xcc ... 0xcf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xcc ... 0xcf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xd0:
|
||||
dev->pci_conf[addr] = val & 0x80;
|
||||
break;
|
||||
case 0xd2:
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
case 0xd3:
|
||||
dev->pci_conf[addr] = val & 0xb0;
|
||||
break;
|
||||
case 0xd0:
|
||||
dev->pci_conf[addr] = val & 0x80;
|
||||
break;
|
||||
case 0xd2:
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
case 0xd3:
|
||||
dev->pci_conf[addr] = val & 0xb0;
|
||||
break;
|
||||
|
||||
case 0xd4:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd5:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
case 0xd6: case 0xd7:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd4:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd5:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
case 0xd6:
|
||||
case 0xd7:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xf0 ... 0xff:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xf0 ... 0xff:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1621_read(int func, int addr, void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ali1621_t *dev = (ali1621_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_reset(void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
int i;
|
||||
ali1621_t *dev = (ali1621_t *) priv;
|
||||
int i;
|
||||
|
||||
/* Default Registers */
|
||||
dev->pci_conf[0x00] = 0xb9;
|
||||
@@ -636,14 +631,13 @@ ali1621_reset(void *priv)
|
||||
ali1621_write(0, 0x83, 0x08, dev);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ali1621_write(0, 0x84 + i, 0x00, dev);
|
||||
ali1621_write(0, 0x84 + i, 0x00, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_close(void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
ali1621_t *dev = (ali1621_t *) priv;
|
||||
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
@@ -651,11 +645,10 @@ ali1621_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1621_init(const device_t *info)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)malloc(sizeof(ali1621_t));
|
||||
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
|
||||
memset(dev, 0, sizeof(ali1621_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev);
|
||||
@@ -671,15 +664,15 @@ ali1621_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t ali1621_device = {
|
||||
.name = "ALi M1621 CPU-to-PCI Bridge",
|
||||
.name = "ALi M1621 CPU-to-PCI Bridge",
|
||||
.internal_name = "ali1621",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = ali1621_init,
|
||||
.close = ali1621_close,
|
||||
.reset = ali1621_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = ali1621_init,
|
||||
.close = ali1621_close,
|
||||
.reset = ali1621_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -35,18 +35,15 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct ali6117_t
|
||||
{
|
||||
uint32_t local;
|
||||
typedef struct ali6117_t {
|
||||
uint32_t local;
|
||||
|
||||
/* Main registers (port 22h/23h) */
|
||||
uint8_t unlocked, mode;
|
||||
uint8_t reg_offset;
|
||||
uint8_t regs[256];
|
||||
uint8_t unlocked, mode;
|
||||
uint8_t reg_offset;
|
||||
uint8_t regs[256];
|
||||
} ali6117_t;
|
||||
|
||||
|
||||
/* Total size, Bank 0 size, Bank 1 size, Bank 2 size, Bank 3 size. */
|
||||
static uint32_t ali6117_modes[32][5] = {
|
||||
{ 1024, 512, 512, 0, 0 },
|
||||
@@ -83,7 +80,6 @@ static uint32_t ali6117_modes[32][5] = {
|
||||
{ 65536, 32768, 32768, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI6117_LOG
|
||||
int ali6117_do_log = ENABLE_ALI6117_LOG;
|
||||
|
||||
@@ -93,108 +89,105 @@ ali6117_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (ali6117_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali6117_log(fmt, ...)
|
||||
# define ali6117_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ali6117_recalcmapping(ali6117_t *dev)
|
||||
{
|
||||
uint8_t reg, bitpair;
|
||||
uint8_t reg, bitpair;
|
||||
uint32_t base, size;
|
||||
int state;
|
||||
int state;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
ali6117_log("ALI6117: Shadowing for A0000-BFFFF (reg 12 bit 1) = %s\n", (dev->regs[0x12] & 0x02) ? "on" : "off");
|
||||
mem_set_mem_state(0xa0000, 0x20000, (dev->regs[0x12] & 0x02) ? (MEM_WRITE_INTERNAL | MEM_READ_INTERNAL) : (MEM_WRITE_EXTANY | MEM_READ_EXTANY));
|
||||
|
||||
for (reg = 0; reg <= 1; reg++) {
|
||||
for (bitpair = 0; bitpair <= 3; bitpair++) {
|
||||
size = 0x8000;
|
||||
base = 0xc0000 + (size * ((reg * 4) + bitpair));
|
||||
ali6117_log("ALI6117: Shadowing for %05X-%05X (reg %02X bp %d wmask %02X rmask %02X) =", base, base + size - 1, 0x14 + reg, bitpair, 1 << ((bitpair * 2) + 1), 1 << (bitpair * 2));
|
||||
for (bitpair = 0; bitpair <= 3; bitpair++) {
|
||||
size = 0x8000;
|
||||
base = 0xc0000 + (size * ((reg * 4) + bitpair));
|
||||
ali6117_log("ALI6117: Shadowing for %05X-%05X (reg %02X bp %d wmask %02X rmask %02X) =", base, base + size - 1, 0x14 + reg, bitpair, 1 << ((bitpair * 2) + 1), 1 << (bitpair * 2));
|
||||
|
||||
state = 0;
|
||||
if (dev->regs[0x14 + reg] & (1 << ((bitpair * 2) + 1))) {
|
||||
ali6117_log(" w on");
|
||||
state |= MEM_WRITE_INTERNAL;
|
||||
if (base >= 0xe0000)
|
||||
shadowbios_write |= 1;
|
||||
} else {
|
||||
ali6117_log(" w off");
|
||||
state |= MEM_WRITE_EXTANY;
|
||||
}
|
||||
if (dev->regs[0x14 + reg] & (1 << (bitpair * 2))) {
|
||||
ali6117_log("; r on\n");
|
||||
state |= MEM_READ_INTERNAL;
|
||||
if (base >= 0xe0000)
|
||||
shadowbios |= 1;
|
||||
} else {
|
||||
ali6117_log("; r off\n");
|
||||
state |= MEM_READ_EXTANY;
|
||||
}
|
||||
state = 0;
|
||||
if (dev->regs[0x14 + reg] & (1 << ((bitpair * 2) + 1))) {
|
||||
ali6117_log(" w on");
|
||||
state |= MEM_WRITE_INTERNAL;
|
||||
if (base >= 0xe0000)
|
||||
shadowbios_write |= 1;
|
||||
} else {
|
||||
ali6117_log(" w off");
|
||||
state |= MEM_WRITE_EXTANY;
|
||||
}
|
||||
if (dev->regs[0x14 + reg] & (1 << (bitpair * 2))) {
|
||||
ali6117_log("; r on\n");
|
||||
state |= MEM_READ_INTERNAL;
|
||||
if (base >= 0xe0000)
|
||||
shadowbios |= 1;
|
||||
} else {
|
||||
ali6117_log("; r off\n");
|
||||
state |= MEM_READ_EXTANY;
|
||||
}
|
||||
|
||||
mem_set_mem_state(base, size, state);
|
||||
}
|
||||
mem_set_mem_state(base, size, state);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali6117_bank_recalc(ali6117_t *dev)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
uint32_t bank, addr;
|
||||
|
||||
for (i = 0x00000000; i < (mem_size << 10); i += 4096) {
|
||||
if ((i >= 0x000a0000) && (i < 0x00100000))
|
||||
continue;
|
||||
if ((i >= 0x000a0000) && (i < 0x00100000))
|
||||
continue;
|
||||
|
||||
if (!is6117 && (i >= 0x00f00000) && (i < 0x01000000))
|
||||
continue;
|
||||
if (!is6117 && (i >= 0x00f00000) && (i < 0x01000000))
|
||||
continue;
|
||||
|
||||
if (is6117 && (i >= 0x03f00000) && (i < 0x04000000))
|
||||
continue;
|
||||
if (is6117 && (i >= 0x03f00000) && (i < 0x04000000))
|
||||
continue;
|
||||
|
||||
switch (dev->regs[0x10] & 0xf8) {
|
||||
case 0xe8:
|
||||
bank = (i >> 12) & 3;
|
||||
addr = (i & 0xfff) | ((i >> 14) << 12);
|
||||
ali6117_log("E8 (%08X): Bank %i, address %08X vs. bank size %08X\n", i, bank, addr, ali6117_modes[dev->mode][bank + 1] * 1024);
|
||||
if (addr < (ali6117_modes[dev->mode][bank + 1] * 1024))
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0xf8:
|
||||
bank = (i >> 12) & 1;
|
||||
addr = (i & 0xfff) | ((i >> 13) << 12);
|
||||
ali6117_log("F8 (%08X): Bank %i, address %08X vs. bank size %08X\n", i, bank, addr, ali6117_modes[dev->mode][bank + 1] * 1024);
|
||||
if (addr < (ali6117_modes[dev->mode][bank + 1] * 1024))
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
default:
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
switch (dev->regs[0x10] & 0xf8) {
|
||||
case 0xe8:
|
||||
bank = (i >> 12) & 3;
|
||||
addr = (i & 0xfff) | ((i >> 14) << 12);
|
||||
ali6117_log("E8 (%08X): Bank %i, address %08X vs. bank size %08X\n", i, bank, addr, ali6117_modes[dev->mode][bank + 1] * 1024);
|
||||
if (addr < (ali6117_modes[dev->mode][bank + 1] * 1024))
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0xf8:
|
||||
bank = (i >> 12) & 1;
|
||||
addr = (i & 0xfff) | ((i >> 13) << 12);
|
||||
ali6117_log("F8 (%08X): Bank %i, address %08X vs. bank size %08X\n", i, bank, addr, ali6117_modes[dev->mode][bank + 1] * 1024);
|
||||
if (addr < (ali6117_modes[dev->mode][bank + 1] * 1024))
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
default:
|
||||
mem_set_mem_state_both(i, 4096, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -203,194 +196,202 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
ali6117_log("ALI6117: reg_write(%04X, %02X)\n", addr, val);
|
||||
|
||||
if (addr == 0x22)
|
||||
dev->reg_offset = val;
|
||||
dev->reg_offset = val;
|
||||
else if (dev->reg_offset == 0x13)
|
||||
dev->unlocked = (val == 0xc5);
|
||||
dev->unlocked = (val == 0xc5);
|
||||
else if (dev->unlocked) {
|
||||
ali6117_log("ALI6117: regs[%02X] = %02X\n", dev->reg_offset, val);
|
||||
ali6117_log("ALI6117: regs[%02X] = %02X\n", dev->reg_offset, val);
|
||||
|
||||
if (!(dev->local & 0x08) || (dev->reg_offset < 0x30)) switch (dev->reg_offset) {
|
||||
case 0x30: case 0x34: case 0x35: case 0x3e:
|
||||
case 0x3f: case 0x46: case 0x4c: case 0x6a:
|
||||
case 0x73:
|
||||
return; /* read-only registers */
|
||||
if (!(dev->local & 0x08) || (dev->reg_offset < 0x30))
|
||||
switch (dev->reg_offset) {
|
||||
case 0x30:
|
||||
case 0x34:
|
||||
case 0x35:
|
||||
case 0x3e:
|
||||
case 0x3f:
|
||||
case 0x46:
|
||||
case 0x4c:
|
||||
case 0x6a:
|
||||
case 0x73:
|
||||
return; /* read-only registers */
|
||||
|
||||
case 0x10:
|
||||
refresh_at_enable = !(val & 0x02) || !!(dev->regs[0x20] & 0x80);
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
case 0x10:
|
||||
refresh_at_enable = !(val & 0x02) || !!(dev->regs[0x20] & 0x80);
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
|
||||
if (dev->local != 0x8) {
|
||||
if (val & 0x04)
|
||||
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
if (dev->local != 0x8) {
|
||||
if (val & 0x04)
|
||||
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
ali6117_bank_recalc(dev);
|
||||
}
|
||||
break;
|
||||
ali6117_bank_recalc(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
val &= 0xf7;
|
||||
/* FALL-THROUGH */
|
||||
case 0x12:
|
||||
val &= 0xf7;
|
||||
/* FALL-THROUGH */
|
||||
|
||||
case 0x14: case 0x15:
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
ali6117_recalcmapping(dev);
|
||||
break;
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
ali6117_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x1e:
|
||||
val &= 0x07;
|
||||
case 0x1e:
|
||||
val &= 0x07;
|
||||
|
||||
switch (val) {
|
||||
/* Half PIT clock. */
|
||||
case 0x0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
switch (val) {
|
||||
/* Half PIT clock. */
|
||||
case 0x0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
|
||||
/* Divisors on the input clock PCLK2, which is double the CPU clock. */
|
||||
case 0x1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 1.5);
|
||||
break;
|
||||
/* Divisors on the input clock PCLK2, which is double the CPU clock. */
|
||||
case 0x1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 1.5);
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 2);
|
||||
break;
|
||||
case 0x2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 2);
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
cpu_set_isa_speed(cpu_busspeed / 2.5);
|
||||
break;
|
||||
case 0x3:
|
||||
cpu_set_isa_speed(cpu_busspeed / 2.5);
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 3);
|
||||
break;
|
||||
case 0x4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 3);
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
case 0x5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
case 0x6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x7:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
val &= 0xbf;
|
||||
refresh_at_enable = !(dev->regs[0x10] & 0x02) || !!(val & 0x80);
|
||||
break;
|
||||
case 0x20:
|
||||
val &= 0xbf;
|
||||
refresh_at_enable = !(dev->regs[0x10] & 0x02) || !!(val & 0x80);
|
||||
break;
|
||||
|
||||
case 0x31:
|
||||
/* TODO: fast gate A20 (bit 0) */
|
||||
val &= 0x21;
|
||||
break;
|
||||
case 0x31:
|
||||
/* TODO: fast gate A20 (bit 0) */
|
||||
val &= 0x21;
|
||||
break;
|
||||
|
||||
case 0x32:
|
||||
val &= 0xc1;
|
||||
break;
|
||||
case 0x32:
|
||||
val &= 0xc1;
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
val &= 0xfd;
|
||||
break;
|
||||
case 0x33:
|
||||
val &= 0xfd;
|
||||
break;
|
||||
|
||||
case 0x36:
|
||||
val &= 0xf0;
|
||||
val |= dev->regs[dev->reg_offset];
|
||||
break;
|
||||
case 0x36:
|
||||
val &= 0xf0;
|
||||
val |= dev->regs[dev->reg_offset];
|
||||
break;
|
||||
|
||||
case 0x37:
|
||||
val &= 0xf5;
|
||||
break;
|
||||
case 0x37:
|
||||
val &= 0xf5;
|
||||
break;
|
||||
|
||||
case 0x3c:
|
||||
val &= 0x8f;
|
||||
ide_pri_disable();
|
||||
ide_set_base(1, (val & 0x01) ? 0x170 : 0x1f0);
|
||||
ide_set_side(1, (val & 0x01) ? 0x376 : 0x3f6);
|
||||
ide_pri_enable();
|
||||
break;
|
||||
case 0x3c:
|
||||
val &= 0x8f;
|
||||
ide_pri_disable();
|
||||
ide_set_base(1, (val & 0x01) ? 0x170 : 0x1f0);
|
||||
ide_set_side(1, (val & 0x01) ? 0x376 : 0x3f6);
|
||||
ide_pri_enable();
|
||||
break;
|
||||
|
||||
case 0x44: case 0x45:
|
||||
val &= 0x3f;
|
||||
break;
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
val &= 0x3f;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
val &= 0xfe;
|
||||
break;
|
||||
case 0x4a:
|
||||
val &= 0xfe;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
val &= 0x03;
|
||||
break;
|
||||
case 0x55:
|
||||
val &= 0x03;
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
val &= 0xc7;
|
||||
break;
|
||||
case 0x56:
|
||||
val &= 0xc7;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
val &= 0xc3;
|
||||
break;
|
||||
case 0x58:
|
||||
val &= 0xc3;
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
val &= 0x60;
|
||||
break;
|
||||
case 0x59:
|
||||
val &= 0x60;
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
val &= 0x1f;
|
||||
break;
|
||||
case 0x5b:
|
||||
val &= 0x1f;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
val &= 0xf7;
|
||||
break;
|
||||
case 0x64:
|
||||
val &= 0xf7;
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
val &= 0xe3;
|
||||
break;
|
||||
case 0x66:
|
||||
val &= 0xe3;
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
val &= 0xdf;
|
||||
break;
|
||||
case 0x67:
|
||||
val &= 0xdf;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
val &= 0x50;
|
||||
break;
|
||||
case 0x69:
|
||||
val &= 0x50;
|
||||
break;
|
||||
|
||||
case 0x6b:
|
||||
val &= 0x7f;
|
||||
break;
|
||||
case 0x6b:
|
||||
val &= 0x7f;
|
||||
break;
|
||||
|
||||
case 0x6e: case 0x6f:
|
||||
val &= 0x03;
|
||||
break;
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
val &= 0x03;
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
val &= 0x1f;
|
||||
break;
|
||||
}
|
||||
case 0x71:
|
||||
val &= 0x1f;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali6117_reg_read(uint16_t addr, void *priv)
|
||||
{
|
||||
ali6117_t *dev = (ali6117_t *) priv;
|
||||
uint8_t ret;
|
||||
uint8_t ret;
|
||||
|
||||
if (addr == 0x22)
|
||||
ret = dev->reg_offset;
|
||||
ret = dev->reg_offset;
|
||||
else
|
||||
ret = dev->regs[dev->reg_offset];
|
||||
ret = dev->regs[dev->reg_offset];
|
||||
|
||||
ali6117_log("ALI6117: reg_read(%04X) = %02X\n", dev->reg_offset, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali6117_reset(void *priv)
|
||||
{
|
||||
@@ -408,11 +409,11 @@ ali6117_reset(void *priv)
|
||||
dev->regs[0x1d] = 0xff;
|
||||
dev->regs[0x20] = 0x80;
|
||||
if (dev->local & 0x08) {
|
||||
dev->regs[0x30] = 0x08;
|
||||
dev->regs[0x31] = 0x01;
|
||||
dev->regs[0x34] = 0x04; /* enable internal RTC */
|
||||
dev->regs[0x35] = 0x20; /* enable internal KBC */
|
||||
dev->regs[0x36] = dev->local & 0x07; /* M6117D ID */
|
||||
dev->regs[0x30] = 0x08;
|
||||
dev->regs[0x31] = 0x01;
|
||||
dev->regs[0x34] = 0x04; /* enable internal RTC */
|
||||
dev->regs[0x35] = 0x20; /* enable internal KBC */
|
||||
dev->regs[0x36] = dev->local & 0x07; /* M6117D ID */
|
||||
}
|
||||
|
||||
cpu_set_isa_speed(7159091);
|
||||
@@ -420,13 +421,12 @@ ali6117_reset(void *priv)
|
||||
refresh_at_enable = 1;
|
||||
|
||||
if (dev->local != 0x8) {
|
||||
/* On-board memory 15-16M is enabled by default. */
|
||||
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
ali6117_bank_recalc(dev);
|
||||
/* On-board memory 15-16M is enabled by default. */
|
||||
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
ali6117_bank_recalc(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali6117_setup(ali6117_t *dev)
|
||||
{
|
||||
@@ -434,10 +434,9 @@ ali6117_setup(ali6117_t *dev)
|
||||
|
||||
/* Main register interface */
|
||||
io_sethandler(0x22, 2,
|
||||
ali6117_reg_read, NULL, NULL, ali6117_reg_write, NULL, NULL, dev);
|
||||
ali6117_reg_read, NULL, NULL, ali6117_reg_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali6117_close(void *priv)
|
||||
{
|
||||
@@ -446,12 +445,11 @@ ali6117_close(void *priv)
|
||||
ali6117_log("ALI6117: close()\n");
|
||||
|
||||
io_removehandler(0x22, 2,
|
||||
ali6117_reg_read, NULL, NULL, ali6117_reg_write, NULL, NULL, dev);
|
||||
ali6117_reg_read, NULL, NULL, ali6117_reg_write, NULL, NULL, dev);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali6117_init(const device_t *info)
|
||||
{
|
||||
@@ -469,44 +467,44 @@ ali6117_init(const device_t *info)
|
||||
ali6117_setup(dev);
|
||||
|
||||
for (i = 31; i >= 0; i--) {
|
||||
if ((mem_size >= ali6117_modes[i][0]) && (ali6117_modes[i][0] > last_match)) {
|
||||
last_match = ali6117_modes[i][0];
|
||||
dev->mode = i;
|
||||
}
|
||||
if ((mem_size >= ali6117_modes[i][0]) && (ali6117_modes[i][0] > last_match)) {
|
||||
last_match = ali6117_modes[i][0];
|
||||
dev->mode = i;
|
||||
}
|
||||
}
|
||||
|
||||
ali6117_reset(dev);
|
||||
|
||||
if (!(dev->local & 0x08))
|
||||
pic_elcr_io_handler(0);
|
||||
pic_elcr_io_handler(0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t ali1217_device = {
|
||||
.name = "ALi M1217",
|
||||
.name = "ALi M1217",
|
||||
.internal_name = "ali1217",
|
||||
.flags = DEVICE_AT,
|
||||
.local = 0x8,
|
||||
.init = ali6117_init,
|
||||
.close = ali6117_close,
|
||||
.reset = ali6117_reset,
|
||||
.flags = DEVICE_AT,
|
||||
.local = 0x8,
|
||||
.init = ali6117_init,
|
||||
.close = ali6117_close,
|
||||
.reset = ali6117_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ali6117d_device = {
|
||||
.name = "ALi M6117D",
|
||||
.name = "ALi M6117D",
|
||||
.internal_name = "ali6117d",
|
||||
.flags = DEVICE_AT,
|
||||
.local = 0x2,
|
||||
.init = ali6117_init,
|
||||
.close = ali6117_close,
|
||||
.reset = ali6117_reset,
|
||||
.flags = DEVICE_AT,
|
||||
.local = 0x2,
|
||||
.init = ali6117_init,
|
||||
.close = ali6117_close,
|
||||
.reset = ali6117_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <86box/smram.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_CONTAQ_82C59X_LOG
|
||||
int contaq_82c59x_do_log = ENABLE_CONTAQ_82C59X_LOG;
|
||||
|
||||
@@ -38,274 +37,268 @@ contaq_82c59x_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (contaq_82c59x_do_log)
|
||||
{
|
||||
if (contaq_82c59x_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define contaq_82c59x_log(fmt, ...)
|
||||
# define contaq_82c59x_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t phys, virt;
|
||||
uint32_t phys, virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, green,
|
||||
smi_status_set,
|
||||
regs[256], smi_status[2];
|
||||
uint8_t index, green,
|
||||
smi_status_set,
|
||||
regs[256], smi_status[2];
|
||||
|
||||
smram_t *smram[2];
|
||||
smram_t *smram[2];
|
||||
} contaq_82c59x_t;
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev)
|
||||
{
|
||||
if (dev->regs[0x1c] & 0x02)
|
||||
cpu_set_isa_speed(7159091);
|
||||
cpu_set_isa_speed(7159091);
|
||||
else {
|
||||
/* TODO: ISA clock dividers for 386 and alt. 486. */
|
||||
switch (dev->regs[0x10] & 0x03) {
|
||||
case 0x00:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
case 0x01:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
case 0x02:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
case 0x03:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
}
|
||||
/* TODO: ISA clock dividers for 386 and alt. 486. */
|
||||
switch (dev->regs[0x10] & 0x03) {
|
||||
case 0x00:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
case 0x01:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
case 0x02:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
case 0x03:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_shadow_recalc(contaq_82c59x_t *dev)
|
||||
{
|
||||
uint32_t i, base;
|
||||
uint8_t bit;
|
||||
uint8_t bit;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* F0000-FFFFF */
|
||||
if (dev->regs[0x15] & 0x80) {
|
||||
shadowbios |= 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
shadowbios |= 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
} else {
|
||||
shadowbios_write |= 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
shadowbios_write |= 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
/* C0000-CFFFF */
|
||||
if (dev->regs[0x15] & 0x01)
|
||||
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x15] & bit) {
|
||||
if (dev->regs[0x15] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x15] & bit) {
|
||||
if (dev->regs[0x15] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->green) {
|
||||
/* D0000-DFFFF */
|
||||
if (dev->regs[0x6e] & 0x01)
|
||||
mem_set_mem_state_both(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x6e] & bit) {
|
||||
if (dev->regs[0x6e] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
/* D0000-DFFFF */
|
||||
if (dev->regs[0x6e] & 0x01)
|
||||
mem_set_mem_state_both(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x6e] & bit) {
|
||||
if (dev->regs[0x6e] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* E0000-EFFFF */
|
||||
if (dev->regs[0x6f] & 0x01)
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xe0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x6f] & bit) {
|
||||
shadowbios |= 1;
|
||||
if (dev->regs[0x6f] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else {
|
||||
shadowbios_write |= 1;
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
/* E0000-EFFFF */
|
||||
if (dev->regs[0x6f] & 0x01)
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xe0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x6f] & bit) {
|
||||
shadowbios |= 1;
|
||||
if (dev->regs[0x6f] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else {
|
||||
shadowbios_write |= 1;
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_smram_recalc(contaq_82c59x_t *dev)
|
||||
{
|
||||
smram_disable(dev->smram[1]);
|
||||
|
||||
if (dev->regs[0x70] & 0x04)
|
||||
smram_enable(dev->smram[1], 0x00040000, 0x000a0000, 0x00020000, 1, 1);
|
||||
smram_enable(dev->smram[1], 0x00040000, 0x000a0000, 0x00020000, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)priv;
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
contaq_82c59x_log("Contaq 82C59x: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
case 0x23:
|
||||
contaq_82c59x_log("Contaq 82C59x: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
if ((dev->index >= 0x60) && !dev->green)
|
||||
return;
|
||||
if ((dev->index >= 0x60) && !dev->green)
|
||||
return;
|
||||
|
||||
switch (dev->index) {
|
||||
/* Registers common to 82C596(A) and 82C597. */
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
break;
|
||||
switch (dev->index) {
|
||||
/* Registers common to 82C596(A) and 82C597. */
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
dev->regs[dev->index] = val;
|
||||
cpu_cache_int_enabled = !!(val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x11:
|
||||
dev->regs[dev->index] = val;
|
||||
cpu_cache_int_enabled = !!(val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x12: case 0x13:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
dev->regs[dev->index] = val;
|
||||
reset_on_hlt = !!(val & 0x80);
|
||||
break;
|
||||
case 0x14:
|
||||
dev->regs[dev->index] = val;
|
||||
reset_on_hlt = !!(val & 0x80);
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x15:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x16 ... 0x1b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x16 ... 0x1b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
/* TODO: What's NPRST (generated if bit 3 is set)? */
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
break;
|
||||
case 0x1c:
|
||||
/* TODO: What's NPRST (generated if bit 3 is set)? */
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x1d ... 0x1f:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x1d ... 0x1f:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
/* Green (82C597-specific) registers. */
|
||||
case 0x60 ... 0x63:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
/* Green (82C597-specific) registers. */
|
||||
case 0x60 ... 0x63:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
dev->regs[dev->index] = val;
|
||||
if (val & 0x80) {
|
||||
if (dev->regs[0x65] & 0x80)
|
||||
smi_raise();
|
||||
dev->smi_status[0] |= 0x10;
|
||||
}
|
||||
break;
|
||||
case 0x64:
|
||||
dev->regs[dev->index] = val;
|
||||
if (val & 0x80) {
|
||||
if (dev->regs[0x65] & 0x80)
|
||||
smi_raise();
|
||||
dev->smi_status[0] |= 0x10;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x65 ... 0x69:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x65 ... 0x69:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
dev->regs[dev->index] = val;
|
||||
dev->smi_status_set = !!(val & 0x80);
|
||||
break;
|
||||
case 0x6a:
|
||||
dev->regs[dev->index] = val;
|
||||
dev->smi_status_set = !!(val & 0x80);
|
||||
break;
|
||||
|
||||
case 0x6b ... 0x6d:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x6b ... 0x6d:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x6e: case 0x6f:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_smram_recalc(dev);
|
||||
break;
|
||||
case 0x70:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x71 ... 0x79:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x71 ... 0x79:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x7b: case 0x7c:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x7b:
|
||||
case 0x7c:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
contaq_82c59x_read(uint16_t addr, void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x23) {
|
||||
if (dev->index == 0x6a) {
|
||||
ret = dev->smi_status[dev->smi_status_set];
|
||||
/* I assume it's cleared on read. */
|
||||
dev->smi_status[dev->smi_status_set] = 0x00;
|
||||
} else
|
||||
ret = dev->regs[dev->index];
|
||||
if (dev->index == 0x6a) {
|
||||
ret = dev->smi_status[dev->smi_status_set];
|
||||
/* I assume it's cleared on read. */
|
||||
dev->smi_status[dev->smi_status_set] = 0x00;
|
||||
} else
|
||||
ret = dev->regs[dev->index];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_close(void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)priv;
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) priv;
|
||||
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
@@ -313,11 +306,10 @@ contaq_82c59x_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
contaq_82c59x_init(const device_t *info)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)malloc(sizeof(contaq_82c59x_t));
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) malloc(sizeof(contaq_82c59x_t));
|
||||
memset(dev, 0x00, sizeof(contaq_82c59x_t));
|
||||
|
||||
dev->green = info->local;
|
||||
@@ -334,42 +326,42 @@ contaq_82c59x_init(const device_t *info)
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
|
||||
if (dev->green) {
|
||||
/* SMRAM 0: Fixed A0000-BFFFF to A0000-BFFFF DRAM. */
|
||||
dev->smram[0] = smram_add();
|
||||
smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x00020000, 0, 1);
|
||||
/* SMRAM 0: Fixed A0000-BFFFF to A0000-BFFFF DRAM. */
|
||||
dev->smram[0] = smram_add();
|
||||
smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x00020000, 0, 1);
|
||||
|
||||
/* SMRAM 1: Optional. */
|
||||
dev->smram[1] = smram_add();
|
||||
contaq_82c59x_smram_recalc(dev);
|
||||
/* SMRAM 1: Optional. */
|
||||
dev->smram[1] = smram_add();
|
||||
contaq_82c59x_smram_recalc(dev);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t contaq_82c596a_device = {
|
||||
.name = "Contaq 82C596A",
|
||||
.name = "Contaq 82C596A",
|
||||
.internal_name = "contaq_82c596a",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = contaq_82c59x_init,
|
||||
.close = contaq_82c59x_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = contaq_82c59x_init,
|
||||
.close = contaq_82c59x_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t contaq_82c597_device = {
|
||||
.name = "Contaq 82C597",
|
||||
.name = "Contaq 82C597",
|
||||
.internal_name = "contaq_82c597",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = contaq_82c59x_init,
|
||||
.close = contaq_82c59x_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = contaq_82c59x_init,
|
||||
.close = contaq_82c59x_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -46,107 +46,104 @@ cs4031_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (cs4031_do_log)
|
||||
{
|
||||
if (cs4031_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cs4031_log(fmt, ...)
|
||||
# define cs4031_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void cs4031_shadow_recalc(cs4031_t *dev)
|
||||
static void
|
||||
cs4031_shadow_recalc(cs4031_t *dev)
|
||||
{
|
||||
mem_set_mem_state_both(0xa0000, 0x10000, (dev->regs[0x18] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xb0000, 0x10000, (dev->regs[0x18] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
|
||||
for (uint32_t i = 0; i < 7; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < 7; i++) {
|
||||
if (i < 4)
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, ((dev->regs[0x19] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
else
|
||||
mem_set_mem_state_both(0xd0000 + ((i - 4) << 16), 0x10000, ((dev->regs[0x19] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
}
|
||||
shadowbios = !!(dev->regs[0x19] & 0x40);
|
||||
shadowbios = !!(dev->regs[0x19] & 0x40);
|
||||
shadowbios_write = !!(dev->regs[0x1a] & 0x40);
|
||||
}
|
||||
|
||||
static void
|
||||
cs4031_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
cs4031_t *dev = (cs4031_t *)priv;
|
||||
cs4031_t *dev = (cs4031_t *) priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
cs4031_log("CS4031: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
switch (dev->index)
|
||||
{
|
||||
case 0x05:
|
||||
dev->regs[dev->index] = val & 0x3f;
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
cs4031_log("CS4031: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
switch (dev->index) {
|
||||
case 0x05:
|
||||
dev->regs[dev->index] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
dev->regs[dev->index] = val & 0xbc;
|
||||
break;
|
||||
case 0x06:
|
||||
dev->regs[dev->index] = val & 0xbc;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->regs[dev->index] = val & 0x0f;
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[dev->index] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val & 0x3d;
|
||||
break;
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val & 0x3d;
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
dev->regs[dev->index] = val & 0x8d;
|
||||
break;
|
||||
case 0x11:
|
||||
dev->regs[dev->index] = val & 0x8d;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
dev->regs[dev->index] = val & 0x8d;
|
||||
break;
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
dev->regs[dev->index] = val & 0x8d;
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
dev->regs[dev->index] = val & 0x7f;
|
||||
break;
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
dev->regs[dev->index] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
dev->regs[dev->index] = val & 0xf3;
|
||||
cs4031_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x18:
|
||||
dev->regs[dev->index] = val & 0xf3;
|
||||
cs4031_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x19:
|
||||
case 0x1a:
|
||||
dev->regs[dev->index] = val & 0x7f;
|
||||
cs4031_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x19:
|
||||
case 0x1a:
|
||||
dev->regs[dev->index] = val & 0x7f;
|
||||
cs4031_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x1b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x1b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
dev->regs[dev->index] = val & 0xb3;
|
||||
port_92_set_features(dev->port_92, val & 0x10, val & 0x20);
|
||||
case 0x1c:
|
||||
dev->regs[dev->index] = val & 0xb3;
|
||||
port_92_set_features(dev->port_92, val & 0x10, val & 0x20);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cs4031_read(uint16_t addr, void *priv)
|
||||
{
|
||||
cs4031_t *dev = (cs4031_t *)priv;
|
||||
cs4031_t *dev = (cs4031_t *) priv;
|
||||
|
||||
return (addr == 0x23) ? dev->regs[dev->index] : 0xff;
|
||||
}
|
||||
@@ -154,7 +151,7 @@ cs4031_read(uint16_t addr, void *priv)
|
||||
static void
|
||||
cs4031_close(void *priv)
|
||||
{
|
||||
cs4031_t *dev = (cs4031_t *)priv;
|
||||
cs4031_t *dev = (cs4031_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -162,7 +159,7 @@ cs4031_close(void *priv)
|
||||
static void *
|
||||
cs4031_init(const device_t *info)
|
||||
{
|
||||
cs4031_t *dev = (cs4031_t *)malloc(sizeof(cs4031_t));
|
||||
cs4031_t *dev = (cs4031_t *) malloc(sizeof(cs4031_t));
|
||||
memset(dev, 0, sizeof(cs4031_t));
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
@@ -176,15 +173,15 @@ cs4031_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t cs4031_device = {
|
||||
.name = "Chips & Technogies CS4031",
|
||||
.name = "Chips & Technogies CS4031",
|
||||
.internal_name = "cs4031",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = cs4031_init,
|
||||
.close = cs4031_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = cs4031_init,
|
||||
.close = cs4031_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -29,143 +29,153 @@
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int idx;
|
||||
uint8_t regs[256];
|
||||
int idx;
|
||||
uint8_t regs[256];
|
||||
} cs8230_t;
|
||||
|
||||
|
||||
static void
|
||||
shadow_control(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state) {
|
||||
case 0x00:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x01:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x10:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x11:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x00:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x01:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x10:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x11:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rethink_shadow_mappings(cs8230_t *cs8230)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 32; c++) {
|
||||
/* Addresses 40000-bffff in 16k blocks */
|
||||
if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7)))
|
||||
mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /* I/O channel */
|
||||
else
|
||||
mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /* System board */
|
||||
/* Addresses 40000-bffff in 16k blocks */
|
||||
if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7)))
|
||||
mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /* I/O channel */
|
||||
else
|
||||
mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /* System board */
|
||||
}
|
||||
|
||||
for (c = 0; c < 16; c++) {
|
||||
/* Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here */
|
||||
if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7)))
|
||||
mem_set_mem_state(0xc0000 + (c << 14), 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /* I/O channel */
|
||||
else
|
||||
shadow_control(0xc0000 + (c << 14), 0x4000, (cs8230->regs[9] >> (3 - (c >> 2))) & 0x11);
|
||||
/* Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here */
|
||||
if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7)))
|
||||
mem_set_mem_state(0xc0000 + (c << 14), 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /* I/O channel */
|
||||
else
|
||||
shadow_control(0xc0000 + (c << 14), 0x4000, (cs8230->regs[9] >> (3 - (c >> 2))) & 0x11);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
cs8230_read(uint16_t port, void *p)
|
||||
{
|
||||
cs8230_t *cs8230 = (cs8230_t *) p;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port & 1) {
|
||||
switch (cs8230->idx) {
|
||||
case 0x04: /* 82C301 ID/version */
|
||||
ret = cs8230->regs[cs8230->idx] & ~0xe3;
|
||||
break;
|
||||
switch (cs8230->idx) {
|
||||
case 0x04: /* 82C301 ID/version */
|
||||
ret = cs8230->regs[cs8230->idx] & ~0xe3;
|
||||
break;
|
||||
|
||||
case 0x08: /* 82C302 ID/Version */
|
||||
ret = cs8230->regs[cs8230->idx] & ~0xe0;
|
||||
break;
|
||||
case 0x08: /* 82C302 ID/Version */
|
||||
ret = cs8230->regs[cs8230->idx] & ~0xe0;
|
||||
break;
|
||||
|
||||
case 0x05: case 0x06: /* 82C301 registers */
|
||||
case 0x09: case 0x0a: case 0x0b: case 0x0c: /* 82C302 registers */
|
||||
case 0x0d: case 0x0e: case 0x0f:
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
case 0x28: case 0x29: case 0x2a:
|
||||
ret = cs8230->regs[cs8230->idx];
|
||||
break;
|
||||
}
|
||||
case 0x05:
|
||||
case 0x06: /* 82C301 registers */
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c: /* 82C302 registers */
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
case 0x2a:
|
||||
ret = cs8230->regs[cs8230->idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cs8230_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
cs8230_t *cs8230 = (cs8230_t *)p;
|
||||
cs8230_t *cs8230 = (cs8230_t *) p;
|
||||
|
||||
if (!(port & 1))
|
||||
cs8230->idx = val;
|
||||
cs8230->idx = val;
|
||||
else {
|
||||
cs8230->regs[cs8230->idx] = val;
|
||||
switch (cs8230->idx) {
|
||||
case 0x09: /* RAM/ROM Configuration in boot area */
|
||||
case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* Address maps */
|
||||
rethink_shadow_mappings(cs8230);
|
||||
break;
|
||||
}
|
||||
cs8230->regs[cs8230->idx] = val;
|
||||
switch (cs8230->idx) {
|
||||
case 0x09: /* RAM/ROM Configuration in boot area */
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f: /* Address maps */
|
||||
rethink_shadow_mappings(cs8230);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cs8230_close(void *priv)
|
||||
{
|
||||
cs8230_t *cs8230 = (cs8230_t *)priv;
|
||||
cs8230_t *cs8230 = (cs8230_t *) priv;
|
||||
|
||||
free(cs8230);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*cs8230_init(const device_t *info)
|
||||
*
|
||||
cs8230_init(const device_t *info)
|
||||
{
|
||||
cs8230_t *cs8230 = (cs8230_t *)malloc(sizeof(cs8230_t));
|
||||
cs8230_t *cs8230 = (cs8230_t *) malloc(sizeof(cs8230_t));
|
||||
memset(cs8230, 0, sizeof(cs8230_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0002, cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, cs8230);
|
||||
|
||||
if (mem_size > 768) {
|
||||
mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024);
|
||||
mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000);
|
||||
mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024);
|
||||
mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000);
|
||||
}
|
||||
|
||||
return cs8230;
|
||||
}
|
||||
|
||||
const device_t cs8230_device = {
|
||||
.name = "C&T CS8230 (386/AT)",
|
||||
.name = "C&T CS8230 (386/AT)",
|
||||
.internal_name = "cs8230",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = cs8230_init,
|
||||
.close = cs8230_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = cs8230_init,
|
||||
.close = cs8230_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -45,18 +45,18 @@ et6000_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (et6000_do_log)
|
||||
{
|
||||
if (et6000_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define et6000_log(fmt, ...)
|
||||
# define et6000_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void et6000_shadow_control(int base, int size, int can_read, int can_write)
|
||||
static void
|
||||
et6000_shadow_control(int base, int size, int can_read, int can_write)
|
||||
{
|
||||
mem_set_mem_state_both(base, size, (can_read ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (can_write ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
flushmmucache_nopc();
|
||||
@@ -65,57 +65,55 @@ static void et6000_shadow_control(int base, int size, int can_read, int can_writ
|
||||
static void
|
||||
et6000_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
et6000_t *dev = (et6000_t *)priv;
|
||||
et6000_t *dev = (et6000_t *) priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
switch (INDEX)
|
||||
{
|
||||
case 0: /* System Configuration Register */
|
||||
dev->regs[INDEX] = val & 0xdf;
|
||||
et6000_shadow_control(0xa0000, 0x20000, val & 1, val & 1);
|
||||
refresh_at_enable = !(val & 0x10);
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
switch (INDEX) {
|
||||
case 0: /* System Configuration Register */
|
||||
dev->regs[INDEX] = val & 0xdf;
|
||||
et6000_shadow_control(0xa0000, 0x20000, val & 1, val & 1);
|
||||
refresh_at_enable = !(val & 0x10);
|
||||
break;
|
||||
|
||||
case 1: /* CACHE Configuration and Non-Cacheable Block Size */
|
||||
dev->regs[INDEX] = val & 0xf0;
|
||||
break;
|
||||
case 1: /* CACHE Configuration and Non-Cacheable Block Size */
|
||||
dev->regs[INDEX] = val & 0xf0;
|
||||
break;
|
||||
|
||||
case 2: /* Non-Cacheable Block Address Register */
|
||||
dev->regs[INDEX] = val & 0xfe;
|
||||
break;
|
||||
case 2: /* Non-Cacheable Block Address Register */
|
||||
dev->regs[INDEX] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 3: /* DRAM Bank and Type Configuration Register */
|
||||
dev->regs[INDEX] = val;
|
||||
break;
|
||||
case 3: /* DRAM Bank and Type Configuration Register */
|
||||
dev->regs[INDEX] = val;
|
||||
break;
|
||||
|
||||
case 4: /* DRAM Configuration Register */
|
||||
dev->regs[INDEX] = val;
|
||||
et6000_shadow_control(0xc0000, 0x10000, (dev->regs[0x15] & 2) && (val & 0x20), (dev->regs[0x15] & 2) && (val & 0x20) && (dev->regs[0x15] & 1));
|
||||
et6000_shadow_control(0xd0000, 0x10000, (dev->regs[0x15] & 8) && (val & 0x20), (dev->regs[0x15] & 8) && (val & 0x20) && (dev->regs[0x15] & 4));
|
||||
break;
|
||||
case 4: /* DRAM Configuration Register */
|
||||
dev->regs[INDEX] = val;
|
||||
et6000_shadow_control(0xc0000, 0x10000, (dev->regs[0x15] & 2) && (val & 0x20), (dev->regs[0x15] & 2) && (val & 0x20) && (dev->regs[0x15] & 1));
|
||||
et6000_shadow_control(0xd0000, 0x10000, (dev->regs[0x15] & 8) && (val & 0x20), (dev->regs[0x15] & 8) && (val & 0x20) && (dev->regs[0x15] & 4));
|
||||
break;
|
||||
|
||||
case 5: /* Shadow RAM Configuration Register */
|
||||
dev->regs[INDEX] = val;
|
||||
et6000_shadow_control(0xc0000, 0x10000, (val & 2) && (dev->regs[0x14] & 0x20), (val & 2) && (dev->regs[0x14] & 0x20) && (val & 1));
|
||||
et6000_shadow_control(0xd0000, 0x10000, (val & 8) && (dev->regs[0x14] & 0x20), (val & 8) && (dev->regs[0x14] & 0x20) && (val & 4));
|
||||
et6000_shadow_control(0xe0000, 0x10000, val & 0x20, (val & 0x20) && (val & 0x10));
|
||||
et6000_shadow_control(0xf0000, 0x10000, val & 0x40, !(val & 0x40));
|
||||
case 5: /* Shadow RAM Configuration Register */
|
||||
dev->regs[INDEX] = val;
|
||||
et6000_shadow_control(0xc0000, 0x10000, (val & 2) && (dev->regs[0x14] & 0x20), (val & 2) && (dev->regs[0x14] & 0x20) && (val & 1));
|
||||
et6000_shadow_control(0xd0000, 0x10000, (val & 8) && (dev->regs[0x14] & 0x20), (val & 8) && (dev->regs[0x14] & 0x20) && (val & 4));
|
||||
et6000_shadow_control(0xe0000, 0x10000, val & 0x20, (val & 0x20) && (val & 0x10));
|
||||
et6000_shadow_control(0xf0000, 0x10000, val & 0x40, !(val & 0x40));
|
||||
break;
|
||||
}
|
||||
et6000_log("ET6000: dev->regs[%02x] = %02x\n", dev->index, dev->regs[dev->index]);
|
||||
break;
|
||||
}
|
||||
et6000_log("ET6000: dev->regs[%02x] = %02x\n", dev->index, dev->regs[dev->index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
et6000_read(uint16_t addr, void *priv)
|
||||
{
|
||||
et6000_t *dev = (et6000_t *)priv;
|
||||
et6000_t *dev = (et6000_t *) priv;
|
||||
|
||||
return ((addr == 0x23) && (INDEX >= 0) && (INDEX <= 5)) ? dev->regs[INDEX] : 0xff;
|
||||
}
|
||||
@@ -123,7 +121,7 @@ et6000_read(uint16_t addr, void *priv)
|
||||
static void
|
||||
et6000_close(void *priv)
|
||||
{
|
||||
et6000_t *dev = (et6000_t *)priv;
|
||||
et6000_t *dev = (et6000_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -131,7 +129,7 @@ et6000_close(void *priv)
|
||||
static void *
|
||||
et6000_init(const device_t *info)
|
||||
{
|
||||
et6000_t *dev = (et6000_t *)malloc(sizeof(et6000_t));
|
||||
et6000_t *dev = (et6000_t *) malloc(sizeof(et6000_t));
|
||||
memset(dev, 0, sizeof(et6000_t));
|
||||
|
||||
/* Port 92h */
|
||||
@@ -149,15 +147,15 @@ et6000_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t et6000_device = {
|
||||
.name = "ETEQ Cheetah ET6000",
|
||||
.name = "ETEQ Cheetah ET6000",
|
||||
.internal_name = "et6000",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = et6000_init,
|
||||
.close = et6000_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = et6000_init,
|
||||
.close = et6000_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -41,13 +41,11 @@
|
||||
#include <86box/io.h>
|
||||
#include <86box/video.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t reg[0x10];
|
||||
uint8_t reg[0x10];
|
||||
} gc100_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_GC100_LOG
|
||||
int gc100_do_log = ENABLE_GC100_LOG;
|
||||
|
||||
@@ -59,22 +57,21 @@ gc100_log(const char *fmt, ...)
|
||||
if (gc100_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define gc100_log(fmt, ...)
|
||||
# define gc100_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t
|
||||
get_fdd_switch_settings(void)
|
||||
{
|
||||
int i, fdd_count = 0;
|
||||
|
||||
for (i = 0; i < FDD_NUM; i++) {
|
||||
if (fdd_get_flags(i))
|
||||
fdd_count++;
|
||||
if (fdd_get_flags(i))
|
||||
fdd_count++;
|
||||
}
|
||||
|
||||
if (!fdd_count)
|
||||
@@ -83,71 +80,68 @@ get_fdd_switch_settings(void)
|
||||
return ((fdd_count - 1) << 6) | 0x01;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
get_videomode_switch_settings(void)
|
||||
{
|
||||
if (video_is_mda())
|
||||
return 0x30;
|
||||
return 0x30;
|
||||
else if (video_is_cga())
|
||||
return 0x20; /* 0x10 would be 40x25 */
|
||||
return 0x20; /* 0x10 would be 40x25 */
|
||||
else
|
||||
return 0x00;
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gc100_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
gc100_t *dev = (gc100_t *) priv;
|
||||
gc100_t *dev = (gc100_t *) priv;
|
||||
uint16_t addr = port & 0xf;
|
||||
|
||||
dev->reg[addr] = val;
|
||||
|
||||
switch (addr) {
|
||||
/* addr 0x2
|
||||
* bits 5-7: not used
|
||||
* bit 4: intenal memory wait states
|
||||
* bits 2-3: external memory wait states
|
||||
* bits 0-1: i/o access wait states
|
||||
*/
|
||||
case 2:
|
||||
break;
|
||||
/* addr 0x2
|
||||
* bits 5-7: not used
|
||||
* bit 4: intenal memory wait states
|
||||
* bits 2-3: external memory wait states
|
||||
* bits 0-1: i/o access wait states
|
||||
*/
|
||||
case 2:
|
||||
break;
|
||||
|
||||
/* addr 0x3
|
||||
* bits 1-7: not used
|
||||
* bit 0: turbo 0 xt 1
|
||||
*/
|
||||
case 3:
|
||||
if (val & 1)
|
||||
cpu_dynamic_switch(0);
|
||||
else
|
||||
cpu_dynamic_switch(cpu);
|
||||
break;
|
||||
/* addr 0x3
|
||||
* bits 1-7: not used
|
||||
* bit 0: turbo 0 xt 1
|
||||
*/
|
||||
case 3:
|
||||
if (val & 1)
|
||||
cpu_dynamic_switch(0);
|
||||
else
|
||||
cpu_dynamic_switch(cpu);
|
||||
break;
|
||||
|
||||
/* addr 0x5
|
||||
* programmable dip-switches
|
||||
* bits 6-7: floppy drive number
|
||||
* bits 4-5: video mode
|
||||
* bits 2-3: memory size
|
||||
* bit 1: fpu
|
||||
* bit 0: not used
|
||||
*/
|
||||
/* addr 0x5
|
||||
* programmable dip-switches
|
||||
* bits 6-7: floppy drive number
|
||||
* bits 4-5: video mode
|
||||
* bits 2-3: memory size
|
||||
* bit 1: fpu
|
||||
* bit 0: not used
|
||||
*/
|
||||
|
||||
/* addr 0x6 */
|
||||
/* addr 0x6 */
|
||||
|
||||
/* addr 0x7 */
|
||||
/* addr 0x7 */
|
||||
}
|
||||
|
||||
gc100_log("GC100: Write %02x at %02x\n", val, port);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
gc100_read(uint16_t port, void *priv)
|
||||
{
|
||||
gc100_t *dev = (gc100_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
gc100_t *dev = (gc100_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint16_t addr = port & 0xf;
|
||||
|
||||
ret = dev->reg[addr];
|
||||
@@ -155,47 +149,46 @@ gc100_read(uint16_t port, void *priv)
|
||||
gc100_log("GC100: Read %02x at %02x\n", ret, port);
|
||||
|
||||
switch (addr) {
|
||||
/* addr 0x2
|
||||
* bits 5-7: not used
|
||||
* bit 4: intenal memory wait states
|
||||
* bits 2-3: external memory wait states
|
||||
* bits 0-1: i/o access wait states
|
||||
*/
|
||||
case 0x2:
|
||||
break;
|
||||
/* addr 0x2
|
||||
* bits 5-7: not used
|
||||
* bit 4: intenal memory wait states
|
||||
* bits 2-3: external memory wait states
|
||||
* bits 0-1: i/o access wait states
|
||||
*/
|
||||
case 0x2:
|
||||
break;
|
||||
|
||||
/* addr 0x3
|
||||
* bits 1-7: not used
|
||||
* bit 0: turbo 0 xt 1
|
||||
*/
|
||||
case 0x3:
|
||||
break;
|
||||
/* addr 0x3
|
||||
* bits 1-7: not used
|
||||
* bit 0: turbo 0 xt 1
|
||||
*/
|
||||
case 0x3:
|
||||
break;
|
||||
|
||||
/* addr 0x5
|
||||
* programmable dip-switches
|
||||
* bits 6-7: floppy drive number
|
||||
* bits 4-5: video mode
|
||||
* bits 2-3: memory size
|
||||
* bit 1: fpu
|
||||
* bit 0: not used
|
||||
*/
|
||||
case 0x5:
|
||||
ret = ret & 0x0c;
|
||||
ret |= get_fdd_switch_settings();
|
||||
ret |= get_videomode_switch_settings();
|
||||
if (hasfpu)
|
||||
ret |= 0x02;
|
||||
break;
|
||||
/* addr 0x5
|
||||
* programmable dip-switches
|
||||
* bits 6-7: floppy drive number
|
||||
* bits 4-5: video mode
|
||||
* bits 2-3: memory size
|
||||
* bit 1: fpu
|
||||
* bit 0: not used
|
||||
*/
|
||||
case 0x5:
|
||||
ret = ret & 0x0c;
|
||||
ret |= get_fdd_switch_settings();
|
||||
ret |= get_videomode_switch_settings();
|
||||
if (hasfpu)
|
||||
ret |= 0x02;
|
||||
break;
|
||||
|
||||
/* addr 0x6 */
|
||||
/* addr 0x6 */
|
||||
|
||||
/* addr 0x7 */
|
||||
/* addr 0x7 */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gc100_close(void *priv)
|
||||
{
|
||||
@@ -204,7 +197,6 @@ gc100_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
gc100_init(const device_t *info)
|
||||
{
|
||||
@@ -218,11 +210,11 @@ gc100_init(const device_t *info)
|
||||
dev->reg[0x7] = 0x0;
|
||||
|
||||
if (info->local) {
|
||||
/* GC100A */
|
||||
/* GC100A */
|
||||
io_sethandler(0x0c2, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0c5, 0x03, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
|
||||
} else {
|
||||
/* GC100 */
|
||||
/* GC100 */
|
||||
io_sethandler(0x022, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
|
||||
io_sethandler(0x025, 0x01, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
|
||||
}
|
||||
@@ -231,29 +223,29 @@ gc100_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t gc100_device = {
|
||||
.name = "G2 GC100",
|
||||
.name = "G2 GC100",
|
||||
.internal_name = "gc100",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = gc100_init,
|
||||
.close = gc100_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = gc100_init,
|
||||
.close = gc100_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t gc100a_device = {
|
||||
.name = "G2 GC100A",
|
||||
.name = "G2 GC100A",
|
||||
.internal_name = "gc100a",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = gc100_init,
|
||||
.close = gc100_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = gc100_init,
|
||||
.close = gc100_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,6 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
/*
|
||||
IMS 884x Configuration Registers
|
||||
|
||||
@@ -42,158 +41,152 @@
|
||||
By: Tiseno100, Miran Grca(OBattler)
|
||||
|
||||
Register 00h:
|
||||
Bit 3: F0000-FFFFF Shadow Enable
|
||||
Bit 2: E0000-EFFFF Shadow Enable
|
||||
Bit 0: ????
|
||||
Bit 3: F0000-FFFFF Shadow Enable
|
||||
Bit 2: E0000-EFFFF Shadow Enable
|
||||
Bit 0: ????
|
||||
|
||||
Register 04h:
|
||||
Bit 3: Cache Write Hit Wait State
|
||||
Bit 2: Cache Read Hit Wait State
|
||||
Bit 3: Cache Write Hit Wait State
|
||||
Bit 2: Cache Read Hit Wait State
|
||||
|
||||
Register 06h:
|
||||
Bit 3: System BIOS Cacheable (1: Yes / 0: No)
|
||||
Bit 1: Power Management Mode (1: IRQ / 0: SMI#)
|
||||
Bit 3: System BIOS Cacheable (1: Yes / 0: No)
|
||||
Bit 1: Power Management Mode (1: IRQ / 0: SMI#)
|
||||
|
||||
Register 08h:
|
||||
Bit 2: System BIOS Shadow Write (1: Enable / 0: Disable)
|
||||
Bit 1: System BIOS Shadow Read?
|
||||
Bit 2: System BIOS Shadow Write (1: Enable / 0: Disable)
|
||||
Bit 1: System BIOS Shadow Read?
|
||||
|
||||
Register 0Dh:
|
||||
Bit 0: IO 100H-3FFH Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 0: IO 100H-3FFH Idle Detect (1: Enable / 0: Disable)
|
||||
|
||||
Register 0Eh:
|
||||
Bit 7: DMA & Local Bus Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 6: Floppy Disk Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 5: IDE Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 4: Serial Port Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 3: Parallel Port Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 2: Keyboard Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 1: Video Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 7: DMA & Local Bus Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 6: Floppy Disk Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 5: IDE Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 4: Serial Port Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 3: Parallel Port Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 2: Keyboard Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 1: Video Idle Detect (1: Enable / 0: Disable)
|
||||
|
||||
Register 12h:
|
||||
Bits 3-2: Power Saving Timer (00 = 1 MIN, 01 = 3 MIN, 10 = 5 MIN, 11 = 8 MIN)
|
||||
Bit 1: Base Memory (1: 512KB / 0: 640KB)
|
||||
Bits 3-2: Power Saving Timer (00 = 1 MIN, 01 = 3 MIN, 10 = 5 MIN, 11 = 8 MIN)
|
||||
Bit 1: Base Memory (1: 512KB / 0: 640KB)
|
||||
|
||||
Register 1Ah:
|
||||
Bit 3: Cache Write Hit W/S For PCI (1: Enabled / 0: Disable)
|
||||
Bit 2: Cache Read Hit W/S For PCI (1: Enabled / 0: Disable)
|
||||
Bit 1: VESA Clock Skew (1: 4ns/6ns, 0: No Delay/2ns)
|
||||
Bit 3: Cache Write Hit W/S For PCI (1: Enabled / 0: Disable)
|
||||
Bit 2: Cache Read Hit W/S For PCI (1: Enabled / 0: Disable)
|
||||
Bit 1: VESA Clock Skew (1: 4ns/6ns, 0: No Delay/2ns)
|
||||
|
||||
Register 1Bh:
|
||||
Bit 6: Enable SMRAM (always at 30000-4FFFF) in SMM
|
||||
Bit 5: ????
|
||||
Bit 4: Software SMI#
|
||||
Bit 3: DC000-DFFFF Shadow Enable
|
||||
Bit 2: D8000-DBFFF Shadow Enable
|
||||
Bit 1: D4000-D7FFF Shadow Enable
|
||||
Bit 0: D0000-D3FFF Shadow Enable
|
||||
Bit 6: Enable SMRAM (always at 30000-4FFFF) in SMM
|
||||
Bit 5: ????
|
||||
Bit 4: Software SMI#
|
||||
Bit 3: DC000-DFFFF Shadow Enable
|
||||
Bit 2: D8000-DBFFF Shadow Enable
|
||||
Bit 1: D4000-D7FFF Shadow Enable
|
||||
Bit 0: D0000-D3FFF Shadow Enable
|
||||
|
||||
Register 1Ch:
|
||||
Bits 7-4: INTA IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bit 3: CC000-CFFFF Shadow Enable
|
||||
Bit 2: C8000-CBFFF Shadow Enable
|
||||
Bit 1: C4000-C7FFF Shadow Enable
|
||||
Bit 0: C0000-C3FFF Shadow Enable
|
||||
Bits 7-4: INTA IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bit 3: CC000-CFFFF Shadow Enable
|
||||
Bit 2: C8000-CBFFF Shadow Enable
|
||||
Bit 1: C4000-C7FFF Shadow Enable
|
||||
Bit 0: C0000-C3FFF Shadow Enable
|
||||
|
||||
Register 1Dh:
|
||||
Bits 7-4: INTB IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bits 7-4: INTB IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
|
||||
Register 1Eh:
|
||||
Bits 7-4: INTC IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bit 1: C4000-C7FFF Cacheable
|
||||
Bit 0: C0000-C3FFF Cacheable
|
||||
Bits 7-4: INTC IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bit 1: C4000-C7FFF Cacheable
|
||||
Bit 0: C0000-C3FFF Cacheable
|
||||
|
||||
Register 21h:
|
||||
Bits 7-4: INTD IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bits 7-4: INTD IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
|
||||
Register 22h:
|
||||
Bit 5: Local Bus Master #2 select (0 = VESA, 1 = PCI)
|
||||
Bit 4: Local Bus Master #1 select (0 = VESA, 1 = PCI)
|
||||
Bits 1-0: Internal HADS# Delay Always (00 = No Delay, 01 = 1 Clk, 10 = 2 Clks)
|
||||
Bit 5: Local Bus Master #2 select (0 = VESA, 1 = PCI)
|
||||
Bit 4: Local Bus Master #1 select (0 = VESA, 1 = PCI)
|
||||
Bits 1-0: Internal HADS# Delay Always (00 = No Delay, 01 = 1 Clk, 10 = 2 Clks)
|
||||
|
||||
Register 23h:
|
||||
Bit 7: Seven Bits Tag (1: Enabled / 0: Disable)
|
||||
Bit 3: Extend LBRDY#(VL Master) (1: Enabled / 0: Disable)
|
||||
Bit 2: Sync LRDY#(VL Slave) (1: Enabled / 0: Disable)
|
||||
Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable)
|
||||
Bit 7: Seven Bits Tag (1: Enabled / 0: Disable)
|
||||
Bit 3: Extend LBRDY#(VL Master) (1: Enabled / 0: Disable)
|
||||
Bit 2: Sync LRDY#(VL Slave) (1: Enabled / 0: Disable)
|
||||
Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable)
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx, access_data,
|
||||
regs[256], pci_conf[256];
|
||||
uint8_t idx, access_data,
|
||||
regs[256], pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
smram_t *smram;
|
||||
} ims8848_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_IMS8848_LOG
|
||||
int ims8848_do_log = ENABLE_IMS8848_LOG;
|
||||
|
||||
|
||||
static void
|
||||
ims8848_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ims8848_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ims8848_log(fmt, ...)
|
||||
# define ims8848_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Shadow write always enabled, 1B and 1C control C000-DFFF read. */
|
||||
static void
|
||||
ims8848_recalc(ims8848_t *dev)
|
||||
{
|
||||
int i, state_on;
|
||||
int i, state_on;
|
||||
uint32_t base;
|
||||
ims8848_log("SHADOW: 00 = %02X, 08 = %02X, 1B = %02X, 1C = %02X\n",
|
||||
dev->regs[0x00], dev->regs[0x08], dev->regs[0x1b], dev->regs[0x1c]);
|
||||
dev->regs[0x00], dev->regs[0x08], dev->regs[0x1b], dev->regs[0x1c]);
|
||||
|
||||
state_on = MEM_READ_INTERNAL;
|
||||
state_on |= (dev->regs[0x08] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
base = 0xe0000 + (i << 16);
|
||||
if (dev->regs[0x00] & (1 << (i + 2)))
|
||||
mem_set_mem_state_both(base, 0x10000, state_on);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
base = 0xe0000 + (i << 16);
|
||||
if (dev->regs[0x00] & (1 << (i + 2)))
|
||||
mem_set_mem_state_both(base, 0x10000, state_on);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (dev->regs[0x1c] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (dev->regs[0x1c] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (dev->regs[0x1b] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (dev->regs[0x1b] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_base_memory(ims8848_t *dev)
|
||||
{
|
||||
/* We can use the proper mem_set_access to handle that. */
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x12] & 2) ?
|
||||
(MEM_READ_DISABLED | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x12] & 2) ? (MEM_READ_DISABLED | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_smram(ims8848_t *dev)
|
||||
{
|
||||
@@ -202,137 +195,137 @@ ims8848_smram(ims8848_t *dev)
|
||||
smram_enable(dev->smram, 0x00030000, 0x00030000, 0x20000, dev->regs[0x1b] & 0x40, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
uint8_t old = dev->regs[dev->idx];
|
||||
uint8_t old = dev->regs[dev->idx];
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
ims8848_log("[W] IDX = %02X\n", val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x23:
|
||||
ims8848_log("[W] IDX IN = %02X\n", val);
|
||||
if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
|
||||
dev->access_data = 1;
|
||||
break;
|
||||
case 0x24:
|
||||
ims8848_log("[W] [%i] REG %02X = %02X\n", dev->access_data, dev->idx, val);
|
||||
if (dev->access_data) {
|
||||
dev->regs[dev->idx] = val;
|
||||
switch (dev->idx) {
|
||||
case 0x00: case 0x08: case 0x1b: case 0x1c:
|
||||
/* Shadow RAM */
|
||||
ims8848_recalc(dev);
|
||||
if (dev->idx == 0x1b) {
|
||||
ims8848_smram(dev);
|
||||
if (!(old & 0x10) && (val & 0x10))
|
||||
smi_raise();
|
||||
} else if (dev->idx == 0x1c)
|
||||
pci_set_irq_routing(PCI_INTA, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x22:
|
||||
ims8848_log("[W] IDX = %02X\n", val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x23:
|
||||
ims8848_log("[W] IDX IN = %02X\n", val);
|
||||
if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
|
||||
dev->access_data = 1;
|
||||
break;
|
||||
case 0x24:
|
||||
ims8848_log("[W] [%i] REG %02X = %02X\n", dev->access_data, dev->idx, val);
|
||||
if (dev->access_data) {
|
||||
dev->regs[dev->idx] = val;
|
||||
switch (dev->idx) {
|
||||
case 0x00:
|
||||
case 0x08:
|
||||
case 0x1b:
|
||||
case 0x1c:
|
||||
/* Shadow RAM */
|
||||
ims8848_recalc(dev);
|
||||
if (dev->idx == 0x1b) {
|
||||
ims8848_smram(dev);
|
||||
if (!(old & 0x10) && (val & 0x10))
|
||||
smi_raise();
|
||||
} else if (dev->idx == 0x1c)
|
||||
pci_set_irq_routing(PCI_INTA, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x1d: case 0x1e:
|
||||
pci_set_irq_routing(PCI_INTB + (dev->idx - 0x1d), (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x21:
|
||||
pci_set_irq_routing(PCI_INTD, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x1d:
|
||||
case 0x1e:
|
||||
pci_set_irq_routing(PCI_INTB + (dev->idx - 0x1d), (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x21:
|
||||
pci_set_irq_routing(PCI_INTD, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
/* Base Memory */
|
||||
ims8848_base_memory(dev);
|
||||
break;
|
||||
}
|
||||
dev->access_data = 0;
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
/* Base Memory */
|
||||
ims8848_base_memory(dev);
|
||||
break;
|
||||
}
|
||||
dev->access_data = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ims8848_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
#ifdef ENABLE_IMS8848_LOG
|
||||
uint8_t old_ad = dev->access_data;
|
||||
#endif
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
ims8848_log("[R] IDX = %02X\n", ret);
|
||||
ret = dev->idx;
|
||||
break;
|
||||
case 0x23:
|
||||
ims8848_log("[R] IDX IN = %02X\n", ret);
|
||||
ret = (dev->idx >> 4) | (dev->idx << 4);
|
||||
break;
|
||||
case 0x24:
|
||||
if (dev->access_data) {
|
||||
ret = dev->regs[dev->idx];
|
||||
dev->access_data = 0;
|
||||
}
|
||||
ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret);
|
||||
break;
|
||||
case 0x22:
|
||||
ims8848_log("[R] IDX = %02X\n", ret);
|
||||
ret = dev->idx;
|
||||
break;
|
||||
case 0x23:
|
||||
ims8848_log("[R] IDX IN = %02X\n", ret);
|
||||
ret = (dev->idx >> 4) | (dev->idx << 4);
|
||||
break;
|
||||
case 0x24:
|
||||
if (dev->access_data) {
|
||||
ret = dev->regs[dev->idx];
|
||||
dev->access_data = 0;
|
||||
}
|
||||
ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8849_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *)priv;
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
|
||||
ims8848_log("IMS 884x-PCI: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80));
|
||||
|
||||
if (func == 0) switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
if (func == 0)
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 3;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 3;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= val & 0xf7;
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x0c ... 0x0d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x0c ... 0x0d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52 ... 0x55:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
case 0x52 ... 0x55:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ims8849_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->pci_conf[addr];
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_reset(void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *)priv;
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
@@ -347,7 +340,7 @@ ims8848_reset(void *priv)
|
||||
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
|
||||
ims8848_recalc(dev); /* Shadow RAM Setup */
|
||||
ims8848_recalc(dev); /* Shadow RAM Setup */
|
||||
ims8848_base_memory(dev); /* Base Memory Setup */
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
@@ -358,7 +351,6 @@ ims8848_reset(void *priv)
|
||||
ims8848_smram(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_close(void *priv)
|
||||
{
|
||||
@@ -369,7 +361,6 @@ ims8848_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ims8848_init(const device_t *info)
|
||||
{
|
||||
@@ -379,12 +370,12 @@ ims8848_init(const device_t *info)
|
||||
device_add(&port_92_device);
|
||||
|
||||
/* IMS 8848:
|
||||
22h Index
|
||||
23h Data Unlock
|
||||
24h Data
|
||||
22h Index
|
||||
23h Data Unlock
|
||||
24h Data
|
||||
|
||||
IMS 8849:
|
||||
PCI Device 0: IMS 8849 Dummy for compatibility reasons
|
||||
PCI Device 0: IMS 8849 Dummy for compatibility reasons
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
|
||||
@@ -401,15 +392,15 @@ ims8848_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t ims8848_device = {
|
||||
.name = "IMS 8848/8849",
|
||||
.name = "IMS 8848/8849",
|
||||
.internal_name = "ims8848",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ims8848_init,
|
||||
.close = ims8848_close,
|
||||
.reset = ims8848_reset,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ims8848_init,
|
||||
.close = ims8848_close,
|
||||
.reset = ims8848_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -36,72 +36,66 @@
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
|
||||
#define MEM_STATE_SHADOW_R 0x01
|
||||
#define MEM_STATE_SHADOW_W 0x02
|
||||
#define MEM_STATE_SMRAM 0x04
|
||||
|
||||
#define MEM_STATE_SHADOW_R 0x01
|
||||
#define MEM_STATE_SHADOW_W 0x02
|
||||
#define MEM_STATE_SMRAM 0x04
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t has_ide, smram_locked,
|
||||
regs[256];
|
||||
uint8_t has_ide, smram_locked,
|
||||
regs[256];
|
||||
|
||||
uint16_t timer_base,
|
||||
timer_latch;
|
||||
uint16_t timer_base,
|
||||
timer_latch;
|
||||
|
||||
smram_t *smram;
|
||||
smram_t *smram;
|
||||
|
||||
double fast_off_period;
|
||||
double fast_off_period;
|
||||
|
||||
pc_timer_t timer, fast_off_timer;
|
||||
pc_timer_t timer, fast_off_timer;
|
||||
|
||||
apm_t * apm;
|
||||
port_92_t * port_92;
|
||||
apm_t *apm;
|
||||
port_92_t *port_92;
|
||||
} i420ex_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_I420EX_LOG
|
||||
int i420ex_do_log = ENABLE_I420EX_LOG;
|
||||
|
||||
|
||||
static void
|
||||
i420ex_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (i420ex_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define i420ex_log(fmt, ...)
|
||||
# define i420ex_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
i420ex_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_smram_handler_phase0(void)
|
||||
{
|
||||
@@ -109,7 +103,6 @@ i420ex_smram_handler_phase0(void)
|
||||
smram_disable_all();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_smram_handler_phase1(i420ex_t *dev)
|
||||
{
|
||||
@@ -119,244 +112,252 @@ i420ex_smram_handler_phase1(i420ex_t *dev)
|
||||
uint32_t size = 0x00010000;
|
||||
|
||||
switch (regs[0x70] & 0x07) {
|
||||
case 0: case 1:
|
||||
default:
|
||||
host_base = ram_base = 0x00000000;
|
||||
size = 0x00000000;
|
||||
break;
|
||||
case 2:
|
||||
host_base = 0x000a0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 3:
|
||||
host_base = 0x000b0000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 4:
|
||||
host_base = 0x000c0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 5:
|
||||
host_base = 0x000d0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 6:
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 7:
|
||||
host_base = 0x000f0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
host_base = ram_base = 0x00000000;
|
||||
size = 0x00000000;
|
||||
break;
|
||||
case 2:
|
||||
host_base = 0x000a0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 3:
|
||||
host_base = 0x000b0000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 4:
|
||||
host_base = 0x000c0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 5:
|
||||
host_base = 0x000d0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 6:
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 7:
|
||||
host_base = 0x000f0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
}
|
||||
|
||||
smram_enable(dev->smram, host_base, ram_base, size,
|
||||
(regs[0x70] & 0x70) == 0x40, !(regs[0x70] & 0x20));
|
||||
(regs[0x70] & 0x70) == 0x40, !(regs[0x70] & 0x20));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *) priv;
|
||||
|
||||
if (func > 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40))
|
||||
return;
|
||||
return;
|
||||
|
||||
switch (addr) {
|
||||
case 0x05:
|
||||
dev->regs[addr] = (val & 0x01);
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[addr] = (val & 0x01);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->regs[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x44:
|
||||
dev->regs[addr] = (val & 0x07);
|
||||
break;
|
||||
case 0x48:
|
||||
dev->regs[addr] = (val & 0x3f);
|
||||
if (dev->has_ide) {
|
||||
ide_pri_disable();
|
||||
switch (val & 0x03) {
|
||||
case 0x01:
|
||||
ide_set_base(0, 0x01f0);
|
||||
ide_set_side(0, 0x03f6);
|
||||
ide_pri_enable();
|
||||
break;
|
||||
case 0x02:
|
||||
ide_set_base(0, 0x0170);
|
||||
ide_set_side(0, 0x0376);
|
||||
ide_pri_enable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x49: case 0x53:
|
||||
dev->regs[addr] = (val & 0x1f);
|
||||
break;
|
||||
case 0x4c: case 0x51:
|
||||
case 0x57:
|
||||
case 0x68: case 0x69:
|
||||
dev->regs[addr] = val;
|
||||
if (addr == 0x4c) {
|
||||
dma_alias_remove();
|
||||
if (!(val & 0x80))
|
||||
dma_alias_set();
|
||||
}
|
||||
break;
|
||||
case 0x4d:
|
||||
dev->regs[addr] = (dev->regs[addr] & 0xef) | (val & 0x10);
|
||||
break;
|
||||
case 0x4e:
|
||||
dev->regs[addr] = (val & 0xf7);
|
||||
break;
|
||||
case 0x50:
|
||||
dev->regs[addr] = (val & 0x0f);
|
||||
break;
|
||||
case 0x52:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x56:
|
||||
dev->regs[addr] = (val & 0x3e);
|
||||
break;
|
||||
case 0x59: /* PAM0 */
|
||||
if ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i420ex_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
dev->regs[0x59] = val & 0xf0;
|
||||
break;
|
||||
case 0x5a: /* PAM1 */
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i420ex_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i420ex_map(0xc4000, 0x04000, val >> 4);
|
||||
dev->regs[0x5a] = val;
|
||||
break;
|
||||
case 0x5b: /*PAM2 */
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i420ex_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i420ex_map(0xcc000, 0x04000, val >> 4);
|
||||
dev->regs[0x5b] = val;
|
||||
break;
|
||||
case 0x5c: /*PAM3 */
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i420ex_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i420ex_map(0xd4000, 0x04000, val >> 4);
|
||||
dev->regs[0x5c] = val;
|
||||
break;
|
||||
case 0x5d: /* PAM4 */
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i420ex_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i420ex_map(0xdc000, 0x04000, val >> 4);
|
||||
dev->regs[0x5d] = val;
|
||||
break;
|
||||
case 0x5e: /* PAM5 */
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i420ex_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i420ex_map(0xe4000, 0x04000, val >> 4);
|
||||
dev->regs[0x5e] = val;
|
||||
break;
|
||||
case 0x5f: /* PAM6 */
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i420ex_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i420ex_map(0xec000, 0x04000, val >> 4);
|
||||
dev->regs[0x5f] = val;
|
||||
break;
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64:
|
||||
spd_write_drbs(dev->regs, 0x60, 0x64, 1);
|
||||
break;
|
||||
case 0x66: case 0x67:
|
||||
i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val);
|
||||
dev->regs[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x01), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x01), val & 0xf);
|
||||
break;
|
||||
case 0x70: /* SMRAM */
|
||||
i420ex_smram_handler_phase0();
|
||||
if (dev->smram_locked)
|
||||
dev->regs[0x70] = (dev->regs[0x70] & 0xdf) | (val & 0x20);
|
||||
else {
|
||||
dev->regs[0x70] = (dev->regs[0x70] & 0x88) | (val & 0x77);
|
||||
dev->smram_locked = (val & 0x10);
|
||||
if (dev->smram_locked)
|
||||
dev->regs[0x70] &= 0xbf;
|
||||
}
|
||||
i420ex_smram_handler_phase1(dev);
|
||||
break;
|
||||
case 0xa0:
|
||||
dev->regs[addr] = val & 0x1f;
|
||||
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80));
|
||||
switch ((val & 0x18) >> 3) {
|
||||
case 0x00:
|
||||
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
|
||||
break;
|
||||
case 0x01:
|
||||
default:
|
||||
dev->fast_off_period = 0.0;
|
||||
break;
|
||||
case 0x02:
|
||||
dev->fast_off_period = PCICLK;
|
||||
break;
|
||||
case 0x03:
|
||||
dev->fast_off_period = PCICLK * 32768.0;
|
||||
break;
|
||||
}
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
break;
|
||||
case 0xa2:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80));
|
||||
break;
|
||||
case 0xaa:
|
||||
dev->regs[addr] &= (val & 0xff);
|
||||
break;
|
||||
case 0xac: case 0xae:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
break;
|
||||
case 0xa4:
|
||||
dev->regs[addr] = val & 0xfb;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr];
|
||||
break;
|
||||
case 0xa5:
|
||||
dev->regs[addr] = val;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8);
|
||||
break;
|
||||
case 0xa7:
|
||||
dev->regs[addr] = val & 0xe0;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24);
|
||||
break;
|
||||
case 0xa8:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
cpu_fast_off_val = val;
|
||||
cpu_fast_off_count = val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
break;
|
||||
case 0x40:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x44:
|
||||
dev->regs[addr] = (val & 0x07);
|
||||
break;
|
||||
case 0x48:
|
||||
dev->regs[addr] = (val & 0x3f);
|
||||
if (dev->has_ide) {
|
||||
ide_pri_disable();
|
||||
switch (val & 0x03) {
|
||||
case 0x01:
|
||||
ide_set_base(0, 0x01f0);
|
||||
ide_set_side(0, 0x03f6);
|
||||
ide_pri_enable();
|
||||
break;
|
||||
case 0x02:
|
||||
ide_set_base(0, 0x0170);
|
||||
ide_set_side(0, 0x0376);
|
||||
ide_pri_enable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x49:
|
||||
case 0x53:
|
||||
dev->regs[addr] = (val & 0x1f);
|
||||
break;
|
||||
case 0x4c:
|
||||
case 0x51:
|
||||
case 0x57:
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
dev->regs[addr] = val;
|
||||
if (addr == 0x4c) {
|
||||
dma_alias_remove();
|
||||
if (!(val & 0x80))
|
||||
dma_alias_set();
|
||||
}
|
||||
break;
|
||||
case 0x4d:
|
||||
dev->regs[addr] = (dev->regs[addr] & 0xef) | (val & 0x10);
|
||||
break;
|
||||
case 0x4e:
|
||||
dev->regs[addr] = (val & 0xf7);
|
||||
break;
|
||||
case 0x50:
|
||||
dev->regs[addr] = (val & 0x0f);
|
||||
break;
|
||||
case 0x52:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x56:
|
||||
dev->regs[addr] = (val & 0x3e);
|
||||
break;
|
||||
case 0x59: /* PAM0 */
|
||||
if ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i420ex_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
dev->regs[0x59] = val & 0xf0;
|
||||
break;
|
||||
case 0x5a: /* PAM1 */
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i420ex_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i420ex_map(0xc4000, 0x04000, val >> 4);
|
||||
dev->regs[0x5a] = val;
|
||||
break;
|
||||
case 0x5b: /*PAM2 */
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i420ex_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i420ex_map(0xcc000, 0x04000, val >> 4);
|
||||
dev->regs[0x5b] = val;
|
||||
break;
|
||||
case 0x5c: /*PAM3 */
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i420ex_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i420ex_map(0xd4000, 0x04000, val >> 4);
|
||||
dev->regs[0x5c] = val;
|
||||
break;
|
||||
case 0x5d: /* PAM4 */
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i420ex_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i420ex_map(0xdc000, 0x04000, val >> 4);
|
||||
dev->regs[0x5d] = val;
|
||||
break;
|
||||
case 0x5e: /* PAM5 */
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i420ex_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i420ex_map(0xe4000, 0x04000, val >> 4);
|
||||
dev->regs[0x5e] = val;
|
||||
break;
|
||||
case 0x5f: /* PAM6 */
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i420ex_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i420ex_map(0xec000, 0x04000, val >> 4);
|
||||
dev->regs[0x5f] = val;
|
||||
break;
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
spd_write_drbs(dev->regs, 0x60, 0x64, 1);
|
||||
break;
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val);
|
||||
dev->regs[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x01), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x01), val & 0xf);
|
||||
break;
|
||||
case 0x70: /* SMRAM */
|
||||
i420ex_smram_handler_phase0();
|
||||
if (dev->smram_locked)
|
||||
dev->regs[0x70] = (dev->regs[0x70] & 0xdf) | (val & 0x20);
|
||||
else {
|
||||
dev->regs[0x70] = (dev->regs[0x70] & 0x88) | (val & 0x77);
|
||||
dev->smram_locked = (val & 0x10);
|
||||
if (dev->smram_locked)
|
||||
dev->regs[0x70] &= 0xbf;
|
||||
}
|
||||
i420ex_smram_handler_phase1(dev);
|
||||
break;
|
||||
case 0xa0:
|
||||
dev->regs[addr] = val & 0x1f;
|
||||
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80));
|
||||
switch ((val & 0x18) >> 3) {
|
||||
case 0x00:
|
||||
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
|
||||
break;
|
||||
case 0x01:
|
||||
default:
|
||||
dev->fast_off_period = 0.0;
|
||||
break;
|
||||
case 0x02:
|
||||
dev->fast_off_period = PCICLK;
|
||||
break;
|
||||
case 0x03:
|
||||
dev->fast_off_period = PCICLK * 32768.0;
|
||||
break;
|
||||
}
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
break;
|
||||
case 0xa2:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80));
|
||||
break;
|
||||
case 0xaa:
|
||||
dev->regs[addr] &= (val & 0xff);
|
||||
break;
|
||||
case 0xac:
|
||||
case 0xae:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
break;
|
||||
case 0xa4:
|
||||
dev->regs[addr] = val & 0xfb;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr];
|
||||
break;
|
||||
case 0xa5:
|
||||
dev->regs[addr] = val;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8);
|
||||
break;
|
||||
case 0xa7:
|
||||
dev->regs[addr] = val & 0xe0;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24);
|
||||
break;
|
||||
case 0xa8:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
cpu_fast_off_val = val;
|
||||
cpu_fast_off_count = val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
i420ex_read(int func, int addr, void *priv)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *) priv;
|
||||
uint8_t ret;
|
||||
uint8_t ret;
|
||||
|
||||
ret = 0xff;
|
||||
|
||||
@@ -366,7 +367,6 @@ i420ex_read(int func, int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_reset_hard(void *priv)
|
||||
{
|
||||
@@ -374,8 +374,10 @@ i420ex_reset_hard(void *priv)
|
||||
|
||||
memset(dev->regs, 0, 256);
|
||||
|
||||
dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/
|
||||
dev->regs[0x02] = 0x86; dev->regs[0x03] = 0x04; /*82378IB (I420EX)*/
|
||||
dev->regs[0x00] = 0x86;
|
||||
dev->regs[0x01] = 0x80; /*Intel*/
|
||||
dev->regs[0x02] = 0x86;
|
||||
dev->regs[0x03] = 0x04; /*82378IB (I420EX)*/
|
||||
dev->regs[0x04] = 0x07;
|
||||
dev->regs[0x07] = 0x02;
|
||||
|
||||
@@ -383,13 +385,14 @@ i420ex_reset_hard(void *priv)
|
||||
dev->regs[0x4e] = 0x03;
|
||||
/* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */
|
||||
if (cpu_busspeed >= 33333333)
|
||||
dev->regs[0x50] |= 0x02;
|
||||
dev->regs[0x50] |= 0x02;
|
||||
dev->regs[0x51] = 0x80;
|
||||
dev->regs[0x60] = dev->regs[0x61] = dev->regs[0x62] = dev->regs[0x63] = dev->regs[0x64] = 0x01;
|
||||
dev->regs[0x66] = 0x80; dev->regs[0x67] = 0x80;
|
||||
dev->regs[0x69] = 0x02;
|
||||
dev->regs[0xa0] = 0x08;
|
||||
dev->regs[0xa8] = 0x0f;
|
||||
dev->regs[0x66] = 0x80;
|
||||
dev->regs[0x67] = 0x80;
|
||||
dev->regs[0x69] = 0x02;
|
||||
dev->regs[0xa0] = 0x08;
|
||||
dev->regs[0xa8] = 0x0f;
|
||||
|
||||
mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
@@ -398,20 +401,18 @@ i420ex_reset_hard(void *priv)
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
|
||||
if (dev->has_ide)
|
||||
ide_pri_disable();
|
||||
ide_pri_disable();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_apm_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *) p;
|
||||
|
||||
if (dev->apm->do_smi)
|
||||
dev->regs[0xaa] |= 0x80;
|
||||
dev->regs[0xaa] |= 0x80;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_fast_off_count(void *priv)
|
||||
{
|
||||
@@ -423,22 +424,21 @@ i420ex_fast_off_count(void *priv)
|
||||
dev->regs[0xaa] |= 0x20;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_reset(void *p)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *) p;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
i420ex_write(0, 0x48, 0x00, p);
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
i420ex_write(0, 0x59 + i, 0x00, p);
|
||||
i420ex_write(0, 0x59 + i, 0x00, p);
|
||||
|
||||
for (i = 0; i <= 4; i++)
|
||||
i420ex_write(0, 0x60 + i, 0x01, p);
|
||||
i420ex_write(0, 0x60 + i, 0x01, p);
|
||||
|
||||
dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */
|
||||
dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */
|
||||
dev->smram_locked = 0;
|
||||
i420ex_write(0, 0x70, 0x00, p);
|
||||
|
||||
@@ -454,38 +454,35 @@ i420ex_reset(void *p)
|
||||
i420ex_write(0, 0xa8, 0x0f, p);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_close(void *p)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *)p;
|
||||
i420ex_t *dev = (i420ex_t *) p;
|
||||
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_speed_changed(void *priv)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *) priv;
|
||||
int te;
|
||||
int te;
|
||||
|
||||
te = timer_is_enabled(&dev->timer);
|
||||
|
||||
timer_disable(&dev->timer);
|
||||
if (te)
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
|
||||
te = timer_is_enabled(&dev->fast_off_timer);
|
||||
|
||||
timer_stop(&dev->fast_off_timer);
|
||||
if (te)
|
||||
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
|
||||
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
i420ex_init(const device_t *info)
|
||||
{
|
||||
@@ -502,7 +499,7 @@ i420ex_init(const device_t *info)
|
||||
|
||||
cpu_fast_off_flags = 0x00000000;
|
||||
|
||||
cpu_fast_off_val = dev->regs[0xa8];
|
||||
cpu_fast_off_val = dev->regs[0xa8];
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
|
||||
cpu_register_fast_off_handler(&dev->fast_off_timer);
|
||||
@@ -523,29 +520,29 @@ i420ex_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t i420ex_device = {
|
||||
.name = "Intel 82420EX",
|
||||
.name = "Intel 82420EX",
|
||||
.internal_name = "i420ex",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = i420ex_init,
|
||||
.close = i420ex_close,
|
||||
.reset = i420ex_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = i420ex_init,
|
||||
.close = i420ex_close,
|
||||
.reset = i420ex_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = i420ex_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t i420ex_ide_device = {
|
||||
.name = "Intel 82420EX (With IDE)",
|
||||
.name = "Intel 82420EX (With IDE)",
|
||||
.internal_name = "i420ex_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x01,
|
||||
.init = i420ex_init,
|
||||
.close = i420ex_close,
|
||||
.reset = i420ex_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x01,
|
||||
.init = i420ex_init,
|
||||
.close = i420ex_close,
|
||||
.reset = i420ex_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = i420ex_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,19 +29,19 @@
|
||||
|
||||
/* Shadow capabilities */
|
||||
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
#define ENABLED_SHADOW ((LOCK_STATUS) ? RO_SHADOW : RW_SHADOW)
|
||||
#define RW_SHADOW (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)
|
||||
#define RO_SHADOW (MEM_READ_INTERNAL | MEM_WRITE_DISABLED)
|
||||
#define ENABLED_SHADOW ((LOCK_STATUS) ? RO_SHADOW : RW_SHADOW)
|
||||
#define RW_SHADOW (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)
|
||||
#define RO_SHADOW (MEM_READ_INTERNAL | MEM_WRITE_DISABLED)
|
||||
|
||||
/* Granularity Register Enable & Recalc */
|
||||
#define EXTENDED_GRANULARITY_ENABLED (dev->regs[0x2c] & 0x01)
|
||||
#define GRANULARITY_RECALC ((dev->regs[0x2e] & (1 << (i + 8))) ? ((dev->regs[0x2e] & (1 << i)) ? RO_SHADOW : RW_SHADOW) : DISABLED_SHADOW)
|
||||
#define GRANULARITY_RECALC ((dev->regs[0x2e] & (1 << (i + 8))) ? ((dev->regs[0x2e] & (1 << i)) ? RO_SHADOW : RW_SHADOW) : DISABLED_SHADOW)
|
||||
|
||||
/* R/W operator for the Video RAM region */
|
||||
#define DETERMINE_VIDEO_RAM_WRITE_ACCESS ((dev->regs[0x22] & (0x08 << 8)) ? RW_SHADOW : RO_SHADOW)
|
||||
|
||||
/* Base System 512/640KB switch */
|
||||
#define ENABLE_TOP_128KB (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)
|
||||
#define ENABLE_TOP_128KB (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)
|
||||
#define DISABLE_TOP_128KB (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
|
||||
/* ROM size determination */
|
||||
@@ -70,75 +70,69 @@ intel_82335_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (intel_82335_do_log)
|
||||
{
|
||||
if (intel_82335_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define intel_82335_log(fmt, ...)
|
||||
# define intel_82335_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
intel_82335_write(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
intel_82335_t *dev = (intel_82335_t *)priv;
|
||||
uint32_t romsize = 0, base = 0, i = 0, rc1_remap = 0, rc2_remap = 0;
|
||||
intel_82335_t *dev = (intel_82335_t *) priv;
|
||||
uint32_t romsize = 0, base = 0, i = 0, rc1_remap = 0, rc2_remap = 0;
|
||||
|
||||
dev->regs[addr] = val;
|
||||
|
||||
if (!dev->cfg_locked)
|
||||
{
|
||||
if (!dev->cfg_locked) {
|
||||
|
||||
intel_82335_log("Register %02x: Write %04x\n", addr, val);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22: /* Memory Controller */
|
||||
switch (addr) {
|
||||
case 0x22: /* Memory Controller */
|
||||
|
||||
/* Check if the ROM chips are 256 or 512Kbit (Just for Shadowing sanity) */
|
||||
romsize = ROM_SIZE;
|
||||
/* Check if the ROM chips are 256 or 512Kbit (Just for Shadowing sanity) */
|
||||
romsize = ROM_SIZE;
|
||||
|
||||
if (!EXTENDED_GRANULARITY_ENABLED)
|
||||
{
|
||||
shadowbios = !!(dev->regs[0x22] & 0x01);
|
||||
shadowbios_write = !!(dev->regs[0x22] & 0x01);
|
||||
if (!EXTENDED_GRANULARITY_ENABLED) {
|
||||
shadowbios = !!(dev->regs[0x22] & 0x01);
|
||||
shadowbios_write = !!(dev->regs[0x22] & 0x01);
|
||||
|
||||
/* Base System 512/640KB set */
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);
|
||||
/* Base System 512/640KB set */
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);
|
||||
|
||||
/* Video RAM shadow*/
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (dev->regs[0x22] & (0x04 << 8)) ? DETERMINE_VIDEO_RAM_WRITE_ACCESS : DISABLED_SHADOW);
|
||||
/* Video RAM shadow*/
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (dev->regs[0x22] & (0x04 << 8)) ? DETERMINE_VIDEO_RAM_WRITE_ACCESS : DISABLED_SHADOW);
|
||||
|
||||
/* Option ROM shadow */
|
||||
mem_set_mem_state_both(0xc0000, 0x20000, (dev->regs[0x22] & (0x02 << 8)) ? ENABLED_SHADOW : DISABLED_SHADOW);
|
||||
/* Option ROM shadow */
|
||||
mem_set_mem_state_both(0xc0000, 0x20000, (dev->regs[0x22] & (0x02 << 8)) ? ENABLED_SHADOW : DISABLED_SHADOW);
|
||||
|
||||
/* System ROM shadow */
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, (dev->regs[0x22] & 0x01) ? ENABLED_SHADOW : DISABLED_SHADOW);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x24: /* Roll Compare (Just top remapping. Not followed according to datasheet!) */
|
||||
case 0x26:
|
||||
rc1_remap = (dev->regs[0x24] & 0x01) ? DEFINE_RC1_REMAP_SIZE : 0;
|
||||
rc2_remap = (dev->regs[0x26] & 0x01) ? DEFINE_RC2_REMAP_SIZE : 0;
|
||||
mem_remap_top(rc1_remap + rc2_remap);
|
||||
break;
|
||||
|
||||
case 0x2e: /* Extended Granularity (Enabled if Bit 0 in Register 2Ch is set) */
|
||||
if (EXTENDED_GRANULARITY_ENABLED)
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
base = 0xc0000 + (i << 15);
|
||||
shadowbios = (dev->regs[0x2e] & (1 << (i + 8))) && (base == romsize);
|
||||
shadowbios_write = (dev->regs[0x2e] & (1 << i)) && (base == romsize);
|
||||
mem_set_mem_state_both(base, 0x8000, GRANULARITY_RECALC);
|
||||
/* System ROM shadow */
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, (dev->regs[0x22] & 0x01) ? ENABLED_SHADOW : DISABLED_SHADOW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x24: /* Roll Compare (Just top remapping. Not followed according to datasheet!) */
|
||||
case 0x26:
|
||||
rc1_remap = (dev->regs[0x24] & 0x01) ? DEFINE_RC1_REMAP_SIZE : 0;
|
||||
rc2_remap = (dev->regs[0x26] & 0x01) ? DEFINE_RC2_REMAP_SIZE : 0;
|
||||
mem_remap_top(rc1_remap + rc2_remap);
|
||||
break;
|
||||
|
||||
case 0x2e: /* Extended Granularity (Enabled if Bit 0 in Register 2Ch is set) */
|
||||
if (EXTENDED_GRANULARITY_ENABLED) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
shadowbios = (dev->regs[0x2e] & (1 << (i + 8))) && (base == romsize);
|
||||
shadowbios_write = (dev->regs[0x2e] & (1 << i)) && (base == romsize);
|
||||
mem_set_mem_state_both(base, 0x8000, GRANULARITY_RECALC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +143,7 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv)
|
||||
static uint16_t
|
||||
intel_82335_read(uint16_t addr, void *priv)
|
||||
{
|
||||
intel_82335_t *dev = (intel_82335_t *)priv;
|
||||
intel_82335_t *dev = (intel_82335_t *) priv;
|
||||
|
||||
intel_82335_log("Register %02x: Read %04x\n", addr, dev->regs[addr]);
|
||||
|
||||
@@ -159,7 +153,7 @@ intel_82335_read(uint16_t addr, void *priv)
|
||||
static void
|
||||
intel_82335_close(void *priv)
|
||||
{
|
||||
intel_82335_t *dev = (intel_82335_t *)priv;
|
||||
intel_82335_t *dev = (intel_82335_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -167,7 +161,7 @@ intel_82335_close(void *priv)
|
||||
static void *
|
||||
intel_82335_init(const device_t *info)
|
||||
{
|
||||
intel_82335_t *dev = (intel_82335_t *)malloc(sizeof(intel_82335_t));
|
||||
intel_82335_t *dev = (intel_82335_t *) malloc(sizeof(intel_82335_t));
|
||||
memset(dev, 0, sizeof(intel_82335_t));
|
||||
|
||||
memset(dev->regs, 0, sizeof(dev->regs));
|
||||
@@ -197,15 +191,15 @@ intel_82335_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t intel_82335_device = {
|
||||
.name = "Intel 82335",
|
||||
.name = "Intel 82335",
|
||||
.internal_name = "intel_82335",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = intel_82335_init,
|
||||
.close = intel_82335_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = intel_82335_init,
|
||||
.close = intel_82335_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -31,290 +31,292 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t id,
|
||||
regs[256];
|
||||
uint8_t id,
|
||||
regs[256];
|
||||
|
||||
uint16_t timer_base,
|
||||
timer_latch;
|
||||
uint16_t timer_base,
|
||||
timer_latch;
|
||||
|
||||
double fast_off_period;
|
||||
double fast_off_period;
|
||||
|
||||
pc_timer_t timer, fast_off_timer;
|
||||
pc_timer_t timer, fast_off_timer;
|
||||
|
||||
apm_t * apm;
|
||||
port_92_t * port_92;
|
||||
apm_t *apm;
|
||||
port_92_t *port_92;
|
||||
} sio_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_SIO_LOG
|
||||
int sio_do_log = ENABLE_SIO_LOG;
|
||||
|
||||
|
||||
static void
|
||||
sio_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sio_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define sio_log(fmt, ...)
|
||||
# define sio_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
sio_timer_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
|
||||
if (!(addr & 0x0002)) {
|
||||
if (addr & 0x0001)
|
||||
dev->timer_latch = (dev->timer_latch & 0xff) | (val << 8);
|
||||
else
|
||||
dev->timer_latch = (dev->timer_latch & 0xff00) | val;
|
||||
if (addr & 0x0001)
|
||||
dev->timer_latch = (dev->timer_latch & 0xff) | (val << 8);
|
||||
else
|
||||
dev->timer_latch = (dev->timer_latch & 0xff00) | val;
|
||||
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_timer_writew(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
|
||||
if (!(addr & 0x0002)) {
|
||||
dev->timer_latch = val;
|
||||
dev->timer_latch = val;
|
||||
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sio_timer_read(uint16_t addr, void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
uint16_t sio_timer_latch;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (!(addr & 0x0002)) {
|
||||
cycles -= ((int) (PITCONST >> 32));
|
||||
cycles -= ((int) (PITCONST >> 32));
|
||||
|
||||
sio_timer_latch = timer_get_remaining_us(&dev->timer);
|
||||
sio_timer_latch = timer_get_remaining_us(&dev->timer);
|
||||
|
||||
if (addr & 0x0001)
|
||||
ret = sio_timer_latch >> 8;
|
||||
else
|
||||
ret = sio_timer_latch & 0xff;
|
||||
if (addr & 0x0001)
|
||||
ret = sio_timer_latch >> 8;
|
||||
else
|
||||
ret = sio_timer_latch & 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
sio_timer_readw(uint16_t addr, void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
if (!(addr & 0x0002)) {
|
||||
cycles -= ((int) (PITCONST >> 32));
|
||||
cycles -= ((int) (PITCONST >> 32));
|
||||
|
||||
ret = timer_get_remaining_us(&dev->timer);
|
||||
ret = timer_get_remaining_us(&dev->timer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
uint8_t old;
|
||||
|
||||
if (func > 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40))
|
||||
return;
|
||||
return;
|
||||
|
||||
/* The IB (original) variant of the SIO has no PCI IRQ steering. */
|
||||
if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03))
|
||||
return;
|
||||
return;
|
||||
|
||||
old = dev->regs[addr];
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /*Command register*/
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = (dev->regs[addr] & 0xf7) | (val & 0x08);
|
||||
break;
|
||||
case 0x04: /*Command register*/
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = (dev->regs[addr] & 0xf7) | (val & 0x08);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->regs[addr] &= ~(val & 0x38);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[addr] &= ~(val & 0x38);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
case 0x40:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
|
||||
if (!((val ^ old) & 0x40))
|
||||
return;
|
||||
if (!((val ^ old) & 0x40))
|
||||
return;
|
||||
|
||||
dma_alias_remove();
|
||||
if (!(val & 0x40))
|
||||
dma_alias_set();
|
||||
} else
|
||||
dev->regs[addr] = (val & 0x3f);
|
||||
break;
|
||||
case 0x41: case 0x44:
|
||||
dev->regs[addr] = (val & 0x1f);
|
||||
break;
|
||||
case 0x42:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = val;
|
||||
else
|
||||
dev->regs[addr] = (val & 0x77);
|
||||
break;
|
||||
case 0x43:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = (val & 0x01);
|
||||
break;
|
||||
case 0x45: case 0x46:
|
||||
case 0x47: case 0x48:
|
||||
case 0x49: case 0x4a:
|
||||
case 0x4b: case 0x4e:
|
||||
case 0x54: case 0x55:
|
||||
case 0x56:
|
||||
dev->regs[addr] = val;
|
||||
break;
|
||||
case 0x4c: case 0x4d:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->regs[addr] = val;
|
||||
dma_alias_remove();
|
||||
if (!(val & 0x40))
|
||||
dma_alias_set();
|
||||
} else
|
||||
dev->regs[addr] = (val & 0x3f);
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x44:
|
||||
dev->regs[addr] = (val & 0x1f);
|
||||
break;
|
||||
case 0x42:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = val;
|
||||
else
|
||||
dev->regs[addr] = (val & 0x77);
|
||||
break;
|
||||
case 0x43:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = (val & 0x01);
|
||||
break;
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4e:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
dev->regs[addr] = val;
|
||||
break;
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->regs[addr] = val;
|
||||
|
||||
if (!((val ^ old) & 0x40))
|
||||
return;
|
||||
if (!((val ^ old) & 0x40))
|
||||
return;
|
||||
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x40)
|
||||
port_92_add(dev->port_92);
|
||||
break;
|
||||
case 0x57:
|
||||
dev->regs[addr] = val;
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x40)
|
||||
port_92_add(dev->port_92);
|
||||
break;
|
||||
case 0x57:
|
||||
dev->regs[addr] = val;
|
||||
|
||||
dma_remove_sg();
|
||||
dma_set_sg_base(val);
|
||||
break;
|
||||
case 0x60: case 0x61: case 0x62: case 0x63:
|
||||
if (dev->id == 0x03) {
|
||||
sio_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val);
|
||||
dev->regs[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf);
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
if (addr == 0x80)
|
||||
dev->regs[addr] = val & 0xfd;
|
||||
else
|
||||
dev->regs[addr] = val;
|
||||
dma_remove_sg();
|
||||
dma_set_sg_base(val);
|
||||
break;
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
if (dev->id == 0x03) {
|
||||
sio_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val);
|
||||
dev->regs[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf);
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
if (addr == 0x80)
|
||||
dev->regs[addr] = val & 0xfd;
|
||||
else
|
||||
dev->regs[addr] = val;
|
||||
|
||||
if (dev->timer_base & 0x01) {
|
||||
io_removehandler(dev->timer_base & 0xfffc, 0x0004,
|
||||
sio_timer_read, sio_timer_readw, NULL,
|
||||
sio_timer_write, sio_timer_writew, NULL, dev);
|
||||
}
|
||||
dev->timer_base = (dev->regs[0x81] << 8) | (dev->regs[0x80] & 0xfd);
|
||||
if (dev->timer_base & 0x01) {
|
||||
io_sethandler(dev->timer_base & 0xfffc, 0x0004,
|
||||
sio_timer_read, sio_timer_readw, NULL,
|
||||
sio_timer_write, sio_timer_writew, NULL, dev);
|
||||
}
|
||||
break;
|
||||
case 0xa0:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0x1f;
|
||||
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80));
|
||||
switch ((val & 0x18) >> 3) {
|
||||
case 0x00:
|
||||
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
|
||||
break;
|
||||
case 0x01:
|
||||
default:
|
||||
dev->fast_off_period = 0.0;
|
||||
break;
|
||||
case 0x02:
|
||||
dev->fast_off_period = PCICLK;
|
||||
break;
|
||||
case 0x03:
|
||||
dev->fast_off_period = PCICLK * 32768.0;
|
||||
break;
|
||||
}
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
}
|
||||
break;
|
||||
case 0xa2:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xff;
|
||||
apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80));
|
||||
}
|
||||
break;
|
||||
case 0xaa:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] &= (val & 0xff);
|
||||
break;
|
||||
case 0xac: case 0xae:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = val & 0xff;
|
||||
break;
|
||||
case 0xa4:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xfb;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr];
|
||||
}
|
||||
break;
|
||||
case 0xa5:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xff;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8);
|
||||
}
|
||||
break;
|
||||
case 0xa7:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xa0;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24);
|
||||
}
|
||||
break;
|
||||
case 0xa8:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
cpu_fast_off_val = val;
|
||||
cpu_fast_off_count = val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
break;
|
||||
if (dev->timer_base & 0x01) {
|
||||
io_removehandler(dev->timer_base & 0xfffc, 0x0004,
|
||||
sio_timer_read, sio_timer_readw, NULL,
|
||||
sio_timer_write, sio_timer_writew, NULL, dev);
|
||||
}
|
||||
dev->timer_base = (dev->regs[0x81] << 8) | (dev->regs[0x80] & 0xfd);
|
||||
if (dev->timer_base & 0x01) {
|
||||
io_sethandler(dev->timer_base & 0xfffc, 0x0004,
|
||||
sio_timer_read, sio_timer_readw, NULL,
|
||||
sio_timer_write, sio_timer_writew, NULL, dev);
|
||||
}
|
||||
break;
|
||||
case 0xa0:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0x1f;
|
||||
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80));
|
||||
switch ((val & 0x18) >> 3) {
|
||||
case 0x00:
|
||||
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
|
||||
break;
|
||||
case 0x01:
|
||||
default:
|
||||
dev->fast_off_period = 0.0;
|
||||
break;
|
||||
case 0x02:
|
||||
dev->fast_off_period = PCICLK;
|
||||
break;
|
||||
case 0x03:
|
||||
dev->fast_off_period = PCICLK * 32768.0;
|
||||
break;
|
||||
}
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
}
|
||||
break;
|
||||
case 0xa2:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xff;
|
||||
apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80));
|
||||
}
|
||||
break;
|
||||
case 0xaa:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] &= (val & 0xff);
|
||||
break;
|
||||
case 0xac:
|
||||
case 0xae:
|
||||
if (dev->id == 0x03)
|
||||
dev->regs[addr] = val & 0xff;
|
||||
break;
|
||||
case 0xa4:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xfb;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr];
|
||||
}
|
||||
break;
|
||||
case 0xa5:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xff;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8);
|
||||
}
|
||||
break;
|
||||
case 0xa7:
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[addr] = val & 0xa0;
|
||||
cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24);
|
||||
}
|
||||
break;
|
||||
case 0xa8:
|
||||
dev->regs[addr] = val & 0xff;
|
||||
cpu_fast_off_val = val;
|
||||
cpu_fast_off_count = val + 1;
|
||||
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sio_read(int func, int addr, void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
ret = 0xff;
|
||||
@@ -325,47 +327,44 @@ sio_read(int func, int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_config_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sio_config_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
switch (port & 0x000f) {
|
||||
case 3:
|
||||
ret = 0xff;
|
||||
break;
|
||||
case 5:
|
||||
ret = 0xd3;
|
||||
case 3:
|
||||
ret = 0xff;
|
||||
break;
|
||||
case 5:
|
||||
ret = 0xd3;
|
||||
|
||||
switch (cpu_pci_speed) {
|
||||
case 20000000:
|
||||
ret |= 0x0c;
|
||||
break;
|
||||
case 25000000:
|
||||
default:
|
||||
ret |= 0x00;
|
||||
break;
|
||||
case 30000000:
|
||||
ret |= 0x08;
|
||||
break;
|
||||
case 33333333:
|
||||
ret |= 0x04;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
switch (cpu_pci_speed) {
|
||||
case 20000000:
|
||||
ret |= 0x0c;
|
||||
break;
|
||||
case 25000000:
|
||||
default:
|
||||
ret |= 0x00;
|
||||
break;
|
||||
case 30000000:
|
||||
ret |= 0x08;
|
||||
break;
|
||||
case 33333333:
|
||||
ret |= 0x04;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_reset_hard(void *priv)
|
||||
{
|
||||
@@ -373,27 +372,37 @@ sio_reset_hard(void *priv)
|
||||
|
||||
memset(dev->regs, 0, 256);
|
||||
|
||||
dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/
|
||||
dev->regs[0x02] = 0x84; dev->regs[0x03] = 0x04; /*82378IB (SIO)*/
|
||||
dev->regs[0x00] = 0x86;
|
||||
dev->regs[0x01] = 0x80; /*Intel*/
|
||||
dev->regs[0x02] = 0x84;
|
||||
dev->regs[0x03] = 0x04; /*82378IB (SIO)*/
|
||||
dev->regs[0x04] = 0x07;
|
||||
dev->regs[0x07] = 0x02;
|
||||
dev->regs[0x08] = dev->id;
|
||||
|
||||
dev->regs[0x40] = 0x20; dev->regs[0x41] = 0x00;
|
||||
dev->regs[0x40] = 0x20;
|
||||
dev->regs[0x41] = 0x00;
|
||||
dev->regs[0x42] = 0x04;
|
||||
dev->regs[0x45] = 0x10; dev->regs[0x46] = 0x0f;
|
||||
dev->regs[0x45] = 0x10;
|
||||
dev->regs[0x46] = 0x0f;
|
||||
dev->regs[0x48] = 0x01;
|
||||
dev->regs[0x4a] = 0x10; dev->regs[0x4b] = 0x0f;
|
||||
dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40;
|
||||
dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f;
|
||||
dev->regs[0x4a] = 0x10;
|
||||
dev->regs[0x4b] = 0x0f;
|
||||
dev->regs[0x4c] = 0x56;
|
||||
dev->regs[0x4d] = 0x40;
|
||||
dev->regs[0x4e] = 0x07;
|
||||
dev->regs[0x4f] = 0x4f;
|
||||
dev->regs[0x57] = 0x04;
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[0x60] = 0x80; dev->regs[0x61] = 0x80; dev->regs[0x62] = 0x80; dev->regs[0x63] = 0x80;
|
||||
dev->regs[0x60] = 0x80;
|
||||
dev->regs[0x61] = 0x80;
|
||||
dev->regs[0x62] = 0x80;
|
||||
dev->regs[0x63] = 0x80;
|
||||
}
|
||||
dev->regs[0x80] = 0x78;
|
||||
if (dev->id == 0x03) {
|
||||
dev->regs[0xa0] = 0x08;
|
||||
dev->regs[0xa8] = 0x0f;
|
||||
dev->regs[0xa0] = 0x08;
|
||||
dev->regs[0xa8] = 0x0f;
|
||||
}
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
@@ -402,25 +411,23 @@ sio_reset_hard(void *priv)
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
|
||||
if (dev->timer_base & 0x0001) {
|
||||
io_removehandler(dev->timer_base & 0xfffc, 0x0004,
|
||||
sio_timer_read, sio_timer_readw, NULL,
|
||||
sio_timer_write, sio_timer_writew, NULL, dev);
|
||||
io_removehandler(dev->timer_base & 0xfffc, 0x0004,
|
||||
sio_timer_read, sio_timer_readw, NULL,
|
||||
sio_timer_write, sio_timer_writew, NULL, dev);
|
||||
}
|
||||
|
||||
dev->timer_base = 0x0078;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_apm_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
sio_t *dev = (sio_t *) p;
|
||||
|
||||
if (dev->apm->do_smi)
|
||||
dev->regs[0xaa] |= 0x80;
|
||||
dev->regs[0xaa] |= 0x80;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_fast_off_count(void *priv)
|
||||
{
|
||||
@@ -430,7 +437,6 @@ sio_fast_off_count(void *priv)
|
||||
dev->regs[0xaa] |= 0x20;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_reset(void *p)
|
||||
{
|
||||
@@ -441,48 +447,45 @@ sio_reset(void *p)
|
||||
dma_set_params(1, 0xffffffff);
|
||||
|
||||
if (dev->id == 0x03) {
|
||||
sio_write(0, 0xa0, 0x08, p);
|
||||
sio_write(0, 0xa2, 0x00, p);
|
||||
sio_write(0, 0xa4, 0x00, p);
|
||||
sio_write(0, 0xa5, 0x00, p);
|
||||
sio_write(0, 0xa6, 0x00, p);
|
||||
sio_write(0, 0xa7, 0x00, p);
|
||||
sio_write(0, 0xa8, 0x0f, p);
|
||||
sio_write(0, 0xa0, 0x08, p);
|
||||
sio_write(0, 0xa2, 0x00, p);
|
||||
sio_write(0, 0xa4, 0x00, p);
|
||||
sio_write(0, 0xa5, 0x00, p);
|
||||
sio_write(0, 0xa6, 0x00, p);
|
||||
sio_write(0, 0xa7, 0x00, p);
|
||||
sio_write(0, 0xa8, 0x0f, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_close(void *p)
|
||||
{
|
||||
sio_t *dev = (sio_t *)p;
|
||||
sio_t *dev = (sio_t *) p;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sio_speed_changed(void *priv)
|
||||
{
|
||||
sio_t *dev = (sio_t *) priv;
|
||||
int te;
|
||||
int te;
|
||||
|
||||
te = timer_is_enabled(&dev->timer);
|
||||
|
||||
timer_disable(&dev->timer);
|
||||
if (te)
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
|
||||
if (dev->id == 0x03) {
|
||||
te = timer_is_enabled(&dev->fast_off_timer);
|
||||
te = timer_is_enabled(&dev->fast_off_timer);
|
||||
|
||||
timer_stop(&dev->fast_off_timer);
|
||||
if (te)
|
||||
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
|
||||
timer_stop(&dev->fast_off_timer);
|
||||
if (te)
|
||||
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sio_init(const device_t *info)
|
||||
{
|
||||
@@ -494,24 +497,24 @@ sio_init(const device_t *info)
|
||||
dev->id = info->local;
|
||||
|
||||
if (dev->id == 0x03)
|
||||
timer_add(&dev->fast_off_timer, sio_fast_off_count, dev, 0);
|
||||
timer_add(&dev->fast_off_timer, sio_fast_off_count, dev, 0);
|
||||
|
||||
sio_reset_hard(dev);
|
||||
|
||||
cpu_fast_off_flags = 0x00000000;
|
||||
|
||||
if (dev->id == 0x03) {
|
||||
cpu_fast_off_val = dev->regs[0xa8];
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
cpu_fast_off_val = dev->regs[0xa8];
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
|
||||
cpu_register_fast_off_handler(&dev->fast_off_timer);
|
||||
cpu_register_fast_off_handler(&dev->fast_off_timer);
|
||||
} else
|
||||
cpu_fast_off_val = cpu_fast_off_count = 0;
|
||||
cpu_fast_off_val = cpu_fast_off_count = 0;
|
||||
|
||||
if (dev->id == 0x03) {
|
||||
dev->apm = device_add(&apm_pci_device);
|
||||
/* APM intercept handler to update 82378ZB SMI status on APM SMI. */
|
||||
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, sio_apm_out, NULL, NULL, dev);
|
||||
dev->apm = device_add(&apm_pci_device);
|
||||
/* APM intercept handler to update 82378ZB SMI status on APM SMI. */
|
||||
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, sio_apm_out, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
@@ -522,12 +525,12 @@ sio_init(const device_t *info)
|
||||
dma_high_page_init();
|
||||
|
||||
if (dev->id == 0x03)
|
||||
dma_alias_set();
|
||||
dma_alias_set();
|
||||
|
||||
io_sethandler(0x0073, 0x0001,
|
||||
sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev);
|
||||
sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0075, 0x0001,
|
||||
sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev);
|
||||
sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev);
|
||||
|
||||
timer_add(&dev->timer, NULL, NULL, 0);
|
||||
|
||||
@@ -536,32 +539,30 @@ sio_init(const device_t *info)
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t sio_device = {
|
||||
.name = "Intel 82378IB (SIO)",
|
||||
.name = "Intel 82378IB (SIO)",
|
||||
.internal_name = "sio",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sio_init,
|
||||
.close = sio_close,
|
||||
.reset = sio_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sio_init,
|
||||
.close = sio_close,
|
||||
.reset = sio_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = sio_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t sio_zb_device = {
|
||||
.name = "Intel 82378ZB (SIO)",
|
||||
.name = "Intel 82378ZB (SIO)",
|
||||
.internal_name = "sio_zb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x03,
|
||||
.init = sio_init,
|
||||
.close = sio_close,
|
||||
.reset = sio_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x03,
|
||||
.init = sio_init,
|
||||
.close = sio_close,
|
||||
.reset = sio_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = sio_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
1016
src/chipset/neat.c
1016
src/chipset/neat.c
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,6 @@
|
||||
* Copyright 2020-2021 EngiNerd
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -35,8 +34,8 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t reg_065;
|
||||
uint8_t reg_067;
|
||||
uint8_t reg_065;
|
||||
uint8_t reg_067;
|
||||
uint8_t reg_069;
|
||||
} olivetti_eva_t;
|
||||
|
||||
@@ -50,11 +49,11 @@ olivetti_eva_log(const char *fmt, ...)
|
||||
if (olivetti_eva_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define olivetti_eva_log(fmt, ...)
|
||||
# define olivetti_eva_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
@@ -98,7 +97,7 @@ static uint8_t
|
||||
olivetti_eva_read(uint16_t addr, void *priv)
|
||||
{
|
||||
olivetti_eva_t *dev = (olivetti_eva_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
switch (addr) {
|
||||
case 0x065:
|
||||
ret = dev->reg_065;
|
||||
@@ -115,7 +114,6 @@ olivetti_eva_read(uint16_t addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
olivetti_eva_close(void *priv)
|
||||
{
|
||||
@@ -157,15 +155,15 @@ olivetti_eva_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t olivetti_eva_device = {
|
||||
.name = "Olivetti EVA Gate Array",
|
||||
.name = "Olivetti EVA Gate Array",
|
||||
.internal_name = "olivetta_eva",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = olivetti_eva_init,
|
||||
.close = olivetti_eva_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = olivetti_eva_init,
|
||||
.close = olivetti_eva_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI283_LOG
|
||||
int opti283_do_log = ENABLE_OPTI283_LOG;
|
||||
|
||||
@@ -39,33 +38,29 @@ opti283_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti283_do_log)
|
||||
{
|
||||
if (opti283_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti283_log(fmt, ...)
|
||||
# define opti283_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t phys, virt;
|
||||
uint32_t phys, virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, shadow_high,
|
||||
regs[256];
|
||||
mem_remapping_t mem_remappings[2];
|
||||
mem_mapping_t mem_mappings[2];
|
||||
uint8_t index, shadow_high,
|
||||
regs[256];
|
||||
mem_remapping_t mem_remappings[2];
|
||||
mem_mapping_t mem_mappings[2];
|
||||
} opti283_t;
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti283_read_remapped_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -74,7 +69,6 @@ opti283_read_remapped_ram(uint32_t addr, void *priv)
|
||||
return mem_read_ram((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
opti283_read_remapped_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -83,7 +77,6 @@ opti283_read_remapped_ramw(uint32_t addr, void *priv)
|
||||
return mem_read_ramw((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
opti283_read_remapped_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -92,7 +85,6 @@ opti283_read_remapped_raml(uint32_t addr, void *priv)
|
||||
return mem_read_raml((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti283_write_remapped_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -101,7 +93,6 @@ opti283_write_remapped_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
mem_write_ram((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti283_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
@@ -110,7 +101,6 @@ opti283_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
mem_write_ramw((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti283_write_remapped_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
@@ -119,161 +109,157 @@ opti283_write_remapped_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
mem_write_raml((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti283_shadow_recalc(opti283_t *dev)
|
||||
{
|
||||
uint32_t i, base;
|
||||
uint32_t rbase;
|
||||
uint8_t sh_enable, sh_mode;
|
||||
uint8_t rom, sh_copy;
|
||||
uint8_t sh_enable, sh_mode;
|
||||
uint8_t rom, sh_copy;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
dev->shadow_high = 0;
|
||||
dev->shadow_high = 0;
|
||||
|
||||
opti283_log("OPTI 283: %02X %02X %02X %02X\n", dev->regs[0x11], dev->regs[0x12], dev->regs[0x13], dev->regs[0x14]);
|
||||
|
||||
if (dev->regs[0x11] & 0x80) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: F0000-FFFFF READ_EXTANY, WRITE_INTERNAL\n");
|
||||
shadowbios_write = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: F0000-FFFFF READ_EXTANY, WRITE_INTERNAL\n");
|
||||
shadowbios_write = 1;
|
||||
} else {
|
||||
shadowbios = 1;
|
||||
if (dev->regs[0x14] & 0x80) {
|
||||
mem_set_mem_state_both(0xf0000, 0x01000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: F0000-F0FFF READ_INTERNAL, WRITE_INTERNAL\n");
|
||||
shadowbios_write = 1;
|
||||
} else {
|
||||
mem_set_mem_state_both(0xf0000, 0x01000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: F0000-F0FFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
}
|
||||
shadowbios = 1;
|
||||
if (dev->regs[0x14] & 0x80) {
|
||||
mem_set_mem_state_both(0xf0000, 0x01000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: F0000-F0FFF READ_INTERNAL, WRITE_INTERNAL\n");
|
||||
shadowbios_write = 1;
|
||||
} else {
|
||||
mem_set_mem_state_both(0xf0000, 0x01000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: F0000-F0FFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(0xf1000, 0x0f000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: F1000-FFFFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
mem_set_mem_state_both(0xf1000, 0x0f000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: F1000-FFFFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
}
|
||||
|
||||
sh_copy = dev->regs[0x11] & 0x08;
|
||||
for (i = 0; i < 12; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (i >= 4)
|
||||
sh_enable = dev->regs[0x12] & (1 << (i - 4));
|
||||
else
|
||||
sh_enable = dev->regs[0x13] & (1 << (i + 4));
|
||||
sh_mode = dev->regs[0x11] & (1 << (i >> 2));
|
||||
rom = dev->regs[0x11] & (1 << ((i >> 2) + 4));
|
||||
opti283_log("OPTI 283: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (i >= 4)
|
||||
sh_enable = dev->regs[0x12] & (1 << (i - 4));
|
||||
else
|
||||
sh_enable = dev->regs[0x13] & (1 << (i + 4));
|
||||
sh_mode = dev->regs[0x11] & (1 << (i >> 2));
|
||||
rom = dev->regs[0x11] & (1 << ((i >> 2) + 4));
|
||||
opti283_log("OPTI 283: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (sh_mode) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (sh_mode) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
if (sh_copy) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_EXTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTANY, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
if (sh_copy) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_EXTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTANY, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_DISABLED);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rbase = ((uint32_t) (dev->regs[0x13] & 0x0f)) << 20;
|
||||
|
||||
if (rbase > 0) {
|
||||
dev->mem_remappings[0].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[0], rbase, 0x00020000);
|
||||
dev->mem_remappings[0].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[0], rbase, 0x00020000);
|
||||
|
||||
if (!dev->shadow_high) {
|
||||
rbase += 0x00020000;
|
||||
dev->mem_remappings[1].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[1], rbase , 0x00020000);
|
||||
} else
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
if (!dev->shadow_high) {
|
||||
rbase += 0x00020000;
|
||||
dev->mem_remappings[1].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[1], rbase, 0x00020000);
|
||||
} else
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti283_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti283_t *dev = (opti283_t *)priv;
|
||||
opti283_t *dev = (opti283_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti283_log("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
case 0x24:
|
||||
opti283_log("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
switch (dev->index) {
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
/* FALLTHROUGH */
|
||||
case 0x11: case 0x12:
|
||||
case 0x13:
|
||||
dev->regs[dev->index] = val;
|
||||
opti283_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
/* FALLTHROUGH */
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
dev->regs[dev->index] = val;
|
||||
opti283_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti283_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti283_t *dev = (opti283_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
opti283_t *dev = (opti283_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24)
|
||||
ret = dev->regs[dev->index];
|
||||
ret = dev->regs[dev->index];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti283_close(void *priv)
|
||||
{
|
||||
opti283_t *dev = (opti283_t *)priv;
|
||||
opti283_t *dev = (opti283_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti283_init(const device_t *info)
|
||||
{
|
||||
opti283_t *dev = (opti283_t *)malloc(sizeof(opti283_t));
|
||||
opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t));
|
||||
memset(dev, 0x00, sizeof(opti283_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
|
||||
@@ -286,14 +272,14 @@ opti283_init(const device_t *info)
|
||||
dev->mem_remappings[1].phys = 0x000d0000;
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[0], 0, 0x00020000,
|
||||
opti283_read_remapped_ram, opti283_read_remapped_ramw, opti283_read_remapped_raml,
|
||||
opti283_write_remapped_ram, opti283_write_remapped_ramw, opti283_write_remapped_raml,
|
||||
opti283_read_remapped_ram, opti283_read_remapped_ramw, opti283_read_remapped_raml,
|
||||
opti283_write_remapped_ram, opti283_write_remapped_ramw, opti283_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[0].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[1], 0, 0x00020000,
|
||||
opti283_read_remapped_ram, opti283_read_remapped_ramw, opti283_read_remapped_raml,
|
||||
opti283_write_remapped_ram, opti283_write_remapped_ramw, opti283_write_remapped_raml,
|
||||
opti283_read_remapped_ram, opti283_read_remapped_ramw, opti283_read_remapped_raml,
|
||||
opti283_write_remapped_ram, opti283_write_remapped_ramw, opti283_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[1].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[1]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
|
||||
@@ -303,15 +289,15 @@ opti283_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti283_device = {
|
||||
.name = "OPTi 82C283",
|
||||
.name = "OPTi 82C283",
|
||||
.internal_name = "opti283",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti283_init,
|
||||
.close = opti283_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti283_init,
|
||||
.close = opti283_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -34,128 +34,125 @@ int opti291_do_log = ENABLE_OPTI291_LOG;
|
||||
static void
|
||||
opti291_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
if (opti291_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
if (opti291_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti291_log(fmt, ...)
|
||||
# define opti291_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, regs[256];
|
||||
port_92_t *port_92;
|
||||
uint8_t index, regs[256];
|
||||
port_92_t *port_92;
|
||||
} opti291_t;
|
||||
|
||||
static void opti291_recalc(opti291_t *dev)
|
||||
static void
|
||||
opti291_recalc(opti291_t *dev)
|
||||
{
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, (!(dev->regs[0x23] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x80) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, (!(dev->regs[0x23] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x80) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, ((dev->regs[0x26] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x10) ? MEM_WRITE_DISABLED : ((dev->regs[0x26] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
|
||||
mem_set_mem_state_both(0xd0000 + (i << 14), 0x4000, ((dev->regs[0x25] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x20) ? MEM_WRITE_DISABLED : ((dev->regs[0x25] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 14), 0x4000, ((dev->regs[0x24] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x40) ? MEM_WRITE_DISABLED : ((dev->regs[0x24] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
|
||||
}
|
||||
flushmmucache();
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, ((dev->regs[0x26] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x10) ? MEM_WRITE_DISABLED : ((dev->regs[0x26] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
|
||||
mem_set_mem_state_both(0xd0000 + (i << 14), 0x4000, ((dev->regs[0x25] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x20) ? MEM_WRITE_DISABLED : ((dev->regs[0x25] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 14), 0x4000, ((dev->regs[0x24] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x40) ? MEM_WRITE_DISABLED : ((dev->regs[0x24] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
|
||||
}
|
||||
flushmmucache();
|
||||
}
|
||||
static void
|
||||
opti291_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti291_t *dev = (opti291_t *)priv;
|
||||
opti291_t *dev = (opti291_t *) priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x24:
|
||||
opti291_log("OPTi 291: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
switch (dev->index)
|
||||
{
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = val & 0x3f;
|
||||
break;
|
||||
case 0x21:
|
||||
dev->regs[dev->index] = val & 0xf3;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
dev->regs[dev->index] = val;
|
||||
opti291_recalc(dev);
|
||||
break;
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x29:
|
||||
dev->regs[dev->index] = val & 0x0f;
|
||||
break;
|
||||
case 0x2a:
|
||||
case 0x2b:
|
||||
case 0x2c:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x24:
|
||||
opti291_log("OPTi 291: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
switch (dev->index) {
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = val & 0x3f;
|
||||
break;
|
||||
case 0x21:
|
||||
dev->regs[dev->index] = val & 0xf3;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
dev->regs[dev->index] = val;
|
||||
opti291_recalc(dev);
|
||||
break;
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x29:
|
||||
dev->regs[dev->index] = val & 0x0f;
|
||||
break;
|
||||
case 0x2a:
|
||||
case 0x2b:
|
||||
case 0x2c:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti291_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti291_t *dev = (opti291_t *)priv;
|
||||
opti291_t *dev = (opti291_t *) priv;
|
||||
|
||||
return (addr == 0x24) ? dev->regs[dev->index] : 0xff;
|
||||
return (addr == 0x24) ? dev->regs[dev->index] : 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
opti291_close(void *priv)
|
||||
{
|
||||
opti291_t *dev = (opti291_t *)priv;
|
||||
opti291_t *dev = (opti291_t *) priv;
|
||||
|
||||
free(dev);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
opti291_init(const device_t *info)
|
||||
{
|
||||
opti291_t *dev = (opti291_t *)malloc(sizeof(opti291_t));
|
||||
memset(dev, 0, sizeof(opti291_t));
|
||||
opti291_t *dev = (opti291_t *) malloc(sizeof(opti291_t));
|
||||
memset(dev, 0, sizeof(opti291_t));
|
||||
|
||||
io_sethandler(0x022, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
|
||||
io_sethandler(0x024, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
|
||||
dev->regs[0x22] = 0xf0;
|
||||
dev->regs[0x23] = 0x40;
|
||||
dev->regs[0x28] = 0x08;
|
||||
dev->regs[0x29] = 0xa0;
|
||||
device_add(&port_92_device);
|
||||
opti291_recalc(dev);
|
||||
io_sethandler(0x022, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
|
||||
io_sethandler(0x024, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
|
||||
dev->regs[0x22] = 0xf0;
|
||||
dev->regs[0x23] = 0x40;
|
||||
dev->regs[0x28] = 0x08;
|
||||
dev->regs[0x29] = 0xa0;
|
||||
device_add(&port_92_device);
|
||||
opti291_recalc(dev);
|
||||
|
||||
return dev;
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t opti291_device = {
|
||||
.name = "OPTi 82C291",
|
||||
.name = "OPTi 82C291",
|
||||
.internal_name = "opti291",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti291_init,
|
||||
.close = opti291_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti291_init,
|
||||
.close = opti291_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI391_LOG
|
||||
int opti391_do_log = ENABLE_OPTI391_LOG;
|
||||
|
||||
@@ -37,160 +36,159 @@ opti391_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti391_do_log)
|
||||
{
|
||||
if (opti391_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti391_log(fmt, ...)
|
||||
# define opti391_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t phys, virt;
|
||||
uint32_t phys, virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, regs[256];
|
||||
uint8_t index, regs[256];
|
||||
} opti391_t;
|
||||
|
||||
|
||||
static void
|
||||
opti391_shadow_recalc(opti391_t *dev)
|
||||
{
|
||||
uint32_t i, base;
|
||||
uint8_t sh_enable, sh_master;
|
||||
uint8_t sh_wp, sh_write_internal;
|
||||
uint8_t sh_enable, sh_master;
|
||||
uint8_t sh_wp, sh_write_internal;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* F0000-FFFFF */
|
||||
sh_enable = !(dev->regs[0x22] & 0x80);
|
||||
if (sh_enable)
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
|
||||
sh_write_internal = (dev->regs[0x26] & 0x40);
|
||||
/* D0000-EFFFF */
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (base >= 0xe0000) {
|
||||
sh_master = (dev->regs[0x22] & 0x40);
|
||||
sh_wp = (dev->regs[0x22] & 0x10);
|
||||
} else {
|
||||
sh_master = (dev->regs[0x22] & 0x20);
|
||||
sh_wp = (dev->regs[0x22] & 0x08);
|
||||
}
|
||||
sh_enable = dev->regs[0x23] & (1 << i);
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (base >= 0xe0000) {
|
||||
sh_master = (dev->regs[0x22] & 0x40);
|
||||
sh_wp = (dev->regs[0x22] & 0x10);
|
||||
} else {
|
||||
sh_master = (dev->regs[0x22] & 0x20);
|
||||
sh_wp = (dev->regs[0x22] & 0x08);
|
||||
}
|
||||
sh_enable = dev->regs[0x23] & (1 << i);
|
||||
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
if (sh_wp)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
if (sh_wp)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
|
||||
/* C0000-CFFFF */
|
||||
sh_master = !(dev->regs[0x26] & 0x10);
|
||||
sh_wp = (dev->regs[0x26] & 0x20);
|
||||
sh_wp = (dev->regs[0x26] & 0x20);
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
sh_enable = dev->regs[0x26] & (1 << i);
|
||||
base = 0xc0000 + (i << 14);
|
||||
sh_enable = dev->regs[0x26] & (1 << i);
|
||||
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
if (sh_wp)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
if (sh_wp)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti391_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)priv;
|
||||
opti391_t *dev = (opti391_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
case 0x24:
|
||||
opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f);
|
||||
break;
|
||||
switch (dev->index) {
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f);
|
||||
break;
|
||||
|
||||
case 0x21: case 0x24: case 0x25: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x21:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
case 0x2a:
|
||||
case 0x2b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x22: case 0x23:
|
||||
case 0x26:
|
||||
dev->regs[dev->index] = val;
|
||||
opti391_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
dev->regs[dev->index] = val;
|
||||
opti391_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti391_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
opti391_t *dev = (opti391_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24)
|
||||
ret = dev->regs[dev->index];
|
||||
ret = dev->regs[dev->index];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti391_close(void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)priv;
|
||||
opti391_t *dev = (opti391_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti391_init(const device_t *info)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)malloc(sizeof(opti391_t));
|
||||
opti391_t *dev = (opti391_t *) malloc(sizeof(opti391_t));
|
||||
memset(dev, 0x00, sizeof(opti391_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
|
||||
@@ -212,15 +210,15 @@ opti391_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti391_device = {
|
||||
.name = "OPTi 82C391",
|
||||
.name = "OPTi 82C391",
|
||||
.internal_name = "opti391",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti391_init,
|
||||
.close = opti391_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti391_init,
|
||||
.close = opti391_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -31,159 +31,151 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx,
|
||||
regs[256],
|
||||
scratch[2];
|
||||
uint8_t idx,
|
||||
regs[256],
|
||||
scratch[2];
|
||||
} opti495_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI495_LOG
|
||||
int opti495_do_log = ENABLE_OPTI495_LOG;
|
||||
|
||||
|
||||
static void
|
||||
opti495_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti495_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti495_log(fmt, ...)
|
||||
# define opti495_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
opti495_recalc(opti495_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
if (dev->regs[0x22] & 0x80) {
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
base = 0xd0000 + (i << 14);
|
||||
|
||||
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) &&
|
||||
(dev->regs[0x23] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
shflags = MEM_READ_EXTANY;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
}
|
||||
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
shflags = MEM_READ_EXTANY;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
base = 0xc0000 + (i << 14);
|
||||
|
||||
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
shflags = MEM_READ_EXTANY;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
}
|
||||
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
shflags = MEM_READ_EXTANY;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti495_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti495_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti495_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
case 0x22:
|
||||
opti495_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti495_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
|
||||
switch(dev->idx) {
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
switch (dev->idx) {
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
opti495_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
opti495_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[~addr & 0x01] = val;
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[~addr & 0x01] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti495_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti495_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
ret = dev->regs[dev->idx];
|
||||
opti495_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[~addr & 0x01];
|
||||
break;
|
||||
case 0x22:
|
||||
opti495_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
ret = dev->regs[dev->idx];
|
||||
opti495_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[~addr & 0x01];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti495_close(void *priv)
|
||||
{
|
||||
@@ -192,7 +184,6 @@ opti495_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti495_init(const device_t *info)
|
||||
{
|
||||
@@ -207,26 +198,26 @@ opti495_init(const device_t *info)
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
if (info->local == 1) {
|
||||
/* 85C495 */
|
||||
dev->regs[0x20] = 0x02;
|
||||
dev->regs[0x21] = 0x20;
|
||||
dev->regs[0x22] = 0xe4;
|
||||
dev->regs[0x25] = 0xf0;
|
||||
dev->regs[0x26] = 0x80;
|
||||
dev->regs[0x27] = 0xb1;
|
||||
dev->regs[0x28] = 0x80;
|
||||
dev->regs[0x29] = 0x10;
|
||||
/* 85C495 */
|
||||
dev->regs[0x20] = 0x02;
|
||||
dev->regs[0x21] = 0x20;
|
||||
dev->regs[0x22] = 0xe4;
|
||||
dev->regs[0x25] = 0xf0;
|
||||
dev->regs[0x26] = 0x80;
|
||||
dev->regs[0x27] = 0xb1;
|
||||
dev->regs[0x28] = 0x80;
|
||||
dev->regs[0x29] = 0x10;
|
||||
} else {
|
||||
/* 85C493 */
|
||||
dev->regs[0x20] = 0x40;
|
||||
dev->regs[0x22] = 0x84;
|
||||
dev->regs[0x24] = 0x87;
|
||||
dev->regs[0x25] = 0xf1; /* Note: 0xf0 is also valid default. */
|
||||
dev->regs[0x27] = 0x91;
|
||||
dev->regs[0x28] = 0x80;
|
||||
dev->regs[0x29] = 0x10;
|
||||
dev->regs[0x2a] = 0x80;
|
||||
dev->regs[0x2b] = 0x10;
|
||||
/* 85C493 */
|
||||
dev->regs[0x20] = 0x40;
|
||||
dev->regs[0x22] = 0x84;
|
||||
dev->regs[0x24] = 0x87;
|
||||
dev->regs[0x25] = 0xf1; /* Note: 0xf0 is also valid default. */
|
||||
dev->regs[0x27] = 0x91;
|
||||
dev->regs[0x28] = 0x80;
|
||||
dev->regs[0x29] = 0x10;
|
||||
dev->regs[0x2a] = 0x80;
|
||||
dev->regs[0x2b] = 0x10;
|
||||
}
|
||||
|
||||
opti495_recalc(dev);
|
||||
@@ -237,29 +228,29 @@ opti495_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti493_device = {
|
||||
.name = "OPTi 82C493",
|
||||
.name = "OPTi 82C493",
|
||||
.internal_name = "opti493",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495_device = {
|
||||
.name = "OPTi 82C495",
|
||||
.name = "OPTi 82C495",
|
||||
.internal_name = "opti495",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -31,172 +31,167 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx,
|
||||
regs[256], scratch[2];
|
||||
uint8_t idx,
|
||||
regs[256], scratch[2];
|
||||
} opti499_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI499_LOG
|
||||
int opti499_do_log = ENABLE_OPTI499_LOG;
|
||||
|
||||
|
||||
static void
|
||||
opti499_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti499_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti499_log(fmt, ...)
|
||||
# define opti499_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
opti499_recalc(opti499_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
if (dev->regs[0x22] & 0x80) {
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
base = 0xd0000 + (i << 14);
|
||||
|
||||
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) &&
|
||||
(dev->regs[0x23] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
base = 0xc0000 + (i << 14);
|
||||
|
||||
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x20)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x20)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
|
||||
switch(dev->idx) {
|
||||
case 0x20:
|
||||
reset_on_hlt = !(val & 0x02);
|
||||
break;
|
||||
switch (dev->idx) {
|
||||
case 0x20:
|
||||
reset_on_hlt = !(val & 0x02);
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x22: case 0x23:
|
||||
case 0x26: case 0x2d:
|
||||
opti499_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
case 0x2d:
|
||||
opti499_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe1: case 0xe2:
|
||||
dev->scratch[~addr & 0x01] = val;
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[~addr & 0x01] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti499_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x2d)
|
||||
ret = dev->regs[dev->idx] & 0xbf;
|
||||
else
|
||||
ret = dev->regs[dev->idx];
|
||||
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[~addr & 0x01];
|
||||
break;
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x2d)
|
||||
ret = dev->regs[dev->idx] & 0xbf;
|
||||
else
|
||||
ret = dev->regs[dev->idx];
|
||||
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[~addr & 0x01];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti499_reset(void *priv)
|
||||
{
|
||||
@@ -213,7 +208,7 @@ opti499_reset(void *priv)
|
||||
dev->regs[0x27] = 0xd1;
|
||||
dev->regs[0x28] = dev->regs[0x2a] = 0x80;
|
||||
dev->regs[0x29] = dev->regs[0x2b] = 0x10;
|
||||
dev->regs[0x2d] = 0x40;
|
||||
dev->regs[0x2d] = 0x40;
|
||||
|
||||
reset_on_hlt = 1;
|
||||
|
||||
@@ -225,7 +220,6 @@ opti499_reset(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti499_close(void *priv)
|
||||
{
|
||||
@@ -234,7 +228,6 @@ opti499_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti499_init(const device_t *info)
|
||||
{
|
||||
@@ -254,15 +247,15 @@ opti499_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti499_device = {
|
||||
.name = "OPTi 82C499",
|
||||
.name = "OPTi 82C499",
|
||||
.internal_name = "opti499",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = opti499_init,
|
||||
.close = opti499_close,
|
||||
.reset = opti499_reset,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = opti499_init,
|
||||
.close = opti499_close,
|
||||
.reset = opti499_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -45,43 +45,39 @@ opti5x7_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti5x7_do_log)
|
||||
{
|
||||
if (opti5x7_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti5x7_log(fmt, ...)
|
||||
# define opti5x7_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
opti5x7_shadow_map(int cur_reg, opti5x7_t *dev)
|
||||
{
|
||||
|
||||
/*
|
||||
Register 4h: Cxxxx Segment
|
||||
Register 5h: Dxxxx Segment
|
||||
/*
|
||||
Register 4h: Cxxxx Segment
|
||||
Register 5h: Dxxxx Segment
|
||||
|
||||
Bits 7-6: xC000-xFFFF
|
||||
Bits 5-4: x8000-xBFFF
|
||||
Bits 3-2: x4000-x7FFF
|
||||
Bits 0-1: x0000-x3FFF
|
||||
Bits 7-6: xC000-xFFFF
|
||||
Bits 5-4: x8000-xBFFF
|
||||
Bits 3-2: x4000-x7FFF
|
||||
Bits 0-1: x0000-x3FFF
|
||||
|
||||
x-y
|
||||
0 0 Read/Write AT bus
|
||||
1 0 Read from AT - Write to DRAM
|
||||
1 1 Read from DRAM - Write to DRAM
|
||||
0 1 Read from DRAM (write protected)
|
||||
*/
|
||||
if (cur_reg == 0x06)
|
||||
{
|
||||
x-y
|
||||
0 0 Read/Write AT bus
|
||||
1 0 Read from AT - Write to DRAM
|
||||
1 1 Read from DRAM - Write to DRAM
|
||||
0 1 Read from DRAM (write protected)
|
||||
*/
|
||||
if (cur_reg == 0x06) {
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
for (int i = 0; i < 4; i++)
|
||||
mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
}
|
||||
@@ -92,63 +88,61 @@ Bits 0-1: x0000-x3FFF
|
||||
static void
|
||||
opti5x7_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti5x7_t *dev = (opti5x7_t *)priv;
|
||||
opti5x7_t *dev = (opti5x7_t *) priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
switch (dev->idx)
|
||||
{
|
||||
case 0x00: /* DRAM Configuration Register #1 */
|
||||
dev->regs[dev->idx] = val & 0x7f;
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x01: /* DRAM Control Register #1 */
|
||||
dev->regs[dev->idx] = val;
|
||||
case 0x24:
|
||||
switch (dev->idx) {
|
||||
case 0x00: /* DRAM Configuration Register #1 */
|
||||
dev->regs[dev->idx] = val & 0x7f;
|
||||
break;
|
||||
case 0x01: /* DRAM Control Register #1 */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x02: /* Cache Control Register #1 */
|
||||
dev->regs[dev->idx] = val;
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x0c);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x03: /* Cache Control Register #2 */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x04: /* Shadow RAM Control Register #1 */
|
||||
case 0x05: /* Shadow RAM Control Register #2 */
|
||||
case 0x06: /* Shadow RAM Control Register #3 */
|
||||
dev->regs[dev->idx] = val;
|
||||
opti5x7_shadow_map(dev->idx, dev);
|
||||
break;
|
||||
case 0x07: /* Tag Test Register */
|
||||
case 0x08: /* CPU Cache Control Register #1 */
|
||||
case 0x09: /* System Memory Function Register #1 */
|
||||
case 0x0a: /* System Memory Address Decode Register #1 */
|
||||
case 0x0b: /* System Memory Address Decode Register #2 */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x0c: /* Extended DMA Register */
|
||||
dev->regs[dev->idx] = val & 0xcf;
|
||||
break;
|
||||
case 0x0d: /* ROMCS# Register */
|
||||
case 0x0e: /* Local Master Preemption Register */
|
||||
case 0x0f: /* Deturbo Control Register #1 */
|
||||
case 0x10: /* Cache Write-Hit Control Register */
|
||||
case 0x11: /* Master Cycle Control Register */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
}
|
||||
opti5x7_log("OPTi 5x7: dev->regs[%02x] = %02x\n", dev->idx, dev->regs[dev->idx]);
|
||||
break;
|
||||
case 0x02: /* Cache Control Register #1 */
|
||||
dev->regs[dev->idx] = val;
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x0c);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x03: /* Cache Control Register #2 */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x04: /* Shadow RAM Control Register #1 */
|
||||
case 0x05: /* Shadow RAM Control Register #2 */
|
||||
case 0x06: /* Shadow RAM Control Register #3 */
|
||||
dev->regs[dev->idx] = val;
|
||||
opti5x7_shadow_map(dev->idx, dev);
|
||||
break;
|
||||
case 0x07: /* Tag Test Register */
|
||||
case 0x08: /* CPU Cache Control Register #1 */
|
||||
case 0x09: /* System Memory Function Register #1 */
|
||||
case 0x0a: /* System Memory Address Decode Register #1 */
|
||||
case 0x0b: /* System Memory Address Decode Register #2 */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x0c: /* Extended DMA Register */
|
||||
dev->regs[dev->idx] = val & 0xcf;
|
||||
break;
|
||||
case 0x0d: /* ROMCS# Register */
|
||||
case 0x0e: /* Local Master Preemption Register */
|
||||
case 0x0f: /* Deturbo Control Register #1 */
|
||||
case 0x10: /* Cache Write-Hit Control Register */
|
||||
case 0x11: /* Master Cycle Control Register */
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
}
|
||||
opti5x7_log("OPTi 5x7: dev->regs[%02x] = %02x\n", dev->idx, dev->regs[dev->idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti5x7_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti5x7_t *dev = (opti5x7_t *)priv;
|
||||
opti5x7_t *dev = (opti5x7_t *) priv;
|
||||
|
||||
return (addr == 0x24) ? dev->regs[dev->idx] : 0xff;
|
||||
}
|
||||
@@ -156,7 +150,7 @@ opti5x7_read(uint16_t addr, void *priv)
|
||||
static void
|
||||
opti5x7_close(void *priv)
|
||||
{
|
||||
opti5x7_t *dev = (opti5x7_t *)priv;
|
||||
opti5x7_t *dev = (opti5x7_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -164,7 +158,7 @@ opti5x7_close(void *priv)
|
||||
static void *
|
||||
opti5x7_init(const device_t *info)
|
||||
{
|
||||
opti5x7_t *dev = (opti5x7_t *)malloc(sizeof(opti5x7_t));
|
||||
opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t));
|
||||
memset(dev, 0, sizeof(opti5x7_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
|
||||
@@ -176,15 +170,15 @@ opti5x7_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti5x7_device = {
|
||||
.name = "OPTi 82C5x6/82C5x7",
|
||||
.name = "OPTi 82C5x6/82C5x7",
|
||||
.internal_name = "opti5x7",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti5x7_init,
|
||||
.close = opti5x7_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti5x7_init,
|
||||
.close = opti5x7_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
/* Shadow RAM */
|
||||
#define SYSTEM_READ ((dev->pci_conf[0x44] & 2) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SYSTEM_READ ((dev->pci_conf[0x44] & 2) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SYSTEM_WRITE ((dev->pci_conf[0x44] & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define SHADOW_READ ((dev->pci_conf[cur_reg] & (1 << (4 + i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SHADOW_READ ((dev->pci_conf[cur_reg] & (1 << (4 + i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SHADOW_WRITE ((dev->pci_conf[cur_reg] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
|
||||
#ifdef ENABLE_OPTI822_LOG
|
||||
@@ -45,25 +45,24 @@ opti822_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti822_do_log)
|
||||
{
|
||||
if (opti822_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti822_log(fmt, ...)
|
||||
# define opti822_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct opti822_t
|
||||
{
|
||||
typedef struct opti822_t {
|
||||
uint8_t pci_conf[256];
|
||||
} opti822_t;
|
||||
|
||||
int opti822_irq_routing[7] = {5, 9, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f};
|
||||
int opti822_irq_routing[7] = { 5, 9, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f };
|
||||
|
||||
void opti822_shadow(int cur_reg, opti822_t *dev)
|
||||
void
|
||||
opti822_shadow(int cur_reg, opti822_t *dev)
|
||||
{
|
||||
if (cur_reg == 0x44)
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE);
|
||||
@@ -78,183 +77,179 @@ static void
|
||||
opti822_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
|
||||
opti822_t *dev = (opti822_t *)priv;
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
|
||||
switch (func)
|
||||
{
|
||||
case 0x04: /* Command Register */
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
switch (func) {
|
||||
case 0x04: /* Command Register */
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
|
||||
case 0x05: /* Command Register */
|
||||
dev->pci_conf[addr] = val & 1;
|
||||
break;
|
||||
case 0x05: /* Command Register */
|
||||
dev->pci_conf[addr] = val & 1;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status Register */
|
||||
dev->pci_conf[addr] |= val & 0xc0;
|
||||
break;
|
||||
case 0x06: /* Status Register */
|
||||
dev->pci_conf[addr] |= val & 0xc0;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status Register */
|
||||
dev->pci_conf[addr] = val & 0xa9;
|
||||
break;
|
||||
case 0x07: /* Status Register */
|
||||
dev->pci_conf[addr] = val & 0xa9;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0xc0;
|
||||
break;
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0xc0;
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0x42:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
case 0x42:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x43:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x44: /* Shadow RAM */
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = (addr == 0x44) ? (val & 0xcb) : val;
|
||||
opti822_shadow(addr, dev);
|
||||
break;
|
||||
case 0x44: /* Shadow RAM */
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = (addr == 0x44) ? (val & 0xcb) : val;
|
||||
opti822_shadow(addr, dev);
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
case 0x70:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
case 0x74:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x77:
|
||||
dev->pci_conf[addr] = val & 0xe7;
|
||||
break;
|
||||
case 0x77:
|
||||
dev->pci_conf[addr] = val & 0xe7;
|
||||
break;
|
||||
|
||||
case 0x78:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x78:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x79:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
case 0x79:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x7a:
|
||||
case 0x7b:
|
||||
case 0x7c:
|
||||
case 0x7d:
|
||||
case 0x7e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x7a:
|
||||
case 0x7b:
|
||||
case 0x7c:
|
||||
case 0x7d:
|
||||
case 0x7e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x7f:
|
||||
dev->pci_conf[addr] = val & 3;
|
||||
break;
|
||||
case 0x7f:
|
||||
dev->pci_conf[addr] = val & 3;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x88: /* PCI IRQ Routing */
|
||||
case 0x89: /* Very hacky implementation. Needs surely a rewrite after */
|
||||
case 0x8a: /* a PCI rework happens. */
|
||||
case 0x8b:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8e:
|
||||
case 0x8f:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (addr % 2)
|
||||
{
|
||||
pci_set_irq_routing(PCI_INTB, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTA, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
pci_set_irq_routing(PCI_INTD, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTC, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
}
|
||||
break;
|
||||
case 0x88: /* PCI IRQ Routing */
|
||||
case 0x89: /* Very hacky implementation. Needs surely a rewrite after */
|
||||
case 0x8a: /* a PCI rework happens. */
|
||||
case 0x8b:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8e:
|
||||
case 0x8f:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (addr % 2) {
|
||||
pci_set_irq_routing(PCI_INTB, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTA, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
} else {
|
||||
pci_set_irq_routing(PCI_INTD, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTC, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
opti822_log("OPTI822: dev->pci_conf[%02x] = %02x\n", addr, dev->pci_conf[addr]);
|
||||
@@ -263,14 +258,14 @@ opti822_write(int func, int addr, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
opti822_read(int func, int addr, void *priv)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *)priv;
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
static void
|
||||
opti822_reset(void *priv)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *)priv;
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x45;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
@@ -291,7 +286,7 @@ opti822_reset(void *priv)
|
||||
static void
|
||||
opti822_close(void *priv)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *)priv;
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -299,7 +294,7 @@ opti822_close(void *priv)
|
||||
static void *
|
||||
opti822_init(const device_t *info)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *)malloc(sizeof(opti822_t));
|
||||
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
|
||||
memset(dev, 0, sizeof(opti822_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_read, opti822_write, dev);
|
||||
@@ -310,15 +305,15 @@ opti822_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti822_device = {
|
||||
.name = "OPTi 82C822 PCIB",
|
||||
.name = "OPTi 82C822 PCIB",
|
||||
.internal_name = "opti822",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = opti822_init,
|
||||
.close = opti822_close,
|
||||
.reset = opti822_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = opti822_init,
|
||||
.close = opti822_close,
|
||||
.reset = opti822_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -32,195 +32,186 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx, forced_green,
|
||||
regs[256],
|
||||
scratch[2];
|
||||
uint8_t idx, forced_green,
|
||||
regs[256],
|
||||
scratch[2];
|
||||
|
||||
smram_t *smram;
|
||||
smram_t *smram;
|
||||
} opti895_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI895_LOG
|
||||
int opti895_do_log = ENABLE_OPTI895_LOG;
|
||||
|
||||
|
||||
static void
|
||||
opti895_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti895_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti895_log(fmt, ...)
|
||||
# define opti895_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
opti895_recalc(opti895_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
if (dev->regs[0x22] & 0x80) {
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
base = 0xd0000 + (i << 14);
|
||||
|
||||
if (dev->regs[0x23] & (1 << i)) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shflags = (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
if (dev->regs[0x26] & 0x40)
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
else {
|
||||
if (dev->regs[0x26] & 0x80)
|
||||
shflags |= (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
else
|
||||
shflags |= MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
if (dev->regs[0x23] & (1 << i)) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shflags = (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
if (dev->regs[0x26] & 0x40)
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
else {
|
||||
if (dev->regs[0x26] & 0x80)
|
||||
shflags |= (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
else
|
||||
shflags |= MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
base = 0xc0000 + (i << 14);
|
||||
|
||||
if (dev->regs[0x26] & (1 << i)) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shflags = (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
if (dev->regs[0x26] & 0x40)
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
else {
|
||||
if (dev->regs[0x26] & 0x80)
|
||||
shflags |= (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
else
|
||||
shflags |= MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
if (dev->regs[0x26] & (1 << i)) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shflags = (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
if (dev->regs[0x26] & 0x40)
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
else {
|
||||
if (dev->regs[0x26] & 0x80)
|
||||
shflags |= (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
else
|
||||
shflags |= MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti895_t *dev = (opti895_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->idx == 0x01) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) ||
|
||||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->idx == 0x01) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
|
||||
switch(dev->idx) {
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
switch (dev->idx) {
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
case 0x2d:
|
||||
opti895_recalc(dev);
|
||||
break;
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
case 0x2d:
|
||||
opti895_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
break;
|
||||
case 0x24:
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0xe0:
|
||||
if (!(val & 0x01))
|
||||
dev->forced_green = 0;
|
||||
break;
|
||||
case 0xe0:
|
||||
if (!(val & 0x01))
|
||||
dev->forced_green = 0;
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
if ((val & 0x08) && (dev->regs[0xe0] & 0x01)) {
|
||||
smi_raise();
|
||||
dev->forced_green = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
if ((val & 0x08) && (dev->regs[0xe0] & 0x01)) {
|
||||
smi_raise();
|
||||
dev->forced_green = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[addr - 0xe1] = val;
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[addr - 0xe1] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti895_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
opti895_t *dev = (opti895_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x23:
|
||||
if (dev->idx == 0x01)
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) ||
|
||||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
ret = dev->regs[dev->idx];
|
||||
if (dev->idx == 0xe0)
|
||||
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[addr - 0xe1];
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->idx == 0x01)
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
ret = dev->regs[dev->idx];
|
||||
if (dev->idx == 0xe0)
|
||||
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[addr - 0xe1];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti895_close(void *priv)
|
||||
{
|
||||
@@ -231,7 +222,6 @@ opti895_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti895_init(const device_t *info)
|
||||
{
|
||||
@@ -273,29 +263,29 @@ opti895_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t opti802g_device = {
|
||||
.name = "OPTi 82C802G",
|
||||
.name = "OPTi 82C802G",
|
||||
.internal_name = "opti802g",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti895_device = {
|
||||
.name = "OPTi 82C895",
|
||||
.name = "OPTi 82C895",
|
||||
.internal_name = "opti895",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
1223
src/chipset/scamp.c
1223
src/chipset/scamp.c
File diff suppressed because it is too large
Load Diff
2242
src/chipset/scat.c
2242
src/chipset/scat.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,27 +12,25 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cur_reg, tries,
|
||||
regs[258];
|
||||
uint8_t cur_reg, tries,
|
||||
regs[258];
|
||||
} rabbit_t;
|
||||
|
||||
|
||||
static void
|
||||
rabbit_recalcmapping(rabbit_t *dev)
|
||||
{
|
||||
uint32_t shread, shwrite;
|
||||
uint32_t shflags = 0;
|
||||
|
||||
shread = !!(dev->regs[0x101] & 0x40);
|
||||
shread = !!(dev->regs[0x101] & 0x40);
|
||||
shwrite = !!(dev->regs[0x100] & 0x02);
|
||||
|
||||
shflags = shread ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
shflags |= shwrite ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
|
||||
shadowbios = !!shread;
|
||||
shadowbios = !!shread;
|
||||
shadowbios_write = !!shwrite;
|
||||
|
||||
#ifdef USE_SHADOW_C0000
|
||||
@@ -42,79 +40,76 @@ rabbit_recalcmapping(rabbit_t *dev)
|
||||
#endif
|
||||
|
||||
switch (dev->regs[0x100] & 0x09) {
|
||||
case 0x01:
|
||||
case 0x01:
|
||||
/* The one BIOS we use seems to use something else to control C0000-DFFFF shadow,
|
||||
no idea what. */
|
||||
#ifdef USE_SHADOW_C0000
|
||||
/* 64K at 0C0000-0CFFFF */
|
||||
mem_set_mem_state(0x000c0000, 0x00010000, shflags);
|
||||
/* FALLTHROUGH */
|
||||
/* 64K at 0C0000-0CFFFF */
|
||||
mem_set_mem_state(0x000c0000, 0x00010000, shflags);
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case 0x00:
|
||||
/* 64K at 0F0000-0FFFFF */
|
||||
mem_set_mem_state(0x000f0000, 0x00010000, shflags);
|
||||
break;
|
||||
case 0x00:
|
||||
/* 64K at 0F0000-0FFFFF */
|
||||
mem_set_mem_state(0x000f0000, 0x00010000, shflags);
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
case 0x09:
|
||||
#ifdef USE_SHADOW_C0000
|
||||
/* 128K at 0C0000-0DFFFF */
|
||||
mem_set_mem_state(0x000c0000, 0x00020000, shflags);
|
||||
/* FALLTHROUGH */
|
||||
/* 128K at 0C0000-0DFFFF */
|
||||
mem_set_mem_state(0x000c0000, 0x00020000, shflags);
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case 0x08:
|
||||
/* 128K at 0E0000-0FFFFF */
|
||||
mem_set_mem_state(0x000e0000, 0x00020000, shflags);
|
||||
break;
|
||||
case 0x08:
|
||||
/* 128K at 0E0000-0FFFFF */
|
||||
mem_set_mem_state(0x000e0000, 0x00020000, shflags);
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rabbit_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
rabbit_t *dev = (rabbit_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->cur_reg = val;
|
||||
dev->tries = 0;
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->cur_reg == 0x83) {
|
||||
if (dev->tries < 0x02) {
|
||||
dev->regs[dev->tries++ | 0x100] = val;
|
||||
if (dev->tries == 0x02)
|
||||
rabbit_recalcmapping(dev);
|
||||
}
|
||||
} else
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->cur_reg = val;
|
||||
dev->tries = 0;
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->cur_reg == 0x83) {
|
||||
if (dev->tries < 0x02) {
|
||||
dev->regs[dev->tries++ | 0x100] = val;
|
||||
if (dev->tries == 0x02)
|
||||
rabbit_recalcmapping(dev);
|
||||
}
|
||||
} else
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
rabbit_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
rabbit_t *dev = (rabbit_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x23:
|
||||
if (dev->cur_reg == 0x83) {
|
||||
if (dev->tries < 0x02)
|
||||
ret = dev->regs[dev->tries++ | 0x100];
|
||||
} else
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->cur_reg == 0x83) {
|
||||
if (dev->tries < 0x02)
|
||||
ret = dev->regs[dev->tries++ | 0x100];
|
||||
} else
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rabbit_close(void *priv)
|
||||
{
|
||||
@@ -123,7 +118,6 @@ rabbit_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
rabbit_init(const device_t *info)
|
||||
{
|
||||
@@ -136,15 +130,15 @@ rabbit_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t rabbit_device = {
|
||||
.name = "SiS Rabbit",
|
||||
.name = "SiS Rabbit",
|
||||
.internal_name = "rabbit",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = rabbit_init,
|
||||
.close = rabbit_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = rabbit_init,
|
||||
.close = rabbit_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -38,39 +38,34 @@
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
|
||||
typedef struct sis_85c496_t
|
||||
{
|
||||
uint8_t cur_reg, rmsmiblk_count,
|
||||
regs[127],
|
||||
pci_conf[256];
|
||||
smram_t *smram;
|
||||
pc_timer_t rmsmiblk_timer;
|
||||
port_92_t * port_92;
|
||||
nvr_t * nvr;
|
||||
typedef struct sis_85c496_t {
|
||||
uint8_t cur_reg, rmsmiblk_count,
|
||||
regs[127],
|
||||
pci_conf[256];
|
||||
smram_t *smram;
|
||||
pc_timer_t rmsmiblk_timer;
|
||||
port_92_t *port_92;
|
||||
nvr_t *nvr;
|
||||
} sis_85c496_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_SIS_85C496_LOG
|
||||
int sis_85c496_do_log = ENABLE_SIS_85C496_LOG;
|
||||
|
||||
|
||||
void
|
||||
sis_85c496_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_85c496_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define sis_85c496_log(fmt, ...)
|
||||
# define sis_85c496_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
sis_85c497_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -79,75 +74,74 @@ sis_85c497_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
sis_85c496_log("[%04X:%08X] ISA Write %02X to %04X\n", CS, cpu_state.pc, val, port);
|
||||
|
||||
if (port == 0x22)
|
||||
dev->cur_reg = val;
|
||||
else if (port == 0x23) switch (dev->cur_reg) {
|
||||
case 0x01: /* Built-in 206 Timing Control */
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
case 0x70: /* ISA Bus Clock Selection */
|
||||
dev->regs[dev->cur_reg] = val & 0xc0;
|
||||
break;
|
||||
case 0x71: /* ISA Bus Timing Control */
|
||||
dev->regs[dev->cur_reg] = val & 0xf6;
|
||||
break;
|
||||
case 0x72: case 0x76: /* SMOUT */
|
||||
case 0x74: /* BIOS Timer */
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
case 0x73: /* BIOS Timer */
|
||||
dev->regs[dev->cur_reg] = val & 0xfd;
|
||||
break;
|
||||
case 0x75: /* DMA / Deturbo Control */
|
||||
dev->regs[dev->cur_reg] = val & 0xfc;
|
||||
dma_set_mask((val & 0x80) ? 0xffffffff : 0x00ffffff);
|
||||
break;
|
||||
}
|
||||
dev->cur_reg = val;
|
||||
else if (port == 0x23)
|
||||
switch (dev->cur_reg) {
|
||||
case 0x01: /* Built-in 206 Timing Control */
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
case 0x70: /* ISA Bus Clock Selection */
|
||||
dev->regs[dev->cur_reg] = val & 0xc0;
|
||||
break;
|
||||
case 0x71: /* ISA Bus Timing Control */
|
||||
dev->regs[dev->cur_reg] = val & 0xf6;
|
||||
break;
|
||||
case 0x72:
|
||||
case 0x76: /* SMOUT */
|
||||
case 0x74: /* BIOS Timer */
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
case 0x73: /* BIOS Timer */
|
||||
dev->regs[dev->cur_reg] = val & 0xfd;
|
||||
break;
|
||||
case 0x75: /* DMA / Deturbo Control */
|
||||
dev->regs[dev->cur_reg] = val & 0xfc;
|
||||
dma_set_mask((val & 0x80) ? 0xffffffff : 0x00ffffff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c497_isa_read(uint16_t port, void *priv)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port == 0x23)
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
else if (port == 0x33)
|
||||
ret = 0x3c /*random_generate()*/;
|
||||
ret = 0x3c /*random_generate()*/;
|
||||
|
||||
sis_85c496_log("[%04X:%08X] ISA Read %02X from %04X\n", CS, cpu_state.pc, ret, port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c496_recalcmapping(sis_85c496_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
base = 0xc0000 + (i << 15);
|
||||
|
||||
if (dev->pci_conf[0x44] & (1 << i)) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->pci_conf[0x45] & 0x02);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->pci_conf[0x45] & 0x01);
|
||||
shflags = (dev->pci_conf[0x45] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
shflags |= (dev->pci_conf[0x45] & 0x01) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state_both(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
if (dev->pci_conf[0x44] & (1 << i)) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->pci_conf[0x45] & 0x02);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->pci_conf[0x45] & 0x01);
|
||||
shflags = (dev->pci_conf[0x45] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
shflags |= (dev->pci_conf[0x45] & 0x01) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state_both(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c496_ide_handler(sis_85c496_t *dev)
|
||||
{
|
||||
@@ -160,308 +154,330 @@ sis_85c496_ide_handler(sis_85c496_t *dev)
|
||||
ide_sec_disable();
|
||||
|
||||
if (ide_cfg[1] & 0x02) {
|
||||
ide_set_base(0, 0x0170);
|
||||
ide_set_side(0, 0x0376);
|
||||
ide_set_base(1, 0x01f0);
|
||||
ide_set_side(1, 0x03f6);
|
||||
ide_set_base(0, 0x0170);
|
||||
ide_set_side(0, 0x0376);
|
||||
ide_set_base(1, 0x01f0);
|
||||
ide_set_side(1, 0x03f6);
|
||||
|
||||
if (ide_cfg[1] & 0x01) {
|
||||
if (!(ide_cfg[0] & 0x40))
|
||||
ide_pri_enable();
|
||||
if (!(ide_cfg[0] & 0x80))
|
||||
ide_sec_enable();
|
||||
}
|
||||
if (ide_cfg[1] & 0x01) {
|
||||
if (!(ide_cfg[0] & 0x40))
|
||||
ide_pri_enable();
|
||||
if (!(ide_cfg[0] & 0x80))
|
||||
ide_sec_enable();
|
||||
}
|
||||
} else {
|
||||
ide_set_base(0, 0x01f0);
|
||||
ide_set_side(0, 0x03f6);
|
||||
ide_set_base(1, 0x0170);
|
||||
ide_set_side(1, 0x0376);
|
||||
ide_set_base(0, 0x01f0);
|
||||
ide_set_side(0, 0x03f6);
|
||||
ide_set_base(1, 0x0170);
|
||||
ide_set_side(1, 0x0376);
|
||||
|
||||
if (ide_cfg[1] & 0x01) {
|
||||
if (!(ide_cfg[0] & 0x40))
|
||||
ide_sec_enable();
|
||||
if (!(ide_cfg[0] & 0x80))
|
||||
ide_pri_enable();
|
||||
}
|
||||
if (ide_cfg[1] & 0x01) {
|
||||
if (!(ide_cfg[0] & 0x40))
|
||||
ide_sec_enable();
|
||||
if (!(ide_cfg[0] & 0x80))
|
||||
ide_pri_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */
|
||||
static void
|
||||
sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
uint8_t old, valxor;
|
||||
uint8_t smm_irq[4] = { 10, 11, 12, 15 };
|
||||
uint32_t host_base, ram_base, size;
|
||||
uint8_t old, valxor;
|
||||
uint8_t smm_irq[4] = { 10, 11, 12, 15 };
|
||||
uint32_t host_base, ram_base, size;
|
||||
|
||||
old = dev->pci_conf[addr];
|
||||
old = dev->pci_conf[addr];
|
||||
valxor = (dev->pci_conf[addr]) ^ val;
|
||||
|
||||
sis_85c496_log("[%04X:%08X] PCI Write %02X to %02X:%02X\n", CS, cpu_state.pc, val, func, addr);
|
||||
|
||||
switch (addr) {
|
||||
/* PCI Configuration Header Registers (00h ~ 3Fh) */
|
||||
case 0x04: /* PCI Device Command */
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
case 0x05: /* PCI Device Command */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0x07: /* Device Status */
|
||||
dev->pci_conf[addr] &= ~(val & 0xf1);
|
||||
break;
|
||||
/* PCI Configuration Header Registers (00h ~ 3Fh) */
|
||||
case 0x04: /* PCI Device Command */
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
case 0x05: /* PCI Device Command */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0x07: /* Device Status */
|
||||
dev->pci_conf[addr] &= ~(val & 0xf1);
|
||||
break;
|
||||
|
||||
/* 86C496 Specific Registers (40h ~ 7Fh) */
|
||||
case 0x40: /* CPU Configuration */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0x41: /* DRAM Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x42: /* Cache Configure */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = (val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x43: /* Cache Configure */
|
||||
dev->pci_conf[addr] = val & 0x8f;
|
||||
break;
|
||||
case 0x44: /* Shadow Configure */
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0xff) {
|
||||
sis_85c496_recalcmapping(dev);
|
||||
if (((old & 0xf0) == 0xf0) && ((val & 0xf0) == 0x30))
|
||||
flushmmucache_nopc();
|
||||
else if (((old & 0xf0) == 0xf0) && ((val & 0xf0) == 0x00))
|
||||
flushmmucache_nopc();
|
||||
else
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
case 0x45: /* Shadow Configure */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
if (valxor & 0x03)
|
||||
sis_85c496_recalcmapping(dev);
|
||||
break;
|
||||
case 0x46: /* Cacheable Control */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x47: /* 85C496 Address Decoder */
|
||||
dev->pci_conf[addr] = val & 0x1f;
|
||||
break;
|
||||
case 0x48: case 0x49: case 0x4a: case 0x4b: /* DRAM Boundary */
|
||||
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
||||
// dev->pci_conf[addr] = val;
|
||||
spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1);
|
||||
break;
|
||||
case 0x50: case 0x51: /* Exclusive Area 0 Setup */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x52: case 0x53: /* Exclusive Area 1 Setup */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x54: /* Exclusive Area 2 Setup */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x55: /* Exclusive Area 3 Setup */
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0x56: /* PCI / Keyboard Configure */
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0x02) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x02)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
case 0x57: /* Output Pin Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x58: /* Build-in IDE Controller / VESA Bus Configuration */
|
||||
dev->pci_conf[addr] = val & 0xd7;
|
||||
if (valxor & 0xc0)
|
||||
sis_85c496_ide_handler(dev);
|
||||
break;
|
||||
case 0x59: /* Build-in IDE Controller / VESA Bus Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0x03)
|
||||
sis_85c496_ide_handler(dev);
|
||||
break;
|
||||
case 0x5a: /* SMRAM Remapping Configuration */
|
||||
dev->pci_conf[addr] = val & 0xbe;
|
||||
if (valxor & 0x3e) {
|
||||
unmask_a20_in_smm = !!(val & 0x20);
|
||||
/* 86C496 Specific Registers (40h ~ 7Fh) */
|
||||
case 0x40: /* CPU Configuration */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0x41: /* DRAM Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x42: /* Cache Configure */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = (val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x43: /* Cache Configure */
|
||||
dev->pci_conf[addr] = val & 0x8f;
|
||||
break;
|
||||
case 0x44: /* Shadow Configure */
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0xff) {
|
||||
sis_85c496_recalcmapping(dev);
|
||||
if (((old & 0xf0) == 0xf0) && ((val & 0xf0) == 0x30))
|
||||
flushmmucache_nopc();
|
||||
else if (((old & 0xf0) == 0xf0) && ((val & 0xf0) == 0x00))
|
||||
flushmmucache_nopc();
|
||||
else
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
case 0x45: /* Shadow Configure */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
if (valxor & 0x03)
|
||||
sis_85c496_recalcmapping(dev);
|
||||
break;
|
||||
case 0x46: /* Cacheable Control */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x47: /* 85C496 Address Decoder */
|
||||
dev->pci_conf[addr] = val & 0x1f;
|
||||
break;
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x4b: /* DRAM Boundary */
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
// dev->pci_conf[addr] = val;
|
||||
spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1);
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x51: /* Exclusive Area 0 Setup */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x52:
|
||||
case 0x53: /* Exclusive Area 1 Setup */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x54: /* Exclusive Area 2 Setup */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x55: /* Exclusive Area 3 Setup */
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0x56: /* PCI / Keyboard Configure */
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0x02) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x02)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
case 0x57: /* Output Pin Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x58: /* Build-in IDE Controller / VESA Bus Configuration */
|
||||
dev->pci_conf[addr] = val & 0xd7;
|
||||
if (valxor & 0xc0)
|
||||
sis_85c496_ide_handler(dev);
|
||||
break;
|
||||
case 0x59: /* Build-in IDE Controller / VESA Bus Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0x03)
|
||||
sis_85c496_ide_handler(dev);
|
||||
break;
|
||||
case 0x5a: /* SMRAM Remapping Configuration */
|
||||
dev->pci_conf[addr] = val & 0xbe;
|
||||
if (valxor & 0x3e) {
|
||||
unmask_a20_in_smm = !!(val & 0x20);
|
||||
|
||||
smram_disable_all();
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 0x02) {
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000a0000;
|
||||
size = 0x00010000;
|
||||
switch ((val >> 3) & 0x03) {
|
||||
case 0x00:
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x01:
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 0x02:
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x03:
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
}
|
||||
if (val & 0x02) {
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000a0000;
|
||||
size = 0x00010000;
|
||||
switch ((val >> 3) & 0x03) {
|
||||
case 0x00:
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x01:
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 0x02:
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x03:
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
}
|
||||
|
||||
smram_enable(dev->smram, host_base, ram_base, size,
|
||||
((val & 0x06) == 0x06), (val & 0x02));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x5b: /* Programmable I/O Traps Configure */
|
||||
case 0x5c: case 0x5d: /* Programmable I/O Trap 0 Base */
|
||||
case 0x5e: case 0x5f: /* Programmable I/O Trap 0 Base */
|
||||
case 0x60: case 0x61: /* IDE Controller Channel 0 Configuration */
|
||||
case 0x62: case 0x63: /* IDE Controller Channel 1 Configuration */
|
||||
case 0x64: case 0x65: /* Exclusive Area 3 Setup */
|
||||
case 0x66: /* EDO DRAM Configuration */
|
||||
case 0x68: case 0x69: /* Asymmetry DRAM Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x67: /* Miscellaneous Control */
|
||||
dev->pci_conf[addr] = val & 0xf9;
|
||||
if (valxor & 0x60)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40));
|
||||
break;
|
||||
smram_enable(dev->smram, host_base, ram_base, size,
|
||||
((val & 0x06) == 0x06), (val & 0x02));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x5b: /* Programmable I/O Traps Configure */
|
||||
case 0x5c:
|
||||
case 0x5d: /* Programmable I/O Trap 0 Base */
|
||||
case 0x5e:
|
||||
case 0x5f: /* Programmable I/O Trap 0 Base */
|
||||
case 0x60:
|
||||
case 0x61: /* IDE Controller Channel 0 Configuration */
|
||||
case 0x62:
|
||||
case 0x63: /* IDE Controller Channel 1 Configuration */
|
||||
case 0x64:
|
||||
case 0x65: /* Exclusive Area 3 Setup */
|
||||
case 0x66: /* EDO DRAM Configuration */
|
||||
case 0x68:
|
||||
case 0x69: /* Asymmetry DRAM Configuration */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x67: /* Miscellaneous Control */
|
||||
dev->pci_conf[addr] = val & 0xf9;
|
||||
if (valxor & 0x60)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40));
|
||||
break;
|
||||
|
||||
/* 86C497 Specific Registers (80h ~ FFh) */
|
||||
case 0x80: /* PMU Configuration */
|
||||
case 0x85: /* STPCLK# Event Control */
|
||||
case 0x86: case 0x87: /* STPCLK# Deassertion IRQ Selection */
|
||||
case 0x89: /* Fast Timer Count */
|
||||
case 0x8a: /* Generic Timer Count */
|
||||
case 0x8b: /* Slow Timer Count */
|
||||
case 0x8e: /* Clock Throttling On Timer Count */
|
||||
case 0x8f: /* Clock Throttling Off Timer Count */
|
||||
case 0x90: /* Clock Throttling On Timer Reload Condition */
|
||||
case 0x92: /* Fast Timer Reload Condition */
|
||||
case 0x94: /* Generic Timer Reload Condition */
|
||||
case 0x96: /* Slow Timer Reload Condition */
|
||||
case 0x98: case 0x99: /* Fast Timer Reload IRQ Selection */
|
||||
case 0x9a: case 0x9b: /* Generic Timer Reload IRQ Selection */
|
||||
case 0x9c: case 0x9d: /* Slow Timer Reload IRQ Selection */
|
||||
case 0xa2: /* SMI Request Status Selection */
|
||||
case 0xa4: case 0xa5: /* SMI Request IRQ Selection */
|
||||
case 0xa6: case 0xa7: /* Clock Throttlign On Timer Reload IRQ Selection */
|
||||
case 0xa8: /* GPIO Control */
|
||||
case 0xaa: /* GPIO DeBounce Count */
|
||||
case 0xd2: /* Exclusive Area 2 Base Address */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x81: /* PMU CPU Type Configuration */
|
||||
dev->pci_conf[addr] = val & 0x9f;
|
||||
break;
|
||||
case 0x88: /* Timer Control */
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x8d: /* RMSMIBLK Timer Count */
|
||||
dev->pci_conf[addr] = val;
|
||||
dev->rmsmiblk_count = val;
|
||||
timer_stop(&dev->rmsmiblk_timer);
|
||||
if (val >= 0x02)
|
||||
timer_on_auto(&dev->rmsmiblk_timer, 35.0);
|
||||
break;
|
||||
case 0x91: /* Clock Throttling On Timer Reload Condition */
|
||||
case 0x93: /* Fast Timer Reload Condition */
|
||||
case 0x95: /* Generic Timer Reload Condition */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0x97: /* Slow Timer Reload Condition */
|
||||
dev->pci_conf[addr] = val & 0xc3;
|
||||
break;
|
||||
case 0x9e: /* Soft-SMI Generation / RMSMIBLK Trigger */
|
||||
if (!smi_block && (val & 0x01) && (dev->pci_conf[0x80] & 0x80) && (dev->pci_conf[0xa2] & 0x10)) {
|
||||
if (dev->pci_conf[0x80] & 0x10)
|
||||
picint(1 << smm_irq[dev->pci_conf[0x81] & 0x03]);
|
||||
else
|
||||
smi_raise();
|
||||
smi_block = 1;
|
||||
dev->pci_conf[0xa0] |= 0x10;
|
||||
}
|
||||
if (val & 0x02) {
|
||||
timer_stop(&dev->rmsmiblk_timer);
|
||||
if (dev->rmsmiblk_count >= 0x02)
|
||||
timer_on_auto(&dev->rmsmiblk_timer, 35.0);
|
||||
}
|
||||
break;
|
||||
case 0xa0: case 0xa1: /* SMI Request Status */
|
||||
dev->pci_conf[addr] &= ~val;
|
||||
break;
|
||||
case 0xa3: /* SMI Request Status Selection */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0xa9: /* GPIO SMI Request Status */
|
||||
dev->pci_conf[addr] = ~(val & 0x03);
|
||||
break;
|
||||
case 0xc0: /* PCI INTA# -to-IRQ Link */
|
||||
case 0xc1: /* PCI INTB# -to-IRQ Link */
|
||||
case 0xc2: /* PCI INTC# -to-IRQ Link */
|
||||
case 0xc3: /* PCI INTD# -to-IRQ Link */
|
||||
dev->pci_conf[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0xc6: /* 85C497 Post / INIT Configuration */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0xc8: case 0xc9: case 0xca: case 0xcb: /* Mail Box */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd0: /* ISA BIOS Configuration */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
case 0xd1: /* ISA Address Decoder */
|
||||
if (dev->pci_conf[0xd0] & 0x01)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd3: /* Exclusive Area 2 Base Address */
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0xd4: /* Miscellaneous Configuration */
|
||||
dev->pci_conf[addr] = val & 0x6e;
|
||||
nvr_bank_set(0, !!(val & 0x40), dev->nvr);
|
||||
break;
|
||||
/* 86C497 Specific Registers (80h ~ FFh) */
|
||||
case 0x80: /* PMU Configuration */
|
||||
case 0x85: /* STPCLK# Event Control */
|
||||
case 0x86:
|
||||
case 0x87: /* STPCLK# Deassertion IRQ Selection */
|
||||
case 0x89: /* Fast Timer Count */
|
||||
case 0x8a: /* Generic Timer Count */
|
||||
case 0x8b: /* Slow Timer Count */
|
||||
case 0x8e: /* Clock Throttling On Timer Count */
|
||||
case 0x8f: /* Clock Throttling Off Timer Count */
|
||||
case 0x90: /* Clock Throttling On Timer Reload Condition */
|
||||
case 0x92: /* Fast Timer Reload Condition */
|
||||
case 0x94: /* Generic Timer Reload Condition */
|
||||
case 0x96: /* Slow Timer Reload Condition */
|
||||
case 0x98:
|
||||
case 0x99: /* Fast Timer Reload IRQ Selection */
|
||||
case 0x9a:
|
||||
case 0x9b: /* Generic Timer Reload IRQ Selection */
|
||||
case 0x9c:
|
||||
case 0x9d: /* Slow Timer Reload IRQ Selection */
|
||||
case 0xa2: /* SMI Request Status Selection */
|
||||
case 0xa4:
|
||||
case 0xa5: /* SMI Request IRQ Selection */
|
||||
case 0xa6:
|
||||
case 0xa7: /* Clock Throttlign On Timer Reload IRQ Selection */
|
||||
case 0xa8: /* GPIO Control */
|
||||
case 0xaa: /* GPIO DeBounce Count */
|
||||
case 0xd2: /* Exclusive Area 2 Base Address */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x81: /* PMU CPU Type Configuration */
|
||||
dev->pci_conf[addr] = val & 0x9f;
|
||||
break;
|
||||
case 0x88: /* Timer Control */
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x8d: /* RMSMIBLK Timer Count */
|
||||
dev->pci_conf[addr] = val;
|
||||
dev->rmsmiblk_count = val;
|
||||
timer_stop(&dev->rmsmiblk_timer);
|
||||
if (val >= 0x02)
|
||||
timer_on_auto(&dev->rmsmiblk_timer, 35.0);
|
||||
break;
|
||||
case 0x91: /* Clock Throttling On Timer Reload Condition */
|
||||
case 0x93: /* Fast Timer Reload Condition */
|
||||
case 0x95: /* Generic Timer Reload Condition */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0x97: /* Slow Timer Reload Condition */
|
||||
dev->pci_conf[addr] = val & 0xc3;
|
||||
break;
|
||||
case 0x9e: /* Soft-SMI Generation / RMSMIBLK Trigger */
|
||||
if (!smi_block && (val & 0x01) && (dev->pci_conf[0x80] & 0x80) && (dev->pci_conf[0xa2] & 0x10)) {
|
||||
if (dev->pci_conf[0x80] & 0x10)
|
||||
picint(1 << smm_irq[dev->pci_conf[0x81] & 0x03]);
|
||||
else
|
||||
smi_raise();
|
||||
smi_block = 1;
|
||||
dev->pci_conf[0xa0] |= 0x10;
|
||||
}
|
||||
if (val & 0x02) {
|
||||
timer_stop(&dev->rmsmiblk_timer);
|
||||
if (dev->rmsmiblk_count >= 0x02)
|
||||
timer_on_auto(&dev->rmsmiblk_timer, 35.0);
|
||||
}
|
||||
break;
|
||||
case 0xa0:
|
||||
case 0xa1: /* SMI Request Status */
|
||||
dev->pci_conf[addr] &= ~val;
|
||||
break;
|
||||
case 0xa3: /* SMI Request Status Selection */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0xa9: /* GPIO SMI Request Status */
|
||||
dev->pci_conf[addr] = ~(val & 0x03);
|
||||
break;
|
||||
case 0xc0: /* PCI INTA# -to-IRQ Link */
|
||||
case 0xc1: /* PCI INTB# -to-IRQ Link */
|
||||
case 0xc2: /* PCI INTC# -to-IRQ Link */
|
||||
case 0xc3: /* PCI INTD# -to-IRQ Link */
|
||||
dev->pci_conf[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0xc6: /* 85C497 Post / INIT Configuration */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0xc8:
|
||||
case 0xc9:
|
||||
case 0xca:
|
||||
case 0xcb: /* Mail Box */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd0: /* ISA BIOS Configuration */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
case 0xd1: /* ISA Address Decoder */
|
||||
if (dev->pci_conf[0xd0] & 0x01)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd3: /* Exclusive Area 2 Base Address */
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0xd4: /* Miscellaneous Configuration */
|
||||
dev->pci_conf[addr] = val & 0x6e;
|
||||
nvr_bank_set(0, !!(val & 0x40), dev->nvr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c49x_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
uint8_t ret = dev->pci_conf[addr];
|
||||
uint8_t ret = dev->pci_conf[addr];
|
||||
|
||||
switch (addr) {
|
||||
case 0xa0:
|
||||
ret &= 0x10;
|
||||
break;
|
||||
case 0xa1:
|
||||
ret = 0x00;
|
||||
break;
|
||||
case 0x82: /*Port 22h Mirror*/
|
||||
ret = dev->cur_reg;
|
||||
break;
|
||||
case 0x83: /*Port 70h Mirror*/
|
||||
ret = inb(0x70);
|
||||
break;
|
||||
case 0xa0:
|
||||
ret &= 0x10;
|
||||
break;
|
||||
case 0xa1:
|
||||
ret = 0x00;
|
||||
break;
|
||||
case 0x82: /*Port 22h Mirror*/
|
||||
ret = dev->cur_reg;
|
||||
break;
|
||||
case 0x83: /*Port 70h Mirror*/
|
||||
ret = inb(0x70);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_85c496_log("[%04X:%08X] PCI Read %02X from %02X:%02X\n", CS, cpu_state.pc, ret, func, addr);
|
||||
@@ -469,7 +485,6 @@ sis_85c49x_pci_read(int func, int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c496_rmsmiblk_count(void *priv)
|
||||
{
|
||||
@@ -478,14 +493,13 @@ sis_85c496_rmsmiblk_count(void *priv)
|
||||
dev->rmsmiblk_count--;
|
||||
|
||||
if (dev->rmsmiblk_count == 1) {
|
||||
smi_block = 0;
|
||||
dev->rmsmiblk_count = 0;
|
||||
timer_stop(&dev->rmsmiblk_timer);
|
||||
smi_block = 0;
|
||||
dev->rmsmiblk_count = 0;
|
||||
timer_stop(&dev->rmsmiblk_timer);
|
||||
} else
|
||||
timer_on_auto(&dev->rmsmiblk_timer, 35.0);
|
||||
timer_on_auto(&dev->rmsmiblk_timer, 35.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c497_isa_reset(sis_85c496_t *dev)
|
||||
{
|
||||
@@ -499,21 +513,20 @@ sis_85c497_isa_reset(sis_85c496_t *dev)
|
||||
dma_set_mask(0x00ffffff);
|
||||
|
||||
io_removehandler(0x0022, 0x0002,
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
io_removehandler(0x0033, 0x0001,
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0022, 0x0002,
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0033, 0x0001,
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c496_reset(void *priv)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
sis_85c49x_pci_write(0, 0x44, 0x00, dev);
|
||||
sis_85c49x_pci_write(0, 0x45, 0x00, dev);
|
||||
@@ -523,7 +536,7 @@ sis_85c496_reset(void *priv)
|
||||
// sis_85c49x_pci_write(0, 0x5a, 0x06, dev);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev);
|
||||
sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev);
|
||||
|
||||
sis_85c49x_pci_write(0, 0x80, 0x00, dev);
|
||||
sis_85c49x_pci_write(0, 0x81, 0x00, dev);
|
||||
@@ -553,20 +566,19 @@ sis_85c496_reset(void *priv)
|
||||
sis_85c497_isa_reset(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c496_close(void *p)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *)p;
|
||||
sis_85c496_t *dev = (sis_85c496_t *) p;
|
||||
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*sis_85c496_init(const device_t *info)
|
||||
*
|
||||
sis_85c496_init(const device_t *info)
|
||||
{
|
||||
sis_85c496_t *dev = malloc(sizeof(sis_85c496_t));
|
||||
memset(dev, 0x00, sizeof(sis_85c496_t));
|
||||
@@ -574,21 +586,21 @@ static void
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* PCI Configuration Header Registers (00h ~ 3Fh) */
|
||||
dev->pci_conf[0x00] = 0x39; /* SiS */
|
||||
dev->pci_conf[0x00] = 0x39; /* SiS */
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x96; /* 496/497 */
|
||||
dev->pci_conf[0x02] = 0x96; /* 496/497 */
|
||||
dev->pci_conf[0x03] = 0x04;
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x06] = 0x80;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x02; /* Device revision */
|
||||
dev->pci_conf[0x09] = 0x00; /* Device class (PCI bridge) */
|
||||
dev->pci_conf[0x08] = 0x02; /* Device revision */
|
||||
dev->pci_conf[0x09] = 0x00; /* Device class (PCI bridge) */
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
|
||||
/* 86C496 Specific Registers (40h ~ 7Fh) */
|
||||
|
||||
/* 86C497 Specific Registers (80h ~ FFh) */
|
||||
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
|
||||
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
|
||||
dev->pci_conf[0xd1] = 0xff;
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
|
||||
@@ -605,9 +617,9 @@ static void
|
||||
ide_sec_disable();
|
||||
|
||||
if (info->local)
|
||||
dev->nvr = device_add(&ami_1994_nvr_device);
|
||||
dev->nvr = device_add(&ami_1994_nvr_device);
|
||||
else
|
||||
dev->nvr = device_add(&at_nvr_device);
|
||||
dev->nvr = device_add(&at_nvr_device);
|
||||
|
||||
dma_high_page_init();
|
||||
|
||||
@@ -619,29 +631,29 @@ static void
|
||||
}
|
||||
|
||||
const device_t sis_85c496_device = {
|
||||
.name = "SiS 85c496/85c497",
|
||||
.name = "SiS 85c496/85c497",
|
||||
.internal_name = "sis_85c496",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_85c496_init,
|
||||
.close = sis_85c496_close,
|
||||
.reset = sis_85c496_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_85c496_init,
|
||||
.close = sis_85c496_close,
|
||||
.reset = sis_85c496_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_85c496_ls486e_device = {
|
||||
.name = "SiS 85c496/85c497 (Lucky Star LS-486E)",
|
||||
.name = "SiS 85c496/85c497 (Lucky Star LS-486E)",
|
||||
.internal_name = "sis_85c496_ls486e",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = sis_85c496_init,
|
||||
.close = sis_85c496_close,
|
||||
.reset = sis_85c496_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = sis_85c496_init,
|
||||
.close = sis_85c496_close,
|
||||
.reset = sis_85c496_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -33,278 +33,275 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cur_reg, tries,
|
||||
reg_base, reg_last,
|
||||
reg_00, is_471,
|
||||
regs[39], scratch[2];
|
||||
uint32_t mem_state[8];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
uint8_t cur_reg, tries,
|
||||
reg_base, reg_last,
|
||||
reg_00, is_471,
|
||||
regs[39], scratch[2];
|
||||
uint32_t mem_state[8];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
} sis_85c4xx_t;
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
{
|
||||
uint32_t base, n = 0;
|
||||
uint32_t base, n = 0;
|
||||
uint32_t i, shflags = 0;
|
||||
uint32_t readext, writeext;
|
||||
uint8_t romcs = 0xc0, cur_romcs;
|
||||
uint8_t romcs = 0xc0, cur_romcs;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
if (dev->regs[0x03] & 0x40)
|
||||
romcs |= 0x01;
|
||||
romcs |= 0x01;
|
||||
if (dev->regs[0x03] & 0x80)
|
||||
romcs |= 0x30;
|
||||
romcs |= 0x30;
|
||||
if (dev->regs[0x08] & 0x04)
|
||||
romcs |= 0x02;
|
||||
romcs |= 0x02;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
cur_romcs = romcs & (1 << i);
|
||||
readext = cur_romcs ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
writeext = cur_romcs ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
base = 0xc0000 + (i << 15);
|
||||
cur_romcs = romcs & (1 << i);
|
||||
readext = cur_romcs ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
writeext = cur_romcs ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((i > 5) || (dev->regs[0x02] & (1 << i))) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : readext;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? writeext : MEM_WRITE_INTERNAL;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
if ((base >= 0xf0000) && (dev->mem_state[i] & MEM_READ_INTERNAL) && !(shflags & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(base, base + 0x7fff);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
} else {
|
||||
shflags = readext | writeext;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
}
|
||||
if ((i > 5) || (dev->regs[0x02] & (1 << i))) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : readext;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? writeext : MEM_WRITE_INTERNAL;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
if ((base >= 0xf0000) && (dev->mem_state[i] & MEM_READ_INTERNAL) && !(shflags & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(base, base + 0x7fff);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
} else {
|
||||
shflags = readext | writeext;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_sw_smi_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
|
||||
if (dev->regs[0x18] & 0x02) {
|
||||
if (dev->regs[0x0b] & 0x10)
|
||||
smi_raise();
|
||||
else
|
||||
picint(1 << ((dev->regs[0x0b] & 0x08) ? 15 : 12));
|
||||
soft_reset_mask = 1;
|
||||
dev->regs[0x19] |= 0x02;
|
||||
if (dev->regs[0x0b] & 0x10)
|
||||
smi_raise();
|
||||
else
|
||||
picint(1 << ((dev->regs[0x0b] & 0x08) ? 15 : 12));
|
||||
soft_reset_mask = 1;
|
||||
dev->regs[0x19] |= 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_sw_smi_handler(sis_85c4xx_t *dev)
|
||||
{
|
||||
uint16_t addr;
|
||||
|
||||
if (!dev->is_471)
|
||||
return;
|
||||
return;
|
||||
|
||||
addr = dev->regs[0x14] | (dev->regs[0x15] << 8);
|
||||
|
||||
io_handler((dev->regs[0x0b] & 0x80) && (dev->regs[0x18] & 0x02), addr, 0x0001,
|
||||
NULL, NULL, NULL, sis_85c4xx_sw_smi_out, NULL, NULL, dev);
|
||||
NULL, NULL, NULL, sis_85c4xx_sw_smi_out, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
|
||||
uint8_t valxor = 0x00;
|
||||
uint32_t host_base = 0x000e0000, ram_base = 0x000a0000;
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
|
||||
uint8_t valxor = 0x00;
|
||||
uint32_t host_base = 0x000e0000, ram_base = 0x000a0000;
|
||||
|
||||
switch (port) {
|
||||
case 0x22:
|
||||
dev->cur_reg = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) {
|
||||
valxor = val ^ dev->regs[rel_reg];
|
||||
if (rel_reg == 0x19)
|
||||
dev->regs[rel_reg] &= ~val;
|
||||
else
|
||||
dev->regs[rel_reg] = val;
|
||||
case 0x22:
|
||||
dev->cur_reg = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) {
|
||||
valxor = val ^ dev->regs[rel_reg];
|
||||
if (rel_reg == 0x19)
|
||||
dev->regs[rel_reg] &= ~val;
|
||||
else
|
||||
dev->regs[rel_reg] = val;
|
||||
|
||||
switch (rel_reg) {
|
||||
case 0x01:
|
||||
cpu_cache_ext_enabled = ((val & 0x84) == 0x84);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
switch (rel_reg) {
|
||||
case 0x01:
|
||||
cpu_cache_ext_enabled = ((val & 0x84) == 0x84);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x02: case 0x03:
|
||||
case 0x08:
|
||||
if (valxor)
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x08:
|
||||
if (valxor)
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
if (dev->is_471 && (valxor & 0x02)) {
|
||||
if (val & 0x02)
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(256);
|
||||
}
|
||||
break;
|
||||
case 0x0b:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
if (dev->is_471 && (valxor & 0x02)) {
|
||||
if (val & 0x02)
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(256);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
if (dev->is_471 && (valxor & 0xf0)) {
|
||||
smram_disable(dev->smram);
|
||||
host_base = (val & 0x80) ? 0x00060000 : 0x000e0000;
|
||||
switch ((val >> 5) & 0x03) {
|
||||
case 0x00:
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x01:
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 0x02:
|
||||
ram_base = (val & 0x80) ? 0x00000000 : 0x000e0000;
|
||||
break;
|
||||
default:
|
||||
ram_base = 0x00000000;
|
||||
break;
|
||||
}
|
||||
if (ram_base != 0x00000000)
|
||||
smram_enable(dev->smram, host_base, ram_base, 0x00010000, (val & 0x10), 1);
|
||||
}
|
||||
break;
|
||||
case 0x13:
|
||||
if (dev->is_471 && (valxor & 0xf0)) {
|
||||
smram_disable(dev->smram);
|
||||
host_base = (val & 0x80) ? 0x00060000 : 0x000e0000;
|
||||
switch ((val >> 5) & 0x03) {
|
||||
case 0x00:
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x01:
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 0x02:
|
||||
ram_base = (val & 0x80) ? 0x00000000 : 0x000e0000;
|
||||
break;
|
||||
default:
|
||||
ram_base = 0x00000000;
|
||||
break;
|
||||
}
|
||||
if (ram_base != 0x00000000)
|
||||
smram_enable(dev->smram, host_base, ram_base, 0x00010000, (val & 0x10), 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x14: case 0x15:
|
||||
case 0x18:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
break;
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x18:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
if (dev->is_471)
|
||||
soft_reset_mask = 0;
|
||||
break;
|
||||
case 0x1c:
|
||||
if (dev->is_471)
|
||||
soft_reset_mask = 0;
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
if (dev->is_471 && (valxor & 0x01)) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x01)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
|
||||
dev->reg_00 = val;
|
||||
dev->cur_reg = 0x00;
|
||||
break;
|
||||
case 0x22:
|
||||
if (dev->is_471 && (valxor & 0x01)) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x01)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
|
||||
dev->reg_00 = val;
|
||||
dev->cur_reg = 0x00;
|
||||
break;
|
||||
|
||||
case 0xe1: case 0xe2:
|
||||
dev->scratch[port - 0xe1] = val;
|
||||
return;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[port - 0xe1] = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c4xx_in(uint16_t port, void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
|
||||
uint8_t ret = 0xff;
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x23:
|
||||
if (dev->is_471 && (dev->cur_reg == 0x1c))
|
||||
ret = inb(0x70);
|
||||
/* On the SiS 40x, the shadow RAM read and write enable bits are write-only! */
|
||||
if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x62))
|
||||
ret = dev->regs[rel_reg] & 0x3f;
|
||||
else if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last))
|
||||
ret = dev->regs[rel_reg];
|
||||
else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
|
||||
ret = dev->reg_00;
|
||||
if (dev->reg_base != 0x60)
|
||||
dev->cur_reg = 0x00;
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->is_471 && (dev->cur_reg == 0x1c))
|
||||
ret = inb(0x70);
|
||||
/* On the SiS 40x, the shadow RAM read and write enable bits are write-only! */
|
||||
if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x62))
|
||||
ret = dev->regs[rel_reg] & 0x3f;
|
||||
else if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last))
|
||||
ret = dev->regs[rel_reg];
|
||||
else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
|
||||
ret = dev->reg_00;
|
||||
if (dev->reg_base != 0x60)
|
||||
dev->cur_reg = 0x00;
|
||||
break;
|
||||
|
||||
case 0xe1: case 0xe2:
|
||||
ret = dev->scratch[port - 0xe1];
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[port - 0xe1];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_reset(void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
int mem_size_mb = mem_size >> 10;
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
int mem_size_mb = mem_size >> 10;
|
||||
static uint8_t ram_4xx[64] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x04, 0x04, 0x05, 0x05, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
|
||||
0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
|
||||
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e };
|
||||
0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
|
||||
0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
|
||||
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e };
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
|
||||
if (cpu_s->rspeed < 25000000)
|
||||
dev->regs[0x08] = 0x80;
|
||||
dev->regs[0x08] = 0x80;
|
||||
|
||||
if (dev->is_471) {
|
||||
dev->regs[0x09] = 0x40;
|
||||
if (mem_size_mb >= 64) {
|
||||
if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[0x09] |= 0x22;
|
||||
else
|
||||
dev->regs[0x09] |= 0x24;
|
||||
} else
|
||||
dev->regs[0x09] |= ram_471[mem_size_mb];
|
||||
dev->regs[0x09] = 0x40;
|
||||
if (mem_size_mb >= 64) {
|
||||
if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[0x09] |= 0x22;
|
||||
else
|
||||
dev->regs[0x09] |= 0x24;
|
||||
} else
|
||||
dev->regs[0x09] |= ram_471[mem_size_mb];
|
||||
|
||||
dev->regs[0x11] = 0x09;
|
||||
dev->regs[0x12] = 0xff;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xf0;
|
||||
dev->regs[0x26] = 0x01;
|
||||
dev->regs[0x11] = 0x09;
|
||||
dev->regs[0x12] = 0xff;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xf0;
|
||||
dev->regs[0x26] = 0x01;
|
||||
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1);
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1);
|
||||
|
||||
port_92_remove(dev->port_92);
|
||||
port_92_remove(dev->port_92);
|
||||
|
||||
mem_remap_top(256);
|
||||
soft_reset_mask = 0;
|
||||
mem_remap_top(256);
|
||||
soft_reset_mask = 0;
|
||||
} else {
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
if (dev->reg_base == 0x60)
|
||||
dev->reg_00 = 0x24;
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
if (dev->reg_base == 0x60)
|
||||
dev->reg_00 = 0x24;
|
||||
|
||||
if (mem_size_mb == 64)
|
||||
dev->regs[0x00] = 0x1f;
|
||||
else if (mem_size_mb < 64)
|
||||
dev->regs[0x00] = ram_4xx[mem_size_mb];
|
||||
if (mem_size_mb == 64)
|
||||
dev->regs[0x00] = 0x1f;
|
||||
else if (mem_size_mb < 64)
|
||||
dev->regs[0x00] = ram_4xx[mem_size_mb];
|
||||
|
||||
dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x11] = 0x01;
|
||||
}
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
@@ -315,19 +312,17 @@ sis_85c4xx_reset(void *priv)
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_close(void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
|
||||
if (dev->is_471)
|
||||
smram_del(dev->smram);
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sis_85c4xx_init(const device_t *info)
|
||||
{
|
||||
@@ -339,19 +334,19 @@ sis_85c4xx_init(const device_t *info)
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
if (dev->is_471) {
|
||||
dev->reg_last = dev->reg_base + 0x76;
|
||||
dev->reg_last = dev->reg_base + 0x76;
|
||||
|
||||
dev->smram = smram_add();
|
||||
dev->smram = smram_add();
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
} else
|
||||
dev->reg_last = dev->reg_base + 0x11;
|
||||
dev->reg_last = dev->reg_base + 0x11;
|
||||
|
||||
io_sethandler(0x0022, 0x0002,
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
|
||||
io_sethandler(0x00e1, 0x0002,
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
|
||||
sis_85c4xx_reset(dev);
|
||||
|
||||
@@ -359,58 +354,58 @@ sis_85c4xx_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t sis_85c401_device = {
|
||||
.name = "SiS 85c401/85c402",
|
||||
.name = "SiS 85c401/85c402",
|
||||
.internal_name = "sis_85c401",
|
||||
.flags = 0,
|
||||
.local = 0x060,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
.flags = 0,
|
||||
.local = 0x060,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_85c460_device = {
|
||||
.name = "SiS 85c460",
|
||||
.name = "SiS 85c460",
|
||||
.internal_name = "sis_85c460",
|
||||
.flags = 0,
|
||||
.local = 0x050,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
.flags = 0,
|
||||
.local = 0x050,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
/* TODO: Log to make sure the registers are correct. */
|
||||
const device_t sis_85c461_device = {
|
||||
.name = "SiS 85c461",
|
||||
.name = "SiS 85c461",
|
||||
.internal_name = "sis_85c461",
|
||||
.flags = 0,
|
||||
.local = 0x050,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
.flags = 0,
|
||||
.local = 0x050,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_85c471_device = {
|
||||
.name = "SiS 85c407/85c471",
|
||||
.name = "SiS 85c407/85c471",
|
||||
.internal_name = "sis_85c471",
|
||||
.flags = 0,
|
||||
.local = 0x150,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
.flags = 0,
|
||||
.local = 0x150,
|
||||
.init = sis_85c4xx_init,
|
||||
.close = sis_85c4xx_close,
|
||||
.reset = sis_85c4xx_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_SIS_85C50X_LOG
|
||||
int sis_85c50x_do_log = ENABLE_SIS_85C50X_LOG;
|
||||
static void
|
||||
@@ -45,264 +44,272 @@ sis_85c50x_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (sis_85c50x_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define sis_85c50x_log(fmt, ...)
|
||||
# define sis_85c50x_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_85c50x_t {
|
||||
uint8_t index,
|
||||
pci_conf[256], pci_conf_sb[256],
|
||||
regs[256];
|
||||
|
||||
typedef struct sis_85c50x_t
|
||||
{
|
||||
uint8_t index,
|
||||
pci_conf[256], pci_conf_sb[256],
|
||||
regs[256];
|
||||
|
||||
smram_t * smram;
|
||||
port_92_t * port_92;
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
} sis_85c50x_t;
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
|
||||
{
|
||||
uint32_t base, i, can_read, can_write;
|
||||
|
||||
can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
if (!can_read)
|
||||
can_write = MEM_WRITE_EXTANY;
|
||||
can_write = MEM_WRITE_EXTANY;
|
||||
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write);
|
||||
shadowbios = 1;
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xe0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xd0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xc0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xe0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xd0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xc0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_smm_recalc(sis_85c50x_t *dev)
|
||||
{
|
||||
/* NOTE: Naming mismatch - what the datasheet calls "host address" is what we call ram_base. */
|
||||
uint32_t ram_base = (dev->pci_conf[0x64] << 20) |
|
||||
((dev->pci_conf[0x65] & 0x07) << 28);
|
||||
uint32_t ram_base = (dev->pci_conf[0x64] << 20) | ((dev->pci_conf[0x65] & 0x07) << 28);
|
||||
|
||||
smram_disable(dev->smram);
|
||||
|
||||
if ((((dev->pci_conf[0x65] & 0xe0) >> 5) != 0x00) && (ram_base == 0x00000000))
|
||||
return;
|
||||
return;
|
||||
|
||||
switch ((dev->pci_conf[0x65] & 0xe0) >> 5) {
|
||||
case 0x00:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x01:
|
||||
smram_enable(dev->smram, 0xb0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x02:
|
||||
smram_enable(dev->smram, 0xa0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x04:
|
||||
smram_enable(dev->smram, 0xa0000, ram_base, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x06:
|
||||
smram_enable(dev->smram, 0xb0000, ram_base, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x00:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x01:
|
||||
smram_enable(dev->smram, 0xb0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x02:
|
||||
smram_enable(dev->smram, 0xa0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x04:
|
||||
smram_enable(dev->smram, 0xa0000, ram_base, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x06:
|
||||
smram_enable(dev->smram, 0xb0000, ram_base, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
uint8_t valxor = (val ^ dev->pci_conf[addr]);
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
uint8_t valxor = (val ^ dev->pci_conf[addr]);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - low byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xb4) | (val & 0x4b);
|
||||
break;
|
||||
case 0x07: /* Status - high byte */
|
||||
dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06);
|
||||
break;
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x51: /* Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = (val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x53: /* Shadow RAM */
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_85c50x_shadow_recalc(dev);
|
||||
if (addr == 0x54)
|
||||
sis_85c50x_smm_recalc(dev);
|
||||
break;
|
||||
case 0x57: case 0x58: case 0x59: case 0x5a:
|
||||
case 0x5c: case 0x5d: case 0x5e: case 0x61:
|
||||
case 0x62: case 0x63: case 0x67: case 0x68:
|
||||
case 0x6a: case 0x6b: case 0x6c: case 0x6d:
|
||||
case 0x6e: case 0x6f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0xc0)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
|
||||
break;
|
||||
case 0x60: /* SMI */
|
||||
if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) {
|
||||
dev->pci_conf[0x69] |= 0x01;
|
||||
smi_raise();
|
||||
}
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
break;
|
||||
case 0x64: /* SMRAM */
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_85c50x_smm_recalc(dev);
|
||||
break;
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= ~(val);
|
||||
break;
|
||||
case 0x04: /* Command - low byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xb4) | (val & 0x4b);
|
||||
break;
|
||||
case 0x07: /* Status - high byte */
|
||||
dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06);
|
||||
break;
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x51: /* Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = (val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x53: /* Shadow RAM */
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_85c50x_shadow_recalc(dev);
|
||||
if (addr == 0x54)
|
||||
sis_85c50x_smm_recalc(dev);
|
||||
break;
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (valxor & 0xc0)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
|
||||
break;
|
||||
case 0x60: /* SMI */
|
||||
if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) {
|
||||
dev->pci_conf[0x69] |= 0x01;
|
||||
smi_raise();
|
||||
}
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
break;
|
||||
case 0x64: /* SMRAM */
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_85c50x_smm_recalc(dev);
|
||||
break;
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= ~(val);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_85c50x_log("85C501: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c50x_read(int func, int addr, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
sis_85c50x_log("85C501: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]);
|
||||
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x07: /* Status */
|
||||
dev->pci_conf_sb[addr] &= ~(val & 0x30);
|
||||
break;
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x41: case 0x42: case 0x43: case 0x44:
|
||||
/* INTA/B/C/D# Remapping Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf);
|
||||
break;
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[addr] = val;
|
||||
break;
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x07: /* Status */
|
||||
dev->pci_conf_sb[addr] &= ~(val & 0x30);
|
||||
break;
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
/* INTA/B/C/D# Remapping Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf);
|
||||
break;
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[addr] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] = %02x\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c50x_sb_read(int func, int addr, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] (%02x)\n", addr, dev->pci_conf_sb[addr]);
|
||||
|
||||
return dev->pci_conf_sb[addr];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
switch (dev->index) {
|
||||
case 0x80:
|
||||
dev->regs[dev->index] = val & 0xe7;
|
||||
break;
|
||||
case 0x81:
|
||||
dev->regs[dev->index] = val & 0xf4;
|
||||
break;
|
||||
case 0x84: case 0x88: case 0x9: case 0x8a:
|
||||
case 0x8b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x85:
|
||||
outb(0x70, val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x23:
|
||||
switch (dev->index) {
|
||||
case 0x80:
|
||||
dev->regs[dev->index] = val & 0xe7;
|
||||
break;
|
||||
case 0x81:
|
||||
dev->regs[dev->index] = val & 0xf4;
|
||||
break;
|
||||
case 0x84:
|
||||
case 0x88:
|
||||
case 0x9:
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x85:
|
||||
outb(0x70, val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c50x_isa_read(uint16_t addr, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
ret = dev->index;
|
||||
break;
|
||||
case 0x22:
|
||||
ret = dev->index;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
if (dev->index == 0x85)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->index == 0x85)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
}
|
||||
|
||||
sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)\n", dev->index, ret);
|
||||
@@ -310,11 +317,10 @@ sis_85c50x_isa_read(uint16_t addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_reset(void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
/* North Bridge (SiS 85C501/502) */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
@@ -358,21 +364,19 @@ sis_85c50x_reset(void *priv)
|
||||
sis_85c50x_write(0, 0x44, 0x80, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_close(void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)priv;
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sis_85c50x_init(const device_t *info)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *)malloc(sizeof(sis_85c50x_t));
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t));
|
||||
memset(dev, 0x00, sizeof(sis_85c50x_t));
|
||||
|
||||
/* 501/502 (Northbridge) */
|
||||
@@ -382,7 +386,7 @@ sis_85c50x_init(const device_t *info)
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev);
|
||||
io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
|
||||
|
||||
dev->smram = smram_add();
|
||||
dev->smram = smram_add();
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
|
||||
sis_85c50x_reset(dev);
|
||||
@@ -391,15 +395,15 @@ sis_85c50x_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t sis_85c50x_device = {
|
||||
.name = "SiS 85C50x",
|
||||
.name = "SiS 85C50x",
|
||||
.internal_name = "sis_85c50x",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_85c50x_init,
|
||||
.close = sis_85c50x_close,
|
||||
.reset = sis_85c50x_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_85c50x_init,
|
||||
.close = sis_85c50x_close,
|
||||
.reset = sis_85c50x_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -48,16 +48,16 @@
|
||||
1 0 PCICLK/2
|
||||
|
||||
Function 0 Register A2 - non-software SMI# status register
|
||||
(documented by Miran Grca):
|
||||
(documented by Miran Grca):
|
||||
Bit 4: I set, graphics card goes into sleep mode
|
||||
This register is most likely R/WC
|
||||
|
||||
Function 0 Register A3 (added more details by Miran Grca):
|
||||
Bit 7: Unlock SMM
|
||||
Bit 6: Software SMI trigger (also doubles as software SMI# status register,
|
||||
cleared by writing a 0 to it - see the handler used by Phoenix BIOS'es):
|
||||
If Function 0 Register 46 Bit 6 is set, it raises the specified IRQ (15
|
||||
or 10) instead.
|
||||
cleared by writing a 0 to it - see the handler used by Phoenix BIOS'es):
|
||||
If Function 0 Register 46 Bit 6 is set, it raises the specified IRQ (15
|
||||
or 10) instead.
|
||||
|
||||
Function 0 Register A4:
|
||||
Bit 0: Host to PCI Clock (1: 1 by 1/0: 1 by half)
|
||||
@@ -87,52 +87,45 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#define IDE_BIT 0x01
|
||||
|
||||
#define IDE_BIT 0x01
|
||||
|
||||
#ifdef ENABLE_UMC_8886_LOG
|
||||
int umc_8886_do_log = ENABLE_UMC_8886_LOG;
|
||||
|
||||
|
||||
static void
|
||||
umc_8886_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (umc_8886_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define umc_8886_log(fmt, ...)
|
||||
# define umc_8886_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* PCI IRQ Flags */
|
||||
#define INTA (PCI_INTA + (2 * !(addr & 1)))
|
||||
#define INTB (PCI_INTB + (2 * !(addr & 1)))
|
||||
#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED)
|
||||
#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED)
|
||||
#define INTA (PCI_INTA + (2 * !(addr & 1)))
|
||||
#define INTB (PCI_INTB + (2 * !(addr & 1)))
|
||||
#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED)
|
||||
#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED)
|
||||
|
||||
/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */
|
||||
#define HAS_IDE dev->has_ide
|
||||
#define HAS_IDE dev->has_ide
|
||||
|
||||
/* Southbridge Revision */
|
||||
#define SB_ID dev->sb_id
|
||||
#define SB_ID dev->sb_id
|
||||
|
||||
|
||||
typedef struct umc_8886_t
|
||||
{
|
||||
uint8_t max_func, /* Last function number */
|
||||
pci_conf_sb[2][256]; /* PCI Registers */
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
int has_ide; /* Check if Southbridge Revision is AF or F */
|
||||
typedef struct umc_8886_t {
|
||||
uint8_t max_func, /* Last function number */
|
||||
pci_conf_sb[2][256]; /* PCI Registers */
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
int has_ide; /* Check if Southbridge Revision is AF or F */
|
||||
} umc_8886_t;
|
||||
|
||||
|
||||
static void
|
||||
umc_8886_ide_handler(int status)
|
||||
{
|
||||
@@ -140,164 +133,172 @@ umc_8886_ide_handler(int status)
|
||||
ide_sec_disable();
|
||||
|
||||
if (status) {
|
||||
ide_pri_enable();
|
||||
ide_sec_enable();
|
||||
ide_pri_enable();
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
umc_8886_t *dev = (umc_8886_t *) priv;
|
||||
|
||||
if (func <= dev->max_func) switch (func) {
|
||||
case 0: /* PCI to ISA Bridge */
|
||||
umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80));
|
||||
if (func <= dev->max_func)
|
||||
switch (func) {
|
||||
case 0: /* PCI to ISA Bridge */
|
||||
umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: case 0x05:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0c: case 0x0d:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40: case 0x41:
|
||||
case 0x42:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x43: case 0x44:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
pci_set_irq_routing(INTA, IRQRECALCA);
|
||||
pci_set_irq_routing(INTB, IRQRECALCB);
|
||||
break;
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
pci_set_irq_routing(INTA, IRQRECALCA);
|
||||
pci_set_irq_routing(INTB, IRQRECALCB);
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
/* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x46:
|
||||
/* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x47:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x53:
|
||||
case 0x54: case 0x55:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
case 0x56:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
|
||||
switch (val & 2) {
|
||||
case 0:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(2);
|
||||
break;
|
||||
}
|
||||
switch (val & 2) {
|
||||
case 0:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(2);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
case 0x70 ... 0x76:
|
||||
case 0x80: case 0x81:
|
||||
case 0x90 ... 0x92:
|
||||
case 0xa0 ... 0xa1:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
case 0x57:
|
||||
case 0x70 ... 0x76:
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x90 ... 0x92:
|
||||
case 0xa0 ... 0xa1:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa2:
|
||||
dev->pci_conf_sb[func][addr] &= ~val;
|
||||
break;
|
||||
case 0xa2:
|
||||
dev->pci_conf_sb[func][addr] &= ~val;
|
||||
break;
|
||||
|
||||
case 0xa3:
|
||||
/* SMI Provocation (Bit 7 Enable SMM + Bit 6 Software SMI) */
|
||||
if (((val & 0xc0) == 0xc0) && !(dev->pci_conf_sb[0][0xa3] & 0x40)) {
|
||||
if (dev->pci_conf_sb[0][0x46] & 0x40)
|
||||
picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10));
|
||||
else
|
||||
smi_raise();
|
||||
dev->pci_conf_sb[0][0xa3] |= 0x04;
|
||||
}
|
||||
case 0xa3:
|
||||
/* SMI Provocation (Bit 7 Enable SMM + Bit 6 Software SMI) */
|
||||
if (((val & 0xc0) == 0xc0) && !(dev->pci_conf_sb[0][0xa3] & 0x40)) {
|
||||
if (dev->pci_conf_sb[0][0x46] & 0x40)
|
||||
picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10));
|
||||
else
|
||||
smi_raise();
|
||||
dev->pci_conf_sb[0][0xa3] |= 0x04;
|
||||
}
|
||||
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa4:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2));
|
||||
break;
|
||||
case 0xa4:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2));
|
||||
break;
|
||||
|
||||
case 0xa5 ... 0xa8:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xa5 ... 0xa8:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* IDE Controller */
|
||||
umc_8886_log("UM8886-IDE: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80));
|
||||
case 1: /* IDE Controller */
|
||||
umc_8886_log("UM8886-IDE: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
umc_8886_ide_handler(val & 1);
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
umc_8886_ide_handler(val & 1);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x3c:
|
||||
case 0x40: case 0x41:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x3c:
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
umc_8886_read(int func, int addr, void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
umc_8886_t *dev = (umc_8886_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func <= dev->max_func)
|
||||
ret = dev->pci_conf_sb[func][addr];
|
||||
ret = dev->pci_conf_sb[func][addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
umc_8886_reset(void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
umc_8886_t *dev = (umc_8886_t *) priv;
|
||||
|
||||
memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0]));
|
||||
memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1]));
|
||||
|
||||
dev->pci_conf_sb[0][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[0][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[0][1] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */
|
||||
dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */
|
||||
dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff);
|
||||
|
||||
dev->pci_conf_sb[0][4] = 0x0f;
|
||||
@@ -321,43 +322,41 @@ umc_8886_reset(void *priv)
|
||||
dev->pci_conf_sb[0][0xa8] = 0x20;
|
||||
|
||||
if (HAS_IDE) {
|
||||
dev->pci_conf_sb[1][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[1][1] = 0x10;
|
||||
dev->pci_conf_sb[1][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[1][1] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */
|
||||
dev->pci_conf_sb[1][3] = 0x67;
|
||||
dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */
|
||||
dev->pci_conf_sb[1][3] = 0x67;
|
||||
|
||||
dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */
|
||||
dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */
|
||||
|
||||
dev->pci_conf_sb[1][8] = 0x10;
|
||||
dev->pci_conf_sb[1][8] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[1][0x09] = 0x0f;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1;
|
||||
dev->pci_conf_sb[1][0x09] = 0x0f;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1;
|
||||
|
||||
umc_8886_ide_handler(1);
|
||||
umc_8886_ide_handler(1);
|
||||
}
|
||||
|
||||
for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */
|
||||
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
|
||||
for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */
|
||||
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
|
||||
|
||||
cpu_set_isa_pci_div(3);
|
||||
cpu_set_pci_speed(cpu_busspeed / 2);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
umc_8886_close(void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
umc_8886_t *dev = (umc_8886_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
umc_8886_init(const device_t *info)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)malloc(sizeof(umc_8886_t));
|
||||
umc_8886_t *dev = (umc_8886_t *) malloc(sizeof(umc_8886_t));
|
||||
memset(dev, 0, sizeof(umc_8886_t));
|
||||
|
||||
dev->has_ide = !!(info->local == 0x886a);
|
||||
@@ -365,7 +364,7 @@ umc_8886_init(const device_t *info)
|
||||
|
||||
/* Add IDE if UM8886AF variant */
|
||||
if (HAS_IDE)
|
||||
device_add(&ide_pci_2ch_device);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->max_func = (HAS_IDE) ? 1 : 0;
|
||||
|
||||
@@ -378,29 +377,29 @@ umc_8886_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t umc_8886f_device = {
|
||||
.name = "UMC 8886F",
|
||||
.name = "UMC 8886F",
|
||||
.internal_name = "umc_8886f",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x8886,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x8886,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t umc_8886af_device = {
|
||||
.name = "UMC 8886AF/8886BF",
|
||||
.name = "UMC 8886AF/8886BF",
|
||||
.internal_name = "umc_8886af",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x886a,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x886a,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
Register 60:
|
||||
Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM
|
||||
Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM
|
||||
SMRAM appears to always be enabled in SMM, and always set to A0000-BFFFF.
|
||||
SMRAM appears to always be enabled in SMM, and always set to A0000-BFFFF.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -108,56 +108,50 @@
|
||||
#include <86box/smram.h>
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen_public.h"
|
||||
# include "codegen_public.h"
|
||||
#else
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define PAGE_MASK_SHIFT 6
|
||||
#else
|
||||
# define PAGE_MASK_INDEX_MASK 3
|
||||
# define PAGE_MASK_INDEX_SHIFT 10
|
||||
# define PAGE_MASK_SHIFT 4
|
||||
#endif
|
||||
# define PAGE_MASK_MASK 63
|
||||
# ifdef USE_NEW_DYNAREC
|
||||
# define PAGE_MASK_SHIFT 6
|
||||
# else
|
||||
# define PAGE_MASK_INDEX_MASK 3
|
||||
# define PAGE_MASK_INDEX_SHIFT 10
|
||||
# define PAGE_MASK_SHIFT 4
|
||||
# endif
|
||||
# define PAGE_MASK_MASK 63
|
||||
#endif
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_HB4_LOG
|
||||
int hb4_do_log = ENABLE_HB4_LOG;
|
||||
|
||||
|
||||
static void
|
||||
hb4_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (hb4_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define hb4_log(fmt, ...)
|
||||
# define hb4_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct hb4_t
|
||||
{
|
||||
uint8_t shadow,
|
||||
shadow_read, shadow_write,
|
||||
pci_conf[256]; /* PCI Registers */
|
||||
int mem_state[9];
|
||||
smram_t *smram[3]; /* SMRAM Handlers */
|
||||
typedef struct hb4_t {
|
||||
uint8_t shadow,
|
||||
shadow_read, shadow_write,
|
||||
pci_conf[256]; /* PCI Registers */
|
||||
int mem_state[9];
|
||||
smram_t *smram[3]; /* SMRAM Handlers */
|
||||
} hb4_t;
|
||||
|
||||
|
||||
static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY),
|
||||
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL), (MEM_READ_INTERNAL | MEM_WRITE_EXTANY) };
|
||||
static int shadow_read[2] = { MEM_READ_EXTANY, MEM_READ_INTERNAL };
|
||||
static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY),
|
||||
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL), (MEM_READ_INTERNAL | MEM_WRITE_EXTANY) };
|
||||
static int shadow_read[2] = { MEM_READ_EXTANY, MEM_READ_INTERNAL };
|
||||
static int shadow_write[2] = { MEM_WRITE_INTERNAL, MEM_WRITE_EXTANY };
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_bios_high(hb4_t *dev)
|
||||
{
|
||||
@@ -166,17 +160,16 @@ hb4_shadow_bios_high(hb4_t *dev)
|
||||
state = shadow_bios[dev->pci_conf[0x55] >> 6];
|
||||
|
||||
if (state != dev->mem_state[8]) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
if ((dev->mem_state[8] & MEM_READ_INTERNAL) && !(state & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(0xf0000, 0xfffff);
|
||||
dev->mem_state[8] = state;
|
||||
return 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
if ((dev->mem_state[8] & MEM_READ_INTERNAL) && !(state & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(0xf0000, 0xfffff);
|
||||
dev->mem_state[8] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_bios_low(hb4_t *dev)
|
||||
{
|
||||
@@ -185,15 +178,14 @@ hb4_shadow_bios_low(hb4_t *dev)
|
||||
state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)];
|
||||
|
||||
if (state != dev->mem_state[7]) {
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, state);
|
||||
dev->mem_state[7] = state;
|
||||
return 1;
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, state);
|
||||
dev->mem_state[7] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_main(hb4_t *dev)
|
||||
{
|
||||
@@ -201,38 +193,34 @@ hb4_shadow_main(hb4_t *dev)
|
||||
int n = 0;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[i + 1]) {
|
||||
n++;
|
||||
mem_set_mem_state_both(0xc8000 + (i << 14), 0x4000, state);
|
||||
dev->mem_state[i + 1] = state;
|
||||
}
|
||||
if (state != dev->mem_state[i + 1]) {
|
||||
n++;
|
||||
mem_set_mem_state_both(0xc8000 + (i << 14), 0x4000, state);
|
||||
dev->mem_state[i + 1] = state;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_video(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[0]) {
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, state);
|
||||
dev->mem_state[0] = state;
|
||||
return 1;
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, state);
|
||||
dev->mem_state[0] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb4_shadow(hb4_t *dev)
|
||||
{
|
||||
@@ -245,10 +233,9 @@ hb4_shadow(hb4_t *dev)
|
||||
n += hb4_shadow_video(dev);
|
||||
|
||||
if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_smram(hb4_t *dev)
|
||||
{
|
||||
@@ -265,93 +252,93 @@ hb4_smram(hb4_t *dev)
|
||||
/* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses
|
||||
this. */
|
||||
if (dev->pci_conf[0x60] & 0x20) {
|
||||
if (dev->pci_conf[0x60] & 0x01)
|
||||
mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02);
|
||||
mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02);
|
||||
if (dev->pci_conf[0x60] & 0x01)
|
||||
mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02);
|
||||
mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
|
||||
hb4_log("UM8881: dev->regs[%02x] = %02x POST: %02x \n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: case 0x05:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0c: case 0x0d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = ((val & 0xf8) | 4); /* Hardcode Cache Size to 512KB */
|
||||
cpu_cache_ext_enabled = !!(val & 0x80); /* Fixes freezing issues on the HOT-433A*/
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = ((val & 0xf8) | 4); /* Hardcode Cache Size to 512KB */
|
||||
cpu_cache_ext_enabled = !!(val & 0x80); /* Fixes freezing issues on the HOT-433A*/
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x51: case 0x52:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_log("HB53: %02X\n", val);
|
||||
break;
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_log("HB53: %02X\n", val);
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->shadow_read = (val & 0x80);
|
||||
dev->shadow_write = (val & 0x40);
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
case 0x54:
|
||||
dev->shadow = (val & 0x01) << 1;
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
case 0x55:
|
||||
dev->shadow_read = (val & 0x80);
|
||||
dev->shadow_write = (val & 0x40);
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
case 0x54:
|
||||
dev->shadow = (val & 0x01) << 1;
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x56 ... 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_smram(dev);
|
||||
break;
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_smram(dev);
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
hb4_read(int func, int addr, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->pci_conf[addr];
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_reset(void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
|
||||
dev->pci_conf[0] = 0x60; /* UMC */
|
||||
@@ -385,23 +372,21 @@ hb4_reset(void *priv)
|
||||
memset(dev->mem_state, 0x00, sizeof(dev->mem_state));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_close(void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
hb4_init(const device_t *info)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)malloc(sizeof(hb4_t));
|
||||
hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t));
|
||||
memset(dev, 0, sizeof(hb4_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
|
||||
|
||||
/* Port 92 */
|
||||
device_add(&port_92_pci_device);
|
||||
@@ -417,15 +402,15 @@ hb4_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t umc_hb4_device = {
|
||||
.name = "UMC HB4(8881F)",
|
||||
.name = "UMC HB4(8881F)",
|
||||
.internal_name = "umc_hb4",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x886a,
|
||||
.init = hb4_init,
|
||||
.close = hb4_close,
|
||||
.reset = hb4_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x886a,
|
||||
.init = hb4_init,
|
||||
.close = hb4_close,
|
||||
.reset = hb4_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -37,14 +37,13 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t has_ide, index,
|
||||
regs[256];
|
||||
uint8_t has_ide, index,
|
||||
regs[256];
|
||||
|
||||
smram_t *smram_smm, *smram_low,
|
||||
*smram_high;
|
||||
smram_t *smram_smm, *smram_low,
|
||||
*smram_high;
|
||||
} vt82c49x_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_VT82C49X_LOG
|
||||
int vt82c49x_do_log = ENABLE_VT82C49X_LOG;
|
||||
static void
|
||||
@@ -53,124 +52,124 @@ vt82c49x_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (vt82c49x_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define vt82c49x_log(fmt, ...)
|
||||
# define vt82c49x_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
vt82c49x_recalc(vt82c49x_t *dev)
|
||||
{
|
||||
int i, relocate;
|
||||
uint8_t reg, bit;
|
||||
int i, relocate;
|
||||
uint8_t reg, bit;
|
||||
uint32_t base, state;
|
||||
uint32_t shadow_bitmap = 0x00000000;
|
||||
|
||||
relocate = (dev->regs[0x33] >> 2) & 0x03;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
reg = 0x30 + (i >> 2);
|
||||
bit = (i & 3) << 1;
|
||||
base = 0xc0000 + (i << 14);
|
||||
reg = 0x30 + (i >> 2);
|
||||
bit = (i & 3) << 1;
|
||||
|
||||
if ((base >= 0xc0000) && (base <= 0xc7fff)) {
|
||||
if (dev->regs[0x40] & 0x80)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[reg]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x40) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
if ((base >= 0xc0000) && (base <= 0xc7fff)) {
|
||||
if (dev->regs[0x40] & 0x80)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[reg]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x40) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((dev->regs[reg]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x40) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} if ((base >= 0xc8000) && (base <= 0xcffff)) {
|
||||
if ((dev->regs[reg]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x80) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
if ((dev->regs[reg]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x40) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
}
|
||||
if ((base >= 0xc8000) && (base <= 0xcffff)) {
|
||||
if ((dev->regs[reg]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x80) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((dev->regs[reg]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x80) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
state = ((dev->regs[reg]) & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
state |= ((dev->regs[reg]) & (1 << (bit + 1))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
}
|
||||
if ((dev->regs[reg]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x80) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
state = ((dev->regs[reg]) & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
state |= ((dev->regs[reg]) & (1 << (bit + 1))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
}
|
||||
|
||||
vt82c49x_log("(%02X=%02X, %i) Setting %08X-%08X to: write %sabled, read %sabled\n",
|
||||
reg, dev->regs[reg], bit, base, base + 0x3fff,
|
||||
((dev->regs[reg]) & (1 << bit)) ? "en" : "dis", ((dev->regs[reg]) & (1 << (bit + 1))) ? "en" : "dis");
|
||||
vt82c49x_log("(%02X=%02X, %i) Setting %08X-%08X to: write %sabled, read %sabled\n",
|
||||
reg, dev->regs[reg], bit, base, base + 0x3fff,
|
||||
((dev->regs[reg]) & (1 << bit)) ? "en" : "dis", ((dev->regs[reg]) & (1 << (bit + 1))) ? "en" : "dis");
|
||||
|
||||
if ((dev->regs[reg]) & (1 << bit))
|
||||
shadow_bitmap |= (1 << i);
|
||||
if ((dev->regs[reg]) & (1 << (bit + 1)))
|
||||
shadow_bitmap |= (1 << (i + 16));
|
||||
if ((dev->regs[reg]) & (1 << bit))
|
||||
shadow_bitmap |= (1 << i);
|
||||
if ((dev->regs[reg]) & (1 << (bit + 1)))
|
||||
shadow_bitmap |= (1 << (i + 16));
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xe0000 + (i << 15);
|
||||
bit = 6 - (i & 2);
|
||||
base = 0xe0000 + (i << 15);
|
||||
bit = 6 - (i & 2);
|
||||
|
||||
if ((base >= 0xe0000) && (base <= 0xe7fff)) {
|
||||
if (dev->regs[0x40] & 0x20)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[0x32]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x10) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
if ((base >= 0xe0000) && (base <= 0xe7fff)) {
|
||||
if (dev->regs[0x40] & 0x20)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[0x32]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x10) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x10) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else if ((base >= 0xe8000) && (base <= 0xeffff)) {
|
||||
if (dev->regs[0x40] & 0x20)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[0x32]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x20) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x10) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else if ((base >= 0xe8000) && (base <= 0xeffff)) {
|
||||
if (dev->regs[0x40] & 0x20)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[0x32]) & (1 << bit))
|
||||
state = MEM_WRITE_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x20) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x20) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x40] & 0x40)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[0x32]) & (1 << bit))
|
||||
state = ((dev->regs[0x32]) & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1)))
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state |= (dev->regs[0x33] & 0x20) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x40] & 0x40)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
else if ((dev->regs[0x32]) & (1 << bit))
|
||||
state = ((dev->regs[0x32]) & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
|
||||
state |= ((dev->regs[0x32]) & (1 << (bit + 1))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
}
|
||||
state |= ((dev->regs[0x32]) & (1 << (bit + 1))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
}
|
||||
|
||||
vt82c49x_log("(32=%02X, %i) Setting %08X-%08X to: write %sabled, read %sabled\n",
|
||||
dev->regs[0x32], bit, base, base + 0x7fff,
|
||||
((dev->regs[0x32]) & (1 << bit)) ? "en" : "dis", ((dev->regs[0x32]) & (1 << (bit + 1))) ? "en" : "dis");
|
||||
vt82c49x_log("(32=%02X, %i) Setting %08X-%08X to: write %sabled, read %sabled\n",
|
||||
dev->regs[0x32], bit, base, base + 0x7fff,
|
||||
((dev->regs[0x32]) & (1 << bit)) ? "en" : "dis", ((dev->regs[0x32]) & (1 << (bit + 1))) ? "en" : "dis");
|
||||
|
||||
if ((dev->regs[0x32]) & (1 << bit)) {
|
||||
shadow_bitmap |= (0xf << ((i << 2) + 8));
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1))) {
|
||||
shadow_bitmap |= (0xf << ((i << 2) + 24));
|
||||
shadowbios |= 1;
|
||||
}
|
||||
if ((dev->regs[0x32]) & (1 << bit)) {
|
||||
shadow_bitmap |= (0xf << ((i << 2) + 8));
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1))) {
|
||||
shadow_bitmap |= (0xf << ((i << 2) + 24));
|
||||
shadowbios |= 1;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x8000, state);
|
||||
mem_set_mem_state_both(base, 0x8000, state);
|
||||
}
|
||||
|
||||
vt82c49x_log("Shadow bitmap: %08X\n", shadow_bitmap);
|
||||
@@ -178,145 +177,142 @@ vt82c49x_recalc(vt82c49x_t *dev)
|
||||
mem_remap_top(0);
|
||||
|
||||
switch (relocate) {
|
||||
case 0x02:
|
||||
if (!(shadow_bitmap & 0xfff0fff0))
|
||||
mem_remap_top(256);
|
||||
break;
|
||||
case 0x03:
|
||||
if (!shadow_bitmap)
|
||||
mem_remap_top(384);
|
||||
break;
|
||||
case 0x02:
|
||||
if (!(shadow_bitmap & 0xfff0fff0))
|
||||
mem_remap_top(256);
|
||||
break;
|
||||
case 0x03:
|
||||
if (!shadow_bitmap)
|
||||
mem_remap_top(384);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c49x_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
vt82c49x_t *dev = (vt82c49x_t *) priv;
|
||||
uint8_t valxor;
|
||||
uint8_t valxor;
|
||||
|
||||
switch (addr) {
|
||||
case 0xa8:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0xa8:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0xa9:
|
||||
valxor = (val ^ dev->regs[dev->index]);
|
||||
if (dev->index == 0x55)
|
||||
dev->regs[dev->index] &= ~val;
|
||||
else
|
||||
dev->regs[dev->index] = val;
|
||||
case 0xa9:
|
||||
valxor = (val ^ dev->regs[dev->index]);
|
||||
if (dev->index == 0x55)
|
||||
dev->regs[dev->index] &= ~val;
|
||||
else
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
vt82c49x_log("dev->regs[0x%02x] = %02x\n", dev->index, val);
|
||||
vt82c49x_log("dev->regs[0x%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch(dev->index) {
|
||||
/* Wait States */
|
||||
case 0x03:
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
switch (dev->index) {
|
||||
/* Wait States */
|
||||
case 0x03:
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
/* Shadow RAM and top of RAM relocation */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x40:
|
||||
vt82c49x_recalc(dev);
|
||||
break;
|
||||
/* Shadow RAM and top of RAM relocation */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x40:
|
||||
vt82c49x_recalc(dev);
|
||||
break;
|
||||
|
||||
/* External Cache Enable(Based on the 486-VC-HD BIOS) */
|
||||
case 0x50:
|
||||
cpu_cache_ext_enabled = (val & 0x84);
|
||||
break;
|
||||
/* External Cache Enable(Based on the 486-VC-HD BIOS) */
|
||||
case 0x50:
|
||||
cpu_cache_ext_enabled = (val & 0x84);
|
||||
break;
|
||||
|
||||
/* Software SMI */
|
||||
case 0x54:
|
||||
if ((dev->regs[0x5b] & 0x80) && (valxor & 0x01) && (val & 0x01)) {
|
||||
if (dev->regs[0x5b] & 0x20)
|
||||
smi_raise();
|
||||
else
|
||||
picint(1 << 15);
|
||||
dev->regs[0x55] = 0x01;
|
||||
}
|
||||
break;
|
||||
/* Software SMI */
|
||||
case 0x54:
|
||||
if ((dev->regs[0x5b] & 0x80) && (valxor & 0x01) && (val & 0x01)) {
|
||||
if (dev->regs[0x5b] & 0x20)
|
||||
smi_raise();
|
||||
else
|
||||
picint(1 << 15);
|
||||
dev->regs[0x55] = 0x01;
|
||||
}
|
||||
break;
|
||||
|
||||
/* SMRAM */
|
||||
case 0x5b:
|
||||
smram_disable_all();
|
||||
/* SMRAM */
|
||||
case 0x5b:
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 0x80) {
|
||||
smram_enable(dev->smram_smm, (val & 0x40) ? 0x00060000 : 0x00030000, 0x000a0000, 0x00020000,
|
||||
0, (val & 0x10));
|
||||
smram_enable(dev->smram_high, 0x000a0000, 0x000a0000, 0x00020000,
|
||||
(val & 0x08), (val & 0x08));
|
||||
smram_enable(dev->smram_low, 0x00030000, 0x000a0000, 0x00020000,
|
||||
(val & 0x02), 0);
|
||||
}
|
||||
break;
|
||||
if (val & 0x80) {
|
||||
smram_enable(dev->smram_smm, (val & 0x40) ? 0x00060000 : 0x00030000, 0x000a0000, 0x00020000,
|
||||
0, (val & 0x10));
|
||||
smram_enable(dev->smram_high, 0x000a0000, 0x000a0000, 0x00020000,
|
||||
(val & 0x08), (val & 0x08));
|
||||
smram_enable(dev->smram_low, 0x00030000, 0x000a0000, 0x00020000,
|
||||
(val & 0x02), 0);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Edge/Level IRQ Control */
|
||||
case 0x62: case 0x63:
|
||||
if (dev->index == 0x63)
|
||||
pic_elcr_write(dev->index, val & 0xde, &pic2);
|
||||
else {
|
||||
pic_elcr_write(dev->index, val & 0xf8, &pic);
|
||||
pic_elcr_set_enabled(val & 0x01);
|
||||
}
|
||||
break;
|
||||
/* Edge/Level IRQ Control */
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
if (dev->index == 0x63)
|
||||
pic_elcr_write(dev->index, val & 0xde, &pic2);
|
||||
else {
|
||||
pic_elcr_write(dev->index, val & 0xf8, &pic);
|
||||
pic_elcr_set_enabled(val & 0x01);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Local Bus IDE Controller */
|
||||
case 0x71:
|
||||
if (dev->has_ide) {
|
||||
ide_pri_disable();
|
||||
ide_set_base(0, (val & 0x40) ? 0x170 : 0x1f0);
|
||||
ide_set_side(0, (val & 0x40) ? 0x376 : 0x3f6);
|
||||
if (val & 0x01)
|
||||
ide_pri_enable();
|
||||
vt82c49x_log("VT82C496 IDE now %sabled as %sary\n", (val & 0x01) ? "en": "dis",
|
||||
(val & 0x40) ? "second" : "prim");
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* Local Bus IDE Controller */
|
||||
case 0x71:
|
||||
if (dev->has_ide) {
|
||||
ide_pri_disable();
|
||||
ide_set_base(0, (val & 0x40) ? 0x170 : 0x1f0);
|
||||
ide_set_side(0, (val & 0x40) ? 0x376 : 0x3f6);
|
||||
if (val & 0x01)
|
||||
ide_pri_enable();
|
||||
vt82c49x_log("VT82C496 IDE now %sabled as %sary\n", (val & 0x01) ? "en" : "dis",
|
||||
(val & 0x40) ? "second" : "prim");
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
vt82c49x_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
vt82c49x_t *dev = (vt82c49x_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0xa9:
|
||||
/* Register 64h is jumper readout. */
|
||||
if (dev->index == 0x64)
|
||||
ret = 0xff;
|
||||
else if (dev->index == 0x63)
|
||||
ret = pic_elcr_read(dev->index, &pic2) | (dev->regs[dev->index] & 0x01);
|
||||
else if (dev->index == 0x62)
|
||||
ret = pic_elcr_read(dev->index, &pic) | (dev->regs[dev->index] & 0x07);
|
||||
else if (dev->index < 0x80)
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
case 0xa9:
|
||||
/* Register 64h is jumper readout. */
|
||||
if (dev->index == 0x64)
|
||||
ret = 0xff;
|
||||
else if (dev->index == 0x63)
|
||||
ret = pic_elcr_read(dev->index, &pic2) | (dev->regs[dev->index] & 0x01);
|
||||
else if (dev->index == 0x62)
|
||||
ret = pic_elcr_read(dev->index, &pic) | (dev->regs[dev->index] & 0x07);
|
||||
else if (dev->index < 0x80)
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c49x_reset(void *priv)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
vt82c49x_write(i, 0x00, priv);
|
||||
vt82c49x_write(i, 0x00, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c49x_close(void *priv)
|
||||
{
|
||||
@@ -329,21 +325,20 @@ vt82c49x_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vt82c49x_init(const device_t *info)
|
||||
{
|
||||
vt82c49x_t *dev = (vt82c49x_t *) malloc(sizeof(vt82c49x_t));
|
||||
memset(dev, 0x00, sizeof(vt82c49x_t));
|
||||
|
||||
dev->smram_smm = smram_add();
|
||||
dev->smram_low = smram_add();
|
||||
dev->smram_smm = smram_add();
|
||||
dev->smram_low = smram_add();
|
||||
dev->smram_high = smram_add();
|
||||
|
||||
dev->has_ide = info->local & 1;
|
||||
if (dev->has_ide) {
|
||||
device_add(&ide_vlb_2ch_device);
|
||||
ide_sec_disable();
|
||||
device_add(&ide_vlb_2ch_device);
|
||||
ide_sec_disable();
|
||||
}
|
||||
|
||||
device_add(&port_92_device);
|
||||
@@ -359,57 +354,57 @@ vt82c49x_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t via_vt82c49x_device = {
|
||||
.name = "VIA VT82C49X",
|
||||
.name = "VIA VT82C49X",
|
||||
.internal_name = "via_vt82c49x",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t via_vt82c49x_pci_device = {
|
||||
.name = "VIA VT82C49X PCI",
|
||||
.name = "VIA VT82C49X PCI",
|
||||
.internal_name = "via_vt82c49x_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = vt82c49x_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = vt82c49x_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t via_vt82c49x_ide_device = {
|
||||
.name = "VIA VT82C49X (With IDE)",
|
||||
.name = "VIA VT82C49X (With IDE)",
|
||||
.internal_name = "via_vt82c49x_ide",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t via_vt82c49x_pci_ide_device = {
|
||||
.name = "VIA VT82C49X PCI (With IDE)",
|
||||
.name = "VIA VT82C49X PCI (With IDE)",
|
||||
.internal_name = "via_vt82c49x_pci_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = vt82c49x_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = vt82c49x_init,
|
||||
.close = vt82c49x_close,
|
||||
.reset = vt82c49x_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -29,161 +29,163 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct vt82c505_t
|
||||
{
|
||||
uint8_t index;
|
||||
uint8_t pci_conf[256];
|
||||
typedef struct vt82c505_t {
|
||||
uint8_t index;
|
||||
uint8_t pci_conf[256];
|
||||
} vt82c505_t;
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
uint8_t irq;
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
uint8_t irq;
|
||||
const uint8_t irq_array[8] = { 0, 5, 9, 10, 11, 14, 15, 0 };
|
||||
|
||||
if (func != 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
switch(addr) {
|
||||
/* RX00-07h: Mandatory header field */
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xbf) | (val & 0x40);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0x90);
|
||||
break;
|
||||
switch (addr) {
|
||||
/* RX00-07h: Mandatory header field */
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xbf) | (val & 0x40);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0x90);
|
||||
break;
|
||||
|
||||
/* RX80-9F: VT82C505 internal configuration registers */
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x0f) | (val & 0xf0);
|
||||
break;
|
||||
case 0x81: case 0x84: case 0x85: case 0x87:
|
||||
case 0x88: case 0x89: case 0x8a: case 0x8b:
|
||||
case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
||||
case 0x92: case 0x94:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val & 0xdb;
|
||||
break;
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0xf9;
|
||||
break;
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
/* Bit 7 switches between the two PCI configuration mechanisms:
|
||||
0 = configuration mechanism 1, 1 = configuration mechanism 2 */
|
||||
pci_set_pmc(!(val & 0x80));
|
||||
break;
|
||||
case 0x90:
|
||||
dev->pci_conf[addr] = val;
|
||||
irq = irq_array[val & 0x07];
|
||||
if ((val & 0x08) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTC, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
/* RX80-9F: VT82C505 internal configuration registers */
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x0f) | (val & 0xf0);
|
||||
break;
|
||||
case 0x81:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x87:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8e:
|
||||
case 0x8f:
|
||||
case 0x92:
|
||||
case 0x94:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val & 0xdb;
|
||||
break;
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0xf9;
|
||||
break;
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
/* Bit 7 switches between the two PCI configuration mechanisms:
|
||||
0 = configuration mechanism 1, 1 = configuration mechanism 2 */
|
||||
pci_set_pmc(!(val & 0x80));
|
||||
break;
|
||||
case 0x90:
|
||||
dev->pci_conf[addr] = val;
|
||||
irq = irq_array[val & 0x07];
|
||||
if ((val & 0x08) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTC, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
|
||||
irq = irq_array[(val & 0x70) >> 4];
|
||||
if ((val & 0x80) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTD, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x91:
|
||||
dev->pci_conf[addr] = val;
|
||||
irq = irq_array[val & 0x07];
|
||||
if ((val & 0x08) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTA, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
irq = irq_array[(val & 0x70) >> 4];
|
||||
if ((val & 0x80) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTD, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x91:
|
||||
dev->pci_conf[addr] = val;
|
||||
irq = irq_array[val & 0x07];
|
||||
if ((val & 0x08) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTA, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
|
||||
irq = irq_array[(val & 0x70) >> 4];
|
||||
if ((val & 0x80) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTB, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x93:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
irq = irq_array[(val & 0x70) >> 4];
|
||||
if ((val & 0x80) && (irq != 0))
|
||||
pci_set_irq_routing(PCI_INTB, irq);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x93:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
vt82c505_read(int func, int addr, void *priv)
|
||||
{
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func != 0)
|
||||
return ret;
|
||||
return ret;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
|
||||
if (addr == 0xa8)
|
||||
dev->index = val;
|
||||
dev->index = val;
|
||||
else if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f))
|
||||
vt82c505_write(0, dev->index, val, priv);
|
||||
vt82c505_write(0, dev->index, val, priv);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
vt82c505_in(uint16_t addr, void *priv)
|
||||
{
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f))
|
||||
ret = vt82c505_read(0, dev->index, priv);
|
||||
ret = vt82c505_read(0, dev->index, priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_reset(void *priv)
|
||||
{
|
||||
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
|
||||
int i;
|
||||
int i;
|
||||
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x07] = 0x00;
|
||||
|
||||
for (i = 0x80; i <= 0x9f; i++) {
|
||||
switch (i) {
|
||||
case 0x81:
|
||||
vt82c505_write(0, i, 0x01, priv);
|
||||
break;
|
||||
case 0x84:
|
||||
vt82c505_write(0, i, 0x03, priv);
|
||||
break;
|
||||
case 0x93:
|
||||
vt82c505_write(0, i, 0x40, priv);
|
||||
break;
|
||||
default:
|
||||
vt82c505_write(0, i, 0x00, priv);
|
||||
break;
|
||||
}
|
||||
switch (i) {
|
||||
case 0x81:
|
||||
vt82c505_write(0, i, 0x01, priv);
|
||||
break;
|
||||
case 0x84:
|
||||
vt82c505_write(0, i, 0x03, priv);
|
||||
break;
|
||||
case 0x93:
|
||||
vt82c505_write(0, i, 0x40, priv);
|
||||
break;
|
||||
default:
|
||||
vt82c505_write(0, i, 0x00, priv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pic_reset();
|
||||
pic_set_pci_flag(1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_close(void *priv)
|
||||
{
|
||||
@@ -192,7 +194,6 @@ vt82c505_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vt82c505_init(const device_t *info)
|
||||
{
|
||||
@@ -217,15 +218,15 @@ vt82c505_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t via_vt82c505_device = {
|
||||
.name = "VIA VT82C505",
|
||||
.name = "VIA VT82C505",
|
||||
.internal_name = "via_vt82c505",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = vt82c505_init,
|
||||
.close = vt82c505_close,
|
||||
.reset = vt82c505_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = vt82c505_init,
|
||||
.close = vt82c505_close,
|
||||
.reset = vt82c505_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -28,148 +28,146 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t idx,
|
||||
regs[256];
|
||||
uint8_t idx,
|
||||
regs[256];
|
||||
} vl82c480_t;
|
||||
|
||||
|
||||
static int
|
||||
vl82c480_shflags(uint8_t access)
|
||||
{
|
||||
int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
|
||||
switch (access) {
|
||||
case 0x00:
|
||||
default:
|
||||
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;
|
||||
case 0x00:
|
||||
default:
|
||||
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
|
||||
vl82c480_recalc(vl82c480_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
int i, j;
|
||||
uint32_t base;
|
||||
uint8_t access;
|
||||
uint8_t access;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
for (j = 0; j < 8; j += 2) {
|
||||
base = 0x000a0000 + (i << 16) + (j << 13);
|
||||
access = (dev->regs[0x0d + i] >> j) & 3;
|
||||
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access));
|
||||
shadowbios |= ((base >= 0xe0000) && (access & 0x02));
|
||||
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01));
|
||||
}
|
||||
base = 0x000a0000 + (i << 16) + (j << 13);
|
||||
access = (dev->regs[0x0d + i] >> j) & 3;
|
||||
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access));
|
||||
shadowbios |= ((base >= 0xe0000) && (access & 0x02));
|
||||
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01));
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vl82c480_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
vl82c480_t *dev = (vl82c480_t *)p;
|
||||
vl82c480_t *dev = (vl82c480_t *) p;
|
||||
|
||||
switch (addr) {
|
||||
case 0xec:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0xec:
|
||||
dev->idx = val;
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
if (dev->idx >= 0x01 && dev->idx <= 0x24) {
|
||||
switch (dev->idx) {
|
||||
default:
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x04:
|
||||
if (dev->regs[0x00] == 0x98)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf);
|
||||
break;
|
||||
case 0x0d: case 0x0e: case 0x0f: case 0x10:
|
||||
case 0x11: case 0x12:
|
||||
dev->regs[dev->idx] = val;
|
||||
vl82c480_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xed:
|
||||
if (dev->idx >= 0x01 && dev->idx <= 0x24) {
|
||||
switch (dev->idx) {
|
||||
default:
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x04:
|
||||
if (dev->regs[0x00] == 0x98)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf);
|
||||
break;
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
dev->regs[dev->idx] = val;
|
||||
vl82c480_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xee:
|
||||
if (mem_a20_alt)
|
||||
outb(0x92, inb(0x92) & ~2);
|
||||
break;
|
||||
case 0xee:
|
||||
if (mem_a20_alt)
|
||||
outb(0x92, inb(0x92) & ~2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
vl82c480_read(uint16_t addr, void *p)
|
||||
{
|
||||
vl82c480_t *dev = (vl82c480_t *)p;
|
||||
uint8_t ret = 0xff;
|
||||
vl82c480_t *dev = (vl82c480_t *) p;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0xec:
|
||||
ret = dev->idx;
|
||||
break;
|
||||
case 0xec:
|
||||
ret = dev->idx;
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
case 0xed:
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
|
||||
case 0xee:
|
||||
if (!mem_a20_alt)
|
||||
outb(0x92, inb(0x92) | 2);
|
||||
break;
|
||||
case 0xee:
|
||||
if (!mem_a20_alt)
|
||||
outb(0x92, inb(0x92) | 2);
|
||||
break;
|
||||
|
||||
case 0xef:
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
break;
|
||||
case 0xef:
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vl82c480_close(void *p)
|
||||
{
|
||||
vl82c480_t *dev = (vl82c480_t *)p;
|
||||
vl82c480_t *dev = (vl82c480_t *) p;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vl82c480_init(const device_t *info)
|
||||
{
|
||||
vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t));
|
||||
vl82c480_t *dev = (vl82c480_t *) malloc(sizeof(vl82c480_t));
|
||||
memset(dev, 0, sizeof(vl82c480_t));
|
||||
|
||||
dev->regs[0x00] = info->local;
|
||||
@@ -178,10 +176,10 @@ vl82c480_init(const device_t *info)
|
||||
dev->regs[0x03] = 0x88;
|
||||
dev->regs[0x06] = 0x1b;
|
||||
if (info->local == 0x98)
|
||||
dev->regs[0x07] = 0x21;
|
||||
dev->regs[0x07] = 0x21;
|
||||
dev->regs[0x08] = 0x38;
|
||||
|
||||
io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev);
|
||||
io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
@@ -189,29 +187,29 @@ vl82c480_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t vl82c480_device = {
|
||||
.name = "VLSI VL82c480",
|
||||
.name = "VLSI VL82c480",
|
||||
.internal_name = "vl82c480",
|
||||
.flags = 0,
|
||||
.local = 0x90,
|
||||
.init = vl82c480_init,
|
||||
.close = vl82c480_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0x90,
|
||||
.init = vl82c480_init,
|
||||
.close = vl82c480_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t vl82c486_device = {
|
||||
.name = "VLSI VL82c486",
|
||||
.name = "VLSI VL82c486",
|
||||
.internal_name = "vl82c486",
|
||||
.flags = 0,
|
||||
.local = 0x98,
|
||||
.init = vl82c480_init,
|
||||
.close = vl82c480_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0x98,
|
||||
.init = vl82c480_init,
|
||||
.close = vl82c480_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
/* Lock/Unlock Procedures */
|
||||
#define LOCK dev->lock
|
||||
#define LOCK dev->lock
|
||||
#define UNLOCKED !dev->lock
|
||||
|
||||
#ifdef ENABLE_WD76C10_LOG
|
||||
@@ -52,15 +52,14 @@ wd76c10_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (wd76c10_do_log)
|
||||
{
|
||||
if (wd76c10_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define wd76c10_log(fmt, ...)
|
||||
# define wd76c10_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
@@ -77,92 +76,90 @@ typedef struct
|
||||
|
||||
int lock;
|
||||
|
||||
fdc_t *fdc_controller;
|
||||
fdc_t *fdc_controller;
|
||||
mem_mapping_t *mem_mapping;
|
||||
serial_t *uart[2];
|
||||
serial_t *uart[2];
|
||||
} wd76c10_t;
|
||||
|
||||
static void wd76c10_refresh_control(wd76c10_t *dev)
|
||||
static void
|
||||
wd76c10_refresh_control(wd76c10_t *dev)
|
||||
{
|
||||
serial_remove(dev->uart[1]);
|
||||
/* Serial B */
|
||||
switch ((dev->refresh_control >> 1) & 7)
|
||||
{
|
||||
case 1:
|
||||
serial_setup(dev->uart[1], 0x3f8, 3);
|
||||
break;
|
||||
case 2:
|
||||
serial_setup(dev->uart[1], 0x2f8, 3);
|
||||
break;
|
||||
case 3:
|
||||
serial_setup(dev->uart[1], 0x3e8, 3);
|
||||
break;
|
||||
case 4:
|
||||
serial_setup(dev->uart[1], 0x2e8, 3);
|
||||
break;
|
||||
switch ((dev->refresh_control >> 1) & 7) {
|
||||
case 1:
|
||||
serial_setup(dev->uart[1], 0x3f8, 3);
|
||||
break;
|
||||
case 2:
|
||||
serial_setup(dev->uart[1], 0x2f8, 3);
|
||||
break;
|
||||
case 3:
|
||||
serial_setup(dev->uart[1], 0x3e8, 3);
|
||||
break;
|
||||
case 4:
|
||||
serial_setup(dev->uart[1], 0x2e8, 3);
|
||||
break;
|
||||
}
|
||||
|
||||
serial_remove(dev->uart[0]);
|
||||
/* Serial A */
|
||||
switch ((dev->refresh_control >> 5) & 7)
|
||||
{
|
||||
case 1:
|
||||
serial_setup(dev->uart[0], 0x3f8, 4);
|
||||
break;
|
||||
case 2:
|
||||
serial_setup(dev->uart[0], 0x2f8, 4);
|
||||
break;
|
||||
case 3:
|
||||
serial_setup(dev->uart[0], 0x3e8, 4);
|
||||
break;
|
||||
case 4:
|
||||
serial_setup(dev->uart[0], 0x2e8, 4);
|
||||
break;
|
||||
switch ((dev->refresh_control >> 5) & 7) {
|
||||
case 1:
|
||||
serial_setup(dev->uart[0], 0x3f8, 4);
|
||||
break;
|
||||
case 2:
|
||||
serial_setup(dev->uart[0], 0x2f8, 4);
|
||||
break;
|
||||
case 3:
|
||||
serial_setup(dev->uart[0], 0x3e8, 4);
|
||||
break;
|
||||
case 4:
|
||||
serial_setup(dev->uart[0], 0x2e8, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
lpt1_remove();
|
||||
/* LPT */
|
||||
switch ((dev->refresh_control >> 9) & 3)
|
||||
{
|
||||
case 1:
|
||||
lpt1_init(0x3bc);
|
||||
lpt1_irq(7);
|
||||
break;
|
||||
case 2:
|
||||
lpt1_init(0x378);
|
||||
lpt1_irq(7);
|
||||
break;
|
||||
case 3:
|
||||
lpt1_init(0x278);
|
||||
lpt1_irq(7);
|
||||
break;
|
||||
switch ((dev->refresh_control >> 9) & 3) {
|
||||
case 1:
|
||||
lpt1_init(0x3bc);
|
||||
lpt1_irq(7);
|
||||
break;
|
||||
case 2:
|
||||
lpt1_init(0x378);
|
||||
lpt1_irq(7);
|
||||
break;
|
||||
case 3:
|
||||
lpt1_init(0x278);
|
||||
lpt1_irq(7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void wd76c10_split_addr(wd76c10_t *dev)
|
||||
static void
|
||||
wd76c10_split_addr(wd76c10_t *dev)
|
||||
{
|
||||
switch ((dev->split_addr >> 8) & 3)
|
||||
{
|
||||
case 1:
|
||||
if (((dev->shadow_ram >> 8) & 3) == 2)
|
||||
mem_remap_top(256);
|
||||
break;
|
||||
case 2:
|
||||
if (((dev->shadow_ram >> 8) & 3) == 1)
|
||||
mem_remap_top(320);
|
||||
break;
|
||||
case 3:
|
||||
if (((dev->shadow_ram >> 8) & 3) == 3)
|
||||
mem_remap_top(384);
|
||||
break;
|
||||
switch ((dev->split_addr >> 8) & 3) {
|
||||
case 1:
|
||||
if (((dev->shadow_ram >> 8) & 3) == 2)
|
||||
mem_remap_top(256);
|
||||
break;
|
||||
case 2:
|
||||
if (((dev->shadow_ram >> 8) & 3) == 1)
|
||||
mem_remap_top(320);
|
||||
break;
|
||||
case 3:
|
||||
if (((dev->shadow_ram >> 8) & 3) == 3)
|
||||
mem_remap_top(384);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void wd76c10_disk_chip_select(wd76c10_t *dev)
|
||||
static void
|
||||
wd76c10_disk_chip_select(wd76c10_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
if (!(dev->disk_chip_select & 1))
|
||||
{
|
||||
if (!(dev->disk_chip_select & 1)) {
|
||||
ide_set_base(0, !(dev->disk_chip_select & 0x0010) ? 0x1f0 : 0x170);
|
||||
ide_set_side(0, !(dev->disk_chip_select & 0x0010) ? 0x3f6 : 0x376);
|
||||
}
|
||||
@@ -173,259 +170,254 @@ static void wd76c10_disk_chip_select(wd76c10_t *dev)
|
||||
fdc_set_base(dev->fdc_controller, !(dev->disk_chip_select & 0x0010) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR);
|
||||
}
|
||||
|
||||
static void wd76c10_shadow_recalc(wd76c10_t *dev)
|
||||
static void
|
||||
wd76c10_shadow_recalc(wd76c10_t *dev)
|
||||
{
|
||||
switch ((dev->shadow_ram >> 14) & 3)
|
||||
{
|
||||
case 0:
|
||||
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(0x80000, 0x20000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(0x40000, 0x60000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
break;
|
||||
switch ((dev->shadow_ram >> 14) & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(0x80000, 0x20000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(0x40000, 0x60000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((dev->shadow_ram >> 8) & 3)
|
||||
{
|
||||
case 0:
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
break;
|
||||
switch ((dev->shadow_ram >> 8) & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wd76c10_write(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
wd76c10_t *dev = (wd76c10_t *) priv;
|
||||
|
||||
if (UNLOCKED)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1072:
|
||||
dev->clk_control = val;
|
||||
break;
|
||||
if (UNLOCKED) {
|
||||
switch (addr) {
|
||||
case 0x1072:
|
||||
dev->clk_control = val;
|
||||
break;
|
||||
|
||||
case 0x1872:
|
||||
dev->bus_timing_power_down_ctl = val;
|
||||
break;
|
||||
case 0x1872:
|
||||
dev->bus_timing_power_down_ctl = val;
|
||||
break;
|
||||
|
||||
case 0x2072:
|
||||
dev->refresh_control = val;
|
||||
wd76c10_refresh_control(dev);
|
||||
break;
|
||||
case 0x2072:
|
||||
dev->refresh_control = val;
|
||||
wd76c10_refresh_control(dev);
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
dev->disk_chip_select = val;
|
||||
wd76c10_disk_chip_select(dev);
|
||||
break;
|
||||
case 0x2872:
|
||||
dev->disk_chip_select = val;
|
||||
wd76c10_disk_chip_select(dev);
|
||||
break;
|
||||
|
||||
case 0x3072:
|
||||
dev->prog_chip_sel_addr = val;
|
||||
break;
|
||||
case 0x3072:
|
||||
dev->prog_chip_sel_addr = val;
|
||||
break;
|
||||
|
||||
case 0x3872:
|
||||
dev->non_page_mode_dram_timing = val;
|
||||
break;
|
||||
case 0x3872:
|
||||
dev->non_page_mode_dram_timing = val;
|
||||
break;
|
||||
|
||||
case 0x4072:
|
||||
dev->mem_control = val;
|
||||
break;
|
||||
case 0x4072:
|
||||
dev->mem_control = val;
|
||||
break;
|
||||
|
||||
case 0x4872:
|
||||
dev->bank10staddr = val;
|
||||
break;
|
||||
case 0x4872:
|
||||
dev->bank10staddr = val;
|
||||
break;
|
||||
|
||||
case 0x5072:
|
||||
dev->bank32staddr = val;
|
||||
break;
|
||||
case 0x5072:
|
||||
dev->bank32staddr = val;
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
dev->split_addr = val;
|
||||
wd76c10_split_addr(dev);
|
||||
break;
|
||||
case 0x5872:
|
||||
dev->split_addr = val;
|
||||
wd76c10_split_addr(dev);
|
||||
break;
|
||||
|
||||
case 0x6072:
|
||||
dev->shadow_ram = val & 0xffbf;
|
||||
wd76c10_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x6072:
|
||||
dev->shadow_ram = val & 0xffbf;
|
||||
wd76c10_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x6872:
|
||||
dev->ems_control_low_address_boundry = val & 0xecff;
|
||||
break;
|
||||
case 0x6872:
|
||||
dev->ems_control_low_address_boundry = val & 0xecff;
|
||||
break;
|
||||
|
||||
case 0x7072:
|
||||
dev->pmc_output = (val >> 8) & 0x00ff;
|
||||
break;
|
||||
case 0x7072:
|
||||
dev->pmc_output = (val >> 8) & 0x00ff;
|
||||
break;
|
||||
|
||||
case 0x7872:
|
||||
dev->pmc_output = val & 0xff00;
|
||||
break;
|
||||
case 0x7872:
|
||||
dev->pmc_output = val & 0xff00;
|
||||
break;
|
||||
|
||||
case 0x8072:
|
||||
dev->pmc_timer = val;
|
||||
break;
|
||||
case 0x8072:
|
||||
dev->pmc_timer = val;
|
||||
break;
|
||||
|
||||
case 0x8872:
|
||||
dev->pmc_input = val;
|
||||
break;
|
||||
case 0x8872:
|
||||
dev->pmc_input = val;
|
||||
break;
|
||||
|
||||
case 0x9072:
|
||||
dev->nmi_status = val & 0x00fc;
|
||||
break;
|
||||
case 0x9072:
|
||||
dev->nmi_status = val & 0x00fc;
|
||||
break;
|
||||
|
||||
case 0x9872:
|
||||
dev->diagnostic = val & 0xfdff;
|
||||
break;
|
||||
case 0x9872:
|
||||
dev->diagnostic = val & 0xfdff;
|
||||
break;
|
||||
|
||||
case 0xa072:
|
||||
dev->delay_line = val;
|
||||
break;
|
||||
case 0xa072:
|
||||
dev->delay_line = val;
|
||||
break;
|
||||
|
||||
case 0xc872:
|
||||
dev->pmc_interrupt = val & 0xfcfc;
|
||||
break;
|
||||
case 0xc872:
|
||||
dev->pmc_interrupt = val & 0xfcfc;
|
||||
break;
|
||||
|
||||
case 0xf072:
|
||||
dev->oscillator_40mhz = 0;
|
||||
break;
|
||||
case 0xf072:
|
||||
dev->oscillator_40mhz = 0;
|
||||
break;
|
||||
|
||||
case 0xf472:
|
||||
dev->oscillator_40mhz = 1;
|
||||
break;
|
||||
case 0xf472:
|
||||
dev->oscillator_40mhz = 1;
|
||||
break;
|
||||
|
||||
case 0xf872:
|
||||
dev->cache_flush = val;
|
||||
flushmmucache();
|
||||
break;
|
||||
case 0xf872:
|
||||
dev->cache_flush = val;
|
||||
flushmmucache();
|
||||
break;
|
||||
}
|
||||
wd76c10_log("WD76C10: dev->regs[%04x] = %04x\n", addr, val);
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0xe072:
|
||||
dev->ems_page_reg_pointer = val & 0x003f;
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0xe072:
|
||||
dev->ems_page_reg_pointer = val & 0x003f;
|
||||
break;
|
||||
|
||||
case 0xe872:
|
||||
dev->ems_page_reg = val & 0x8fff;
|
||||
break;
|
||||
case 0xe872:
|
||||
dev->ems_page_reg = val & 0x8fff;
|
||||
break;
|
||||
|
||||
case 0xf073:
|
||||
dev->lock_reg = val & 0x00ff;
|
||||
LOCK = !(val & 0x00da);
|
||||
break;
|
||||
case 0xf073:
|
||||
dev->lock_reg = val & 0x00ff;
|
||||
LOCK = !(val & 0x00da);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
wd76c10_read(uint16_t addr, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
wd76c10_t *dev = (wd76c10_t *) priv;
|
||||
wd76c10_log("WD76C10: R dev->regs[%04x]\n", addr);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1072:
|
||||
return dev->clk_control;
|
||||
switch (addr) {
|
||||
case 0x1072:
|
||||
return dev->clk_control;
|
||||
|
||||
case 0x1872:
|
||||
return dev->bus_timing_power_down_ctl;
|
||||
case 0x1872:
|
||||
return dev->bus_timing_power_down_ctl;
|
||||
|
||||
case 0x2072:
|
||||
return dev->refresh_control;
|
||||
case 0x2072:
|
||||
return dev->refresh_control;
|
||||
|
||||
case 0x2872:
|
||||
return dev->disk_chip_select;
|
||||
case 0x2872:
|
||||
return dev->disk_chip_select;
|
||||
|
||||
case 0x3072:
|
||||
return dev->prog_chip_sel_addr;
|
||||
case 0x3072:
|
||||
return dev->prog_chip_sel_addr;
|
||||
|
||||
case 0x3872:
|
||||
return dev->non_page_mode_dram_timing;
|
||||
case 0x3872:
|
||||
return dev->non_page_mode_dram_timing;
|
||||
|
||||
case 0x4072:
|
||||
return dev->mem_control;
|
||||
case 0x4072:
|
||||
return dev->mem_control;
|
||||
|
||||
case 0x4872:
|
||||
return dev->bank10staddr;
|
||||
case 0x4872:
|
||||
return dev->bank10staddr;
|
||||
|
||||
case 0x5072:
|
||||
return dev->bank32staddr;
|
||||
case 0x5072:
|
||||
return dev->bank32staddr;
|
||||
|
||||
case 0x5872:
|
||||
return dev->split_addr;
|
||||
case 0x5872:
|
||||
return dev->split_addr;
|
||||
|
||||
case 0x6072:
|
||||
return dev->shadow_ram;
|
||||
case 0x6072:
|
||||
return dev->shadow_ram;
|
||||
|
||||
case 0x6872:
|
||||
return dev->ems_control_low_address_boundry;
|
||||
case 0x6872:
|
||||
return dev->ems_control_low_address_boundry;
|
||||
|
||||
case 0x7072:
|
||||
return (dev->pmc_output << 8) & 0xff00;
|
||||
case 0x7072:
|
||||
return (dev->pmc_output << 8) & 0xff00;
|
||||
|
||||
case 0x7872:
|
||||
return (dev->pmc_output) & 0xff00;
|
||||
case 0x7872:
|
||||
return (dev->pmc_output) & 0xff00;
|
||||
|
||||
case 0x8072:
|
||||
return dev->pmc_timer;
|
||||
case 0x8072:
|
||||
return dev->pmc_timer;
|
||||
|
||||
case 0x8872:
|
||||
return dev->pmc_input;
|
||||
case 0x8872:
|
||||
return dev->pmc_input;
|
||||
|
||||
case 0x9072:
|
||||
return dev->nmi_status;
|
||||
case 0x9072:
|
||||
return dev->nmi_status;
|
||||
|
||||
case 0x9872:
|
||||
return dev->diagnostic;
|
||||
case 0x9872:
|
||||
return dev->diagnostic;
|
||||
|
||||
case 0xa072:
|
||||
return dev->delay_line;
|
||||
case 0xa072:
|
||||
return dev->delay_line;
|
||||
|
||||
case 0xb872:
|
||||
return (inb(0x040b) << 8) | inb(0x04d6);
|
||||
case 0xb872:
|
||||
return (inb(0x040b) << 8) | inb(0x04d6);
|
||||
|
||||
case 0xc872:
|
||||
return dev->pmc_interrupt;
|
||||
case 0xc872:
|
||||
return dev->pmc_interrupt;
|
||||
|
||||
case 0xd072:
|
||||
return dev->port_shadow;
|
||||
case 0xd072:
|
||||
return dev->port_shadow;
|
||||
|
||||
case 0xe072:
|
||||
return dev->ems_page_reg_pointer;
|
||||
case 0xe072:
|
||||
return dev->ems_page_reg_pointer;
|
||||
|
||||
case 0xe872:
|
||||
return dev->ems_page_reg;
|
||||
case 0xe872:
|
||||
return dev->ems_page_reg;
|
||||
|
||||
case 0xfc72:
|
||||
return 0x0ff0;
|
||||
case 0xfc72:
|
||||
return 0x0ff0;
|
||||
|
||||
default:
|
||||
return 0xffff;
|
||||
default:
|
||||
return 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wd76c10_close(void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
wd76c10_t *dev = (wd76c10_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -433,12 +425,12 @@ wd76c10_close(void *priv)
|
||||
static void *
|
||||
wd76c10_init(const device_t *info)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)malloc(sizeof(wd76c10_t));
|
||||
wd76c10_t *dev = (wd76c10_t *) malloc(sizeof(wd76c10_t));
|
||||
memset(dev, 0, sizeof(wd76c10_t));
|
||||
|
||||
device_add(&port_92_inv_device);
|
||||
dev->uart[0] = device_add_inst(&ns16450_device, 1);
|
||||
dev->uart[1] = device_add_inst(&ns16450_device, 2);
|
||||
dev->uart[0] = device_add_inst(&ns16450_device, 1);
|
||||
dev->uart[1] = device_add_inst(&ns16450_device, 2);
|
||||
dev->fdc_controller = device_add(&fdc_at_device);
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
@@ -536,15 +528,15 @@ wd76c10_init(const device_t *info)
|
||||
}
|
||||
|
||||
const device_t wd76c10_device = {
|
||||
.name = "Western Digital WD76C10",
|
||||
.name = "Western Digital WD76C10",
|
||||
.internal_name = "wd76c10",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = wd76c10_init,
|
||||
.close = wd76c10_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = wd76c10_init,
|
||||
.close = wd76c10_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user