From 15e3876e219b5448135740eabd97e926ab48f2bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 06:06:09 +0200 Subject: [PATCH] Prepare WD76C10 for 286/386 interpreter selection, exempt IBM 486BL and all Cyrix'es from the 286/386 interpreter. --- src/chipset/wd76c10.c | 86 ++++++++++++++++++++++++++++++++++------- src/cpu/cpu.c | 3 +- src/include/86box/mem.h | 2 + src/mem/mem.c | 3 +- 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index ef076b606..5b6ea28d2 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -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; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 4398df36c..459d41231 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -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 diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index bc949834f..a130309c4 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -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; diff --git a/src/mem/mem.c b/src/mem/mem.c index 188aa49d0..1d373dafb 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -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 };