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 high_bios_states[8];
uint8_t mem_pages[1024];
uint8_t ram_state[4192];
uint16_t toggle, cpuclk, fpu_ctl, mem_ctl,
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);
}
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
wd76c10_banks_recalc(wd76c10_t *dev)
{
@@ -235,6 +264,9 @@ wd76c10_banks_recalc(wd76c10_t *dev)
bit = i + 12;
rb->enable = (dev->split_sa >> bit) & 0x01;
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);
ram_bank_t *rb = &(dev->ram_banks[4]);
if (rb->enable && (rb->virt_size != 0x00000000))
mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if (rb->enable && (rb->virt_size != 0x00000000)) {
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;
switch (sp_size) {
case 0x00:
@@ -257,8 +293,12 @@ wd76c10_split_recalc(wd76c10_t *dev)
break;
}
rb->enable = !!sp_size;
if (rb->enable && (rb->virt_size != 0x00000000))
mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
if (rb->enable && (rb->virt_size != 0x00000000)) {
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
@@ -287,7 +327,7 @@ wd76c10_dis_mem_recalc(wd76c10_t *dev)
}
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;
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);
flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL :
((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;
}
wd76c10_shadow_ram_do_recalc(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, vbios_states, dev->vbios_states, 0, 4, 0x000c0000);
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. */
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();
}
@@ -385,9 +427,15 @@ wd76c10_high_mem_wp_recalc(wd76c10_t *dev)
/* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */
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;
mem_set_wp(base, size, ACCESS_NORMAL, hm_wp);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, base, size);
dev->hmwp_base = base;
}
@@ -399,7 +447,10 @@ wd76c10_pf_loc_reset(wd76c10_t *dev)
for (uint8_t i = 0x031; i <= 0x03b; i++) {
dev->mem_pages[i] = 0xff;
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. */
@@ -419,9 +470,13 @@ wd76c10_pf_loc_recalc(wd76c10_t *dev)
dev->mem_pages[i] = ems_page;
base = ((uint32_t) i) << 14;
dev->ems_pages[ems_page].virt = base;
if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled)
mem_set_mem_state(dev->ems_pages[ems_page].virt, 0x00004000,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) {
wd76c10_set_mem_state(dev, dev->ems_pages[ems_page].virt,
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;
base = ((uint32_t) i) << 14;
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_enable(&dev->ram_mapping);
memset(dev->ram_state, 0x00, sizeof(dev->ram_state));
return dev;
}

View File

@@ -1803,7 +1803,8 @@ cpu_set(void)
} else
#endif
/* 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_use_exec = 1;
} else

View File

@@ -302,6 +302,8 @@ extern int memspeed[11];
extern int mmu_perm;
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 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 *write_mapping[MEM_MAPPINGS_NO];
uint8_t *_mem_exec[MEM_MAPPINGS_NO];
/* FIXME: re-do this with a 'mem_ops' struct. */
static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */
static uint8_t *readlookupp;
@@ -131,7 +133,6 @@ static mem_mapping_t *base_mapping;
static mem_mapping_t *last_mapping;
static mem_mapping_t *read_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_bus[MEM_MAPPINGS_NO];
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };