From e781d4905e57979e6a19b9d882ca6fc08ee69e5b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 15 Aug 2023 22:11:32 +0200 Subject: [PATCH] 286/386 interpreter fixes. --- src/cpu/386.c | 34 ++++++++++++++++++---------------- src/cpu/386_common.h | 12 ++++++------ src/mem/mmu_2386.c | 36 +++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 5dd143efd..4daa2936b 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -77,7 +77,6 @@ x386_log(const char *fmt, ...) static __inline void fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; if (cpu_rm == 4) { uint8_t sib = rmdat >> 8; @@ -122,19 +121,11 @@ fetch_ea_32_long(uint32_t rmdat) cpu_state.eaaddr = getlong(); } } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); - } } static __inline void fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; if (!cpu_mod && cpu_rm == 6) { cpu_state.eaaddr = getword(); @@ -158,13 +149,6 @@ fetch_ea_16_long(uint32_t rmdat) } cpu_state.eaaddr &= 0xFFFF; } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); - } } #define fetch_ea_16(rmdat) \ @@ -225,11 +209,23 @@ fetch_ea_16_long(uint32_t rmdat) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) +#define CHECK_READ_CS(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ + x86gpf("Limit check (READ)", 0); \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + } + #include "386_ops.h" void exec386_2386(int cycs) { + int ol; + int vector; int tempi; int cycdiff; @@ -264,6 +260,12 @@ exec386_2386(int cycs) cpu_state.ssegs = 0; fetchdat = fastreadl_fetch(cs + cpu_state.pc); + ol = opcode_length[fetchdat & 0xff]; + if (ol < 4) { + CHECK_READ_CS(&cpu_state.seg_cs, cpu_state.pc, cpu_state.pc + ol - 1); + } else { + CHECK_READ_CS(&cpu_state.seg_cs, cpu_state.pc, cpu_state.pc + 3); + } if (!cpu_state.abrt) { #ifdef ENABLE_386_LOG diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index b709e743d..f39733cff 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -225,19 +225,19 @@ int checkio(uint32_t port, int mask); static __inline uint8_t fastreadb(uint32_t a) { - return readmembl(a); + return readmembl_2386(a); } static __inline uint16_t fastreadw(uint32_t a) { - return readmemwl(a); + return readmemwl_2386(a); } static __inline uint32_t fastreadl(uint32_t a) { - return readmemll(a); + return readmemll_2386(a); } #else static __inline uint8_t @@ -351,7 +351,7 @@ fastreadw_fetch(uint32_t a) return val; } - return readmemwl(a); + return readmemwl_2386(a); } static __inline uint32_t @@ -359,14 +359,14 @@ fastreadl_fetch(uint32_t a) { uint32_t val; - if ((a & 0xFFF) > 0xFFC) { + if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { val = fastreadw_fetch(a); if (opcode_length[val & 0xff] > 2) val |= (fastreadw(a + 2) << 16); return val; } - return readmemll(a); + return readmemll_2386(a); } #else static __inline uint16_t diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index af7d8192c..4fd709f14 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -132,6 +132,7 @@ readmembl_2386(uint32_t addr) { mem_mapping_t *map; uint64_t a; + uint8_t ret = 0xff; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); @@ -145,15 +146,15 @@ readmembl_2386(uint32_t addr) addr64 = (uint32_t) a; if (a > 0xffffffffULL) - return 0xff; + return 0xff; } addr = (uint32_t) (addr64 & rammask); map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - return map->read_b(addr, map->priv); + ret = map->read_b(addr, map->priv); - return 0xff; + return ret; } @@ -190,6 +191,7 @@ uint8_t readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) { mem_mapping_t *map; + uint8_t ret = 0xff; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); @@ -205,9 +207,9 @@ readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - return map->read_b(addr, map->priv); + ret = map->read_b(addr, map->priv); - return 0xff; + return ret; } @@ -241,6 +243,7 @@ readmemwl_2386(uint32_t addr) mem_mapping_t *map; int i; uint64_t a; + uint16_t ret = 0xffff; addr64a[0] = addr; addr64a[1] = addr + 1; @@ -283,14 +286,13 @@ readmemwl_2386(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - return map->read_w(addr, map->priv); - - if (map && map->read_b) { - return map->read_b(addr, map->priv) | - ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); + ret = map->read_w(addr, map->priv); + else if (map && map->read_b) { + ret = map->read_b(addr, map->priv) | + ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); } - return 0xffff; + return ret; } @@ -361,6 +363,7 @@ uint16_t readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) { mem_mapping_t *map; + uint16_t ret = 0xffff; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); @@ -391,14 +394,13 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - return map->read_w(addr, map->priv); - - if (map && map->read_b) { - return map->read_b(addr, map->priv) | - ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); + ret = map->read_w(addr, map->priv); + else if (map && map->read_b) { + ret = map->read_b(addr, map->priv) | + ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); } - return 0xffff; + return ret; }