Prepare WD76C10 for 286/386 interpreter selection, exempt IBM 486BL and all Cyrix'es from the 286/386 interpreter.

This commit is contained in:
OBattler
2024-04-24 06:06:09 +02:00
parent 7feb6f578d
commit 15e3876e21
4 changed files with 79 additions and 15 deletions

View File

@@ -84,6 +84,7 @@ typedef struct
uint8_t bios_states[8]; uint8_t bios_states[8];
uint8_t high_bios_states[8]; uint8_t high_bios_states[8];
uint8_t mem_pages[1024]; uint8_t mem_pages[1024];
uint8_t ram_state[4192];
uint16_t toggle, cpuclk, fpu_ctl, mem_ctl, uint16_t toggle, cpuclk, fpu_ctl, mem_ctl,
split_sa, sh_wp, hmwpb, npmdmt, split_sa, sh_wp, hmwpb, npmdmt,
@@ -225,6 +226,34 @@ wd76c10_write_ramw(uint32_t addr, uint16_t val, void *priv)
mem_write_ramw(addr, val, priv); mem_write_ramw(addr, val, priv);
} }
static void
wd76c10_set_mem_state(wd76c10_t *dev, uint32_t base, uint32_t size, uint32_t access, uint8_t present)
{
mem_set_mem_state_both(base, size, access);
for (uint32_t i = base; i < (base + size); i += 4096)
dev->ram_state[i >> 12] = present;
}
static void
wd76c10_recalc_exec(wd76c10_t *dev, uint32_t base, uint32_t size)
{
uint32_t logical_addr = wd76c10_calc_addr(dev, base);
void *exec;
if (logical_addr != WD76C10_ADDR_INVALID)
exec = &(ram[logical_addr]);
else
exec = NULL;
for (uint32_t i = base; i < (base + size); i += 4096)
if (dev->ram_state[i >> 12])
_mem_exec[i >> 12] = exec;
if (cpu_use_exec)
flushmmucache_nopc();
}
static void static void
wd76c10_banks_recalc(wd76c10_t *dev) wd76c10_banks_recalc(wd76c10_t *dev)
{ {
@@ -235,6 +264,9 @@ wd76c10_banks_recalc(wd76c10_t *dev)
bit = i + 12; bit = i + 12;
rb->enable = (dev->split_sa >> bit) & 0x01; rb->enable = (dev->split_sa >> bit) & 0x01;
rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17; rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17;
if (cpu_use_exec)
wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size);
} }
} }
@@ -245,8 +277,12 @@ wd76c10_split_recalc(wd76c10_t *dev)
uint32_t split_size = ((sp_size - 1) * 65536); uint32_t split_size = ((sp_size - 1) * 65536);
ram_bank_t *rb = &(dev->ram_banks[4]); ram_bank_t *rb = &(dev->ram_banks[4]);
if (rb->enable && (rb->virt_size != 0x00000000)) if (rb->enable && (rb->virt_size != 0x00000000)) {
mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); wd76c10_set_mem_state(dev, rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY, 0);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size);
}
rb->virt_addr = ((uint32_t) ((dev->split_sa >> 2) & 0x3f)) << 19; rb->virt_addr = ((uint32_t) ((dev->split_sa >> 2) & 0x3f)) << 19;
switch (sp_size) { switch (sp_size) {
case 0x00: case 0x00:
@@ -257,8 +293,12 @@ wd76c10_split_recalc(wd76c10_t *dev)
break; break;
} }
rb->enable = !!sp_size; rb->enable = !!sp_size;
if (rb->enable && (rb->virt_size != 0x00000000)) if (rb->enable && (rb->virt_size != 0x00000000)) {
mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); wd76c10_set_mem_state(dev, rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, 1);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size);
}
} }
static void static void
@@ -287,7 +327,7 @@ wd76c10_dis_mem_recalc(wd76c10_t *dev)
} }
static void static void
wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) wd76c10_shadow_ram_do_recalc(wd76c10_t *dev, uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr)
{ {
uint32_t base = 0x00000000; uint32_t base = 0x00000000;
int flags = 0; int flags = 0;
@@ -300,7 +340,9 @@ wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint
((new_st[i] & 0x04) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL); ((new_st[i] & 0x04) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL);
flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL : flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL :
((new_st[i] & 0x04) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL); ((new_st[i] & 0x04) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL);
mem_set_mem_state_both(base, 0x00004000, flags); wd76c10_set_mem_state(dev, base, 0x00004000, flags, new_st[i] & 0x01);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, base, 0x000040000);
} }
} }
} }
@@ -366,11 +408,11 @@ wd76c10_shadow_ram_recalc(wd76c10_t *dev)
break; break;
} }
wd76c10_shadow_ram_do_recalc(vbios_states, dev->vbios_states, 0, 4, 0x000c0000); wd76c10_shadow_ram_do_recalc(dev, vbios_states, dev->vbios_states, 0, 4, 0x000c0000);
wd76c10_shadow_ram_do_recalc(bios_states, dev->bios_states, 0, 8, 0x000e0000); wd76c10_shadow_ram_do_recalc(dev, bios_states, dev->bios_states, 0, 8, 0x000e0000);
/* This is not shadowed, but there is a CSPROM# (= ROMCS#) toggle. */ /* This is not shadowed, but there is a CSPROM# (= ROMCS#) toggle. */
wd76c10_shadow_ram_do_recalc(high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); wd76c10_shadow_ram_do_recalc(dev, high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000);
flushmmucache_nopc(); flushmmucache_nopc();
} }
@@ -385,9 +427,15 @@ wd76c10_high_mem_wp_recalc(wd76c10_t *dev)
/* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */ /* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */
mem_set_wp(dev->hmwp_base, size, ACCESS_NORMAL, 0); mem_set_wp(dev->hmwp_base, size, ACCESS_NORMAL, 0);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, dev->hmwp_base, size);
size = 0x01000000 - base; size = 0x01000000 - base;
mem_set_wp(base, size, ACCESS_NORMAL, hm_wp); mem_set_wp(base, size, ACCESS_NORMAL, hm_wp);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, base, size);
dev->hmwp_base = base; dev->hmwp_base = base;
} }
@@ -399,7 +447,10 @@ wd76c10_pf_loc_reset(wd76c10_t *dev)
for (uint8_t i = 0x031; i <= 0x03b; i++) { for (uint8_t i = 0x031; i <= 0x03b; i++) {
dev->mem_pages[i] = 0xff; dev->mem_pages[i] = 0xff;
base = ((uint32_t) i) << 14; base = ((uint32_t) i) << 14;
mem_set_mem_state(base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); wd76c10_set_mem_state(dev, base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY, 0);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, base, 0x00004000);
} }
/* Re-apply any ROMCS#, etc. flags. */ /* Re-apply any ROMCS#, etc. flags. */
@@ -419,9 +470,13 @@ wd76c10_pf_loc_recalc(wd76c10_t *dev)
dev->mem_pages[i] = ems_page; dev->mem_pages[i] = ems_page;
base = ((uint32_t) i) << 14; base = ((uint32_t) i) << 14;
dev->ems_pages[ems_page].virt = base; dev->ems_pages[ems_page].virt = base;
if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) {
mem_set_mem_state(dev->ems_pages[ems_page].virt, 0x00004000, wd76c10_set_mem_state(dev, dev->ems_pages[ems_page].virt,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, 1);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, dev->ems_pages[ems_page].virt, 0x00004000);
}
} }
} }
@@ -436,6 +491,9 @@ wd76c10_low_pages_recalc(wd76c10_t *dev)
dev->mem_pages[i] = ems_page; dev->mem_pages[i] = ems_page;
base = ((uint32_t) i) << 14; base = ((uint32_t) i) << 14;
dev->ems_pages[ems_page].virt = base; dev->ems_pages[ems_page].virt = base;
if (cpu_use_exec)
wd76c10_recalc_exec(dev, dev->ems_pages[ems_page].virt, 0x00004000);
} }
} }
@@ -948,6 +1006,8 @@ wd76c10_init(const device_t *info)
mem_mapping_disable(&ram_high_mapping); mem_mapping_disable(&ram_high_mapping);
mem_mapping_enable(&dev->ram_mapping); mem_mapping_enable(&dev->ram_mapping);
memset(dev->ram_state, 0x00, sizeof(dev->ram_state));
return dev; return dev;
} }

View File

@@ -1803,7 +1803,8 @@ cpu_set(void)
} else } else
#endif #endif
/* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */
if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) { if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) ||
cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC)) {
cpu_exec = exec386; cpu_exec = exec386;
cpu_use_exec = 1; cpu_use_exec = 1;
} else } else

View File

@@ -302,6 +302,8 @@ extern int memspeed[11];
extern int mmu_perm; extern int mmu_perm;
extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern uint8_t high_page; /* if a high (> 4 gb) page was detected */
extern uint8_t *_mem_exec[MEM_MAPPINGS_NO];
extern uint32_t pages_sz; /* #pages in table */ extern uint32_t pages_sz; /* #pages in table */
extern int read_type; extern int read_type;

View File

@@ -123,6 +123,8 @@ uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */
mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
uint8_t *_mem_exec[MEM_MAPPINGS_NO];
/* FIXME: re-do this with a 'mem_ops' struct. */ /* FIXME: re-do this with a 'mem_ops' struct. */
static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */
static uint8_t *readlookupp; static uint8_t *readlookupp;
@@ -131,7 +133,6 @@ static mem_mapping_t *base_mapping;
static mem_mapping_t *last_mapping; static mem_mapping_t *last_mapping;
static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO];
static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO];
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
static uint8_t _mem_wp[MEM_MAPPINGS_NO]; static uint8_t _mem_wp[MEM_MAPPINGS_NO];
static uint8_t _mem_wp_bus[MEM_MAPPINGS_NO]; static uint8_t _mem_wp_bus[MEM_MAPPINGS_NO];
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };