SiS 471 fixes - fixes the DTK 486 hang.

This commit is contained in:
OBattler
2022-10-23 05:06:52 +02:00
parent a64be0bfea
commit 021a63e782
2 changed files with 200 additions and 23 deletions

View File

@@ -38,12 +38,25 @@ typedef struct
uint8_t cur_reg, tries,
reg_base, reg_last,
reg_00, is_471,
force_flush, shadowed,
smram_enabled, pad,
regs[39], scratch[2];
uint32_t mem_state[8];
smram_t *smram;
port_92_t *port_92;
} sis_85c4xx_t;
static void
sis_85c4xx_recalcremap(sis_85c4xx_t *dev)
{
if (dev->is_471) {
if ((mem_size > 8192) || (dev->shadowed & 0x3c) || (dev->regs[0x0b] & 0x02))
mem_remap_top(0);
else
mem_remap_top(-256);
}
}
static void
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
{
@@ -52,6 +65,8 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
uint32_t readext, writeext;
uint8_t romcs = 0xc0, cur_romcs;
dev->shadowed = 0x00;
shadowbios = 0;
shadowbios_write = 0;
@@ -73,25 +88,34 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
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) {
if (dev->regs[0x02] & 0x80)
dev->shadowed |= (1 << i);
if (!(dev->regs[0x02] & 0x40))
dev->shadowed |= (1 << i);
if (dev->force_flush || (dev->mem_state[i] != shflags)) {
n++;
mem_set_mem_state(base, 0x8000, shflags);
mem_set_mem_state_both(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) {
if (dev->force_flush || (dev->mem_state[i] != shflags)) {
n++;
mem_set_mem_state(base, 0x8000, shflags);
mem_set_mem_state_both(base, 0x8000, shflags);
dev->mem_state[i] = shflags;
}
}
}
if (n > 0)
if (dev->force_flush) {
flushmmucache();
dev->force_flush = 0;
} else if (n > 0)
flushmmucache_nopc();
sis_85c4xx_recalcremap(dev);
}
static void
@@ -158,12 +182,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
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);
}
if (valxor & 0x02)
sis_85c4xx_recalcremap(dev);
break;
case 0x13:
@@ -184,8 +204,10 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
ram_base = 0x00000000;
break;
}
dev->smram_enabled = (ram_base != 0x00000000);
if (ram_base != 0x00000000)
smram_enable(dev->smram, host_base, ram_base, 0x00010000, (val & 0x10), 1);
sis_85c4xx_recalcremap(dev);
}
break;
@@ -289,7 +311,6 @@ sis_85c4xx_reset(void *priv)
port_92_remove(dev->port_92);
mem_remap_top(256);
soft_reset_mask = 0;
} else {
/* Bits 6 and 7 must be clear on the SiS 40x. */
@@ -309,6 +330,7 @@ sis_85c4xx_reset(void *priv)
cpu_cache_ext_enabled = 0;
cpu_update_waitstates();
dev->force_flush = 1;
sis_85c4xx_recalcmapping(dev);
}

View File

@@ -55,11 +55,12 @@
#endif
mem_mapping_t ram_low_mapping, /* 0..640K mapping */
ram_mid_mapping,
ram_mid_mapping, /* 640..1024K mapping */
ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */
ram_remapped_mapping, /* 640..1024K mapping */
ram_remapped_mapping2,/* 640..1024K second mapping, for SiS 471 mode */
ram_high_mapping, /* 1024K+ mapping */
ram_2gb_mapping, /* 1024M+ mapping */
ram_remapped_mapping,
ram_split_mapping,
bios_mapping,
bios_high_mapping;
@@ -71,6 +72,7 @@ uint32_t pages_sz; /* #pages in table */
uint8_t *ram, *ram2; /* the virtual RAM */
uint8_t page_ff[4096];
uint32_t rammask;
uint32_t addr_space_size;
uint8_t *rom; /* the virtual ROM */
uint32_t biosmask, biosaddr;
@@ -127,7 +129,7 @@ static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO];
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
static mem_state_t _mem_state[MEM_MAPPINGS_NO];
static uint32_t remap_start_addr;
static uint32_t remap_start_addr, remap_start_addr2;
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
static size_t ram_size = 0, ram2_size = 0;
#else
@@ -157,7 +159,8 @@ mem_addr_is_ram(uint32_t addr)
{
mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS];
return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_remapped_mapping);
return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) ||
(mapping == &ram_mid_mapping2) || (mapping == &ram_remapped_mapping);
}
void
@@ -2087,6 +2090,33 @@ mem_read_remappedl(uint32_t addr, void *priv)
return *(uint32_t *) &ram[addr];
}
static uint8_t
mem_read_remapped2(uint32_t addr, void *priv)
{
addr = 0xD0000 + (addr - remap_start_addr2);
if (is286)
addreadlookup(mem_logical_addr, addr);
return ram[addr];
}
static uint16_t
mem_read_remappedw2(uint32_t addr, void *priv)
{
addr = 0xD0000 + (addr - remap_start_addr2);
if (is286)
addreadlookup(mem_logical_addr, addr);
return *(uint16_t *) &ram[addr];
}
static uint32_t
mem_read_remappedl2(uint32_t addr, void *priv)
{
addr = 0xD0000 + (addr - remap_start_addr2);
if (is286)
addreadlookup(mem_logical_addr, addr);
return *(uint32_t *) &ram[addr];
}
static void
mem_write_remapped(uint32_t addr, uint8_t val, void *priv)
{
@@ -2123,6 +2153,42 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv)
*(uint32_t *) &ram[addr] = val;
}
static void
mem_write_remapped2(uint32_t addr, uint8_t val, void *priv)
{
uint32_t oldaddr = addr;
addr = 0xD0000 + (addr - remap_start_addr2);
if (is286) {
addwritelookup(mem_logical_addr, addr);
mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]);
} else
ram[addr] = val;
}
static void
mem_write_remappedw2(uint32_t addr, uint16_t val, void *priv)
{
uint32_t oldaddr = addr;
addr = 0xD0000 + (addr - remap_start_addr2);
if (is286) {
addwritelookup(mem_logical_addr, addr);
mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]);
} else
*(uint16_t *) &ram[addr] = val;
}
static void
mem_write_remappedl2(uint32_t addr, uint32_t val, void *priv)
{
uint32_t oldaddr = addr;
addr = 0xD0000 + (addr - remap_start_addr2);
if (is286) {
addwritelookup(mem_logical_addr, addr);
mem_write_raml_page(addr, val, &pages[oldaddr >> 12]);
} else
*(uint32_t *) &ram[addr] = val;
}
void
mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
{
@@ -2605,6 +2671,8 @@ mem_reset(void)
m = 256;
}
addr_space_size = m;
/*
* Allocate and initialize the (new) page table.
*/
@@ -2687,15 +2755,26 @@ mem_reset(void)
}
}
if (mem_size > 768)
if (mem_size > 768) {
mem_add_ram_mapping(&ram_mid_mapping, 0xa0000, 0x60000);
mem_add_ram_mapping(&ram_mid_mapping2, 0xa0000, 0x60000);
mem_mapping_disable(&ram_mid_mapping2);
}
mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
mem_read_remapped, mem_read_remappedw, mem_read_remappedl,
mem_write_remapped, mem_write_remappedw, mem_write_remappedl,
ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
mem_mapping_disable(&ram_remapped_mapping);
/* Mapping for SiS 471 relocation which relocates A0000-BFFFF, D0000-EFFFF, which is non-contiguous. */
mem_mapping_add(&ram_remapped_mapping2, mem_size * 1024, 256 * 1024,
mem_read_remapped2, mem_read_remappedw2, mem_read_remappedl2,
mem_write_remapped2, mem_write_remappedw2, mem_write_remappedl2,
ram + 0xd0000, MEM_MAPPING_INTERNAL, NULL);
mem_mapping_disable(&ram_remapped_mapping2);
mem_a20_init();
#ifdef USE_NEW_DYNAREC
@@ -2729,11 +2808,19 @@ mem_remap_top(int kb)
int offset, size = mem_size - 640;
int set = 1;
static int old_kb = 0;
int sis_mode = 0;
uint32_t start_addr = 0, addr = 0;
mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size);
if (mem_size <= 640)
return;
/* SiS 471 special mode. */
if (kb == -256) {
kb = 256;
sis_mode = 1;
}
if (kb == 0) {
kb = old_kb;
set = 0;
@@ -2744,27 +2831,95 @@ mem_remap_top(int kb)
size = kb;
remap_start_addr = start << 10;
remap_start_addr2 = (start << 10) + 0x00020000;
for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) {
offset = c - ((start * 1024) >> 12);
pages[c].mem = set ? &ram[0xa0000 + (offset << 12)] : page_ff;
/* Use A0000-BFFFF, D0000-EFFFF instead of C0000-DFFFF, E0000-FFFFF. */
addr = 0xa0000 + (offset << 12);
if (sis_mode) {
/* A0000-DFFFF -> A0000-BFFFF, D0000-EFFFF */
if (addr >= 0x000c0000)
addr += 0x00010000;
}
if (start_addr != 0)
start_addr = addr;
pages[c].mem = set ? &ram[addr] : page_ff;
pages[c].write_b = set ? mem_write_ramb_page : NULL;
pages[c].write_w = set ? mem_write_ramw_page : NULL;
pages[c].write_l = set ? mem_write_raml_page : NULL;
#ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64];
pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64];
pages[c].byte_dirty_mask = &byte_dirty_mask[(addr >> 12) * 64];
pages[c].byte_code_present_mask = &byte_code_present_mask[(addr >> 12) * 64];
#endif
}
mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
for (c = 0xa0; c < 0xf0; c++) {
if ((c >= 0xc0) && (c <= 0xcf))
continue;
if (sis_mode || ((c << 12) >= (mem_size << 10)))
pages[c].mem = page_ff;
else {
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
if (mem_size > 1048576) {
if ((c << 12) < (1 << 30))
pages[c].mem = &ram[c << 12];
else
pages[c].mem = &ram2[(c << 12) - (1 << 30)];
} else
pages[c].mem = &ram[c << 12];
#else
pages[c].mem = &ram[c << 12];
#endif
}
if (!sis_mode && (c < addr_space_size)) {
pages[c].write_b = mem_write_ramb_page;
pages[c].write_w = mem_write_ramw_page;
pages[c].write_l = mem_write_raml_page;
} else {
pages[c].write_b = NULL;
pages[c].write_w = NULL;
pages[c].write_l = NULL;
}
#ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64];
pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64];
#endif
}
if (set) {
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
mem_mapping_set_exec(&ram_remapped_mapping, ram + 0xa0000);
} else
if (sis_mode) {
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, 0x00020000);
mem_mapping_set_exec(&ram_remapped_mapping, ram + 0x000a0000);
mem_mapping_set_addr(&ram_remapped_mapping2, (start * 1024) + 0x00020000, 0x00020000);
mem_mapping_set_exec(&ram_remapped_mapping2, ram + 0x000d0000);
mem_mapping_set_addr(&ram_mid_mapping, 0x000c0000, 0x00010000);
mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000c0000);
mem_mapping_set_addr(&ram_mid_mapping2, 0x000f0000, 0x00010000);
mem_mapping_set_exec(&ram_mid_mapping2, ram + 0x000f0000);
} else {
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
mem_mapping_set_exec(&ram_remapped_mapping, ram + start_addr);
mem_mapping_disable(&ram_remapped_mapping2);
mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000);
mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000);
mem_mapping_disable(&ram_mid_mapping2);
}
} else {
mem_mapping_disable(&ram_remapped_mapping);
mem_mapping_disable(&ram_remapped_mapping2);
mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000);
mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000);
mem_mapping_disable(&ram_mid_mapping2);
}
flushmmucache();
}