Prepare WD76C10 for 286/386 interpreter selection, exempt IBM 486BL and all Cyrix'es from the 286/386 interpreter.
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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 };
|
||||||
|
Reference in New Issue
Block a user