clang-format in src/chipset/

This commit is contained in:
Jasmine Iwanek
2022-09-18 17:12:38 -04:00
parent d044f8d1f6
commit 3753a9f8b2
49 changed files with 15766 additions and 15762 deletions

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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

View File

@@ -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
};

View File

@@ -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

View File

@@ -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

View File

@@ -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
};

File diff suppressed because it is too large Load Diff

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

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

File diff suppressed because it is too large Load Diff

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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

View File

@@ -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
};

View File

@@ -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

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};