286/386 interpreter fixes - the correct opcode arrays are now used and fixed the debug registers.

This commit is contained in:
OBattler
2024-02-09 12:14:35 +01:00
parent c99c4ecb6e
commit 5a3d74d64f
16 changed files with 597 additions and 140 deletions

View File

@@ -25,6 +25,7 @@
#include <86box/fdd.h> #include <86box/fdd.h>
#include <86box/fdc.h> #include <86box/fdc.h>
#include <86box/machine.h> #include <86box/machine.h>
#include <86box/plat_fallthrough.h>
#include <86box/gdbstub.h> #include <86box/gdbstub.h>
#ifndef OPS_286_386 #ifndef OPS_286_386
# define OPS_286_386 # define OPS_286_386
@@ -262,11 +263,10 @@ exec386_2386(int32_t cycs)
CHECK_READ_CS(MIN(ol, 4)); CHECK_READ_CS(MIN(ol, 4));
ins_fetch_fault = cpu_386_check_instruction_fault(); ins_fetch_fault = cpu_386_check_instruction_fault();
if (!cpu_state.abrt && ins_fetch_fault) { /* Breakpoint fault has priority over other faults. */
x86gen(); if (ins_fetch_fault) {
ins_fetch_fault = 0; ins_fetch_fault = 0;
/* No instructions executed at this point. */ cpu_state.abrt = 1;
goto block_ended;
} }
if (!cpu_state.abrt) { if (!cpu_state.abrt) {
@@ -279,7 +279,8 @@ exec386_2386(int32_t cycs)
trap |= !!(cpu_state.flags & T_FLAG); trap |= !!(cpu_state.flags & T_FLAG);
cpu_state.pc++; cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); cpu_state.eflags &= ~(RF_FLAG);
x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset) if (x86_was_reset)
break; break;
} }
@@ -319,8 +320,7 @@ block_ended:
#endif #endif
} }
} }
if (!x86_was_reset && ins_fetch_fault) according to the manual. */
x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */
} else if (trap) { } else if (trap) {
flags_rebuild(); flags_rebuild();
if (trap & 2) dr[6] |= 0x8000; if (trap & 2) dr[6] |= 0x8000;

View File

@@ -1412,7 +1412,7 @@ x86_int(int num)
cpu_state.pc = cpu_state.oldpc; cpu_state.pc = cpu_state.oldpc;
if (msw & 1) if (msw & 1)
is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0); cpu_use_exec ? pmodeint(num, 0) : pmodeint_2386(num, 0);
else { else {
addr = (num << 2) + idt.base; addr = (num << 2) + idt.base;
@@ -1445,7 +1445,7 @@ x86_int(int num)
oxpc = cpu_state.pc; oxpc = cpu_state.pc;
#endif #endif
cpu_state.pc = readmemw(0, addr); cpu_state.pc = readmemw(0, addr);
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
} }
} }
@@ -1462,7 +1462,7 @@ x86_int_sw(int num)
cycles -= timing_int; cycles -= timing_int;
if (msw & 1) if (msw & 1)
is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1); cpu_use_exec ? pmodeint(num, 1) : pmodeint_2386(num, 1);
else { else {
addr = (num << 2) + idt.base; addr = (num << 2) + idt.base;
@@ -1487,7 +1487,7 @@ x86_int_sw(int num)
oxpc = cpu_state.pc; oxpc = cpu_state.pc;
#endif #endif
cpu_state.pc = readmemw(0, addr); cpu_state.pc = readmemw(0, addr);
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
cycles -= timing_int_rm; cycles -= timing_int_rm;
} }
} }
@@ -1529,7 +1529,7 @@ x86_int_sw_rm(int num)
cpu_state.eflags &= ~VIF_FLAG; cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags &= ~T_FLAG; cpu_state.flags &= ~T_FLAG;
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
is486 ? loadcs(new_cs) : loadcs_2386(new_cs); cpu_use_exec ? loadcs(new_cs) : loadcs_2386(new_cs);
#ifndef USE_NEW_DYNAREC #ifndef USE_NEW_DYNAREC
oxpc = cpu_state.pc; oxpc = cpu_state.pc;
#endif #endif

View File

@@ -225,19 +225,37 @@ int checkio(uint32_t port, int mask);
static __inline uint8_t static __inline uint8_t
fastreadb(uint32_t a) fastreadb(uint32_t a)
{ {
return readmembl_2386(a); uint8_t ret;
read_type = 1;
ret = readmembl_2386(a);
read_type = 4;
if (cpu_state.abrt)
return 0;
return ret;
} }
static __inline uint16_t static __inline uint16_t
fastreadw(uint32_t a) fastreadw(uint32_t a)
{ {
return readmemwl_2386(a); uint16_t ret;
read_type = 1;
ret = readmemwl_2386(a);
read_type = 4;
if (cpu_state.abrt)
return 0;
return ret;
} }
static __inline uint32_t static __inline uint32_t
fastreadl(uint32_t a) fastreadl(uint32_t a)
{ {
return readmemll_2386(a); uint32_t ret;
read_type = 1;
ret = readmemll_2386(a);
read_type = 4;
if (cpu_state.abrt)
return 0;
return ret;
} }
#else #else
static __inline uint8_t static __inline uint8_t
@@ -342,31 +360,41 @@ extern int opcode_length[256];
static __inline uint16_t static __inline uint16_t
fastreadw_fetch(uint32_t a) fastreadw_fetch(uint32_t a)
{ {
uint16_t val; uint16_t ret;
if ((a & 0xFFF) > 0xFFE) { if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a); ret = fastreadb(a);
if (opcode_length[val & 0xff] > 1) if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1))
val |= ((uint16_t) fastreadb(a + 1) << 8); ret |= ((uint16_t) fastreadb(a + 1) << 8);
return val; } else if (cpu_state.abrt)
ret = 0;
else {
read_type = 1;
ret = readmemwl_2386(a);
read_type = 4;
} }
return readmemwl_2386(a); return ret;
} }
static __inline uint32_t static __inline uint32_t
fastreadl_fetch(uint32_t a) fastreadl_fetch(uint32_t a)
{ {
uint32_t val; uint32_t ret;
if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) {
val = fastreadw_fetch(a); ret = fastreadw_fetch(a);
if (opcode_length[val & 0xff] > 2) if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 2))
val |= ((uint32_t) fastreadw(a + 2) << 16); ret |= ((uint32_t) fastreadw(a + 2) << 16);
return val; } else if (cpu_state.abrt)
ret = 0;
else {
read_type = 1;
ret = readmemll_2386(a);
read_type = 4;
} }
return readmemll_2386(a); return ret;
} }
#else #else
static __inline uint16_t static __inline uint16_t

View File

@@ -186,7 +186,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
#else #else
# include "x86_ops_flag.h" # include "x86_ops_flag.h"
#endif #endif
#include "x86_ops_fpu.h" #ifdef OPS_286_386
# include "x86_ops_fpu_2386.h"
#else
# include "x86_ops_fpu.h"
#endif
#include "x86_ops_inc_dec.h" #include "x86_ops_inc_dec.h"
#include "x86_ops_int.h" #include "x86_ops_int.h"
#include "x86_ops_io.h" #include "x86_ops_io.h"
@@ -216,7 +220,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
#endif #endif
#include "x86_ops_mul.h" #include "x86_ops_mul.h"
#include "x86_ops_pmode.h" #include "x86_ops_pmode.h"
#include "x86_ops_prefix.h" #ifdef OPS_286_386
# include "x86_ops_prefix_2386.h"
#else
# include "x86_ops_prefix.h"
#endif
#ifdef IS_DYNAREC #ifdef IS_DYNAREC
# include "x86_ops_rep_dyn.h" # include "x86_ops_rep_dyn.h"
#else #else

View File

@@ -174,6 +174,7 @@ typedef struct {
#define VIP_FLAG 0x0010 /* in EFLAGS */ #define VIP_FLAG 0x0010 /* in EFLAGS */
#define VID_FLAG 0x0020 /* in EFLAGS */ #define VID_FLAG 0x0020 /* in EFLAGS */
#define EM_FLAG 0x00004 /* in CR0 */
#define WP_FLAG 0x10000 /* in CR0 */ #define WP_FLAG 0x10000 /* in CR0 */
#define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */ #define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */

View File

@@ -275,6 +275,12 @@ reset_common(int hard)
cr4 = 0; cr4 = 0;
cpu_state.eflags = 0; cpu_state.eflags = 0;
cgate32 = 0; cgate32 = 0;
if (is386 && !is486) {
for (uint8_t i = 0; i < 4; i++)
dr[i] = 0x00000000;
dr[6] = 0xffff1ff0;
dr[7] = 0x00000400;
}
if (is286) { if (is286) {
if (is486) if (is486)
loadcs(0xF000); loadcs(0xF000);

113
src/cpu/x86_ops_fpu_2386.h Normal file
View File

@@ -0,0 +1,113 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
static int
opESCAPE_d8_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_d8_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_d9_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_d9_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_da_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_da_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_db_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_db_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_dc_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_dc_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_dd_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_dd_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_de_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_de_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_df_a16(uint32_t fetchdat)
{
return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_df_a32(uint32_t fetchdat)
{
return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat);
}
static int
opWAIT(uint32_t fetchdat)
{
if ((cr0 & 0xa) == 0xa) {
x86_int(7);
return 1;
}
#if 0
if (!cpu_use_dynarec && fpu_softfloat) {
#endif
if (fpu_softfloat) {
if (fpu_state.swd & FPU_SW_Summary) {
if (cr0 & 0x20) {
x86_int(16);
return 1;
}
}
}
CLOCK_CYCLES(4);
return 0;
}

View File

@@ -726,6 +726,22 @@ opHLT(uint32_t fetchdat)
return 0; return 0;
} }
#ifdef OPS_286_386
static int
opLOCK(uint32_t fetchdat)
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 0;
cpu_state.pc++;
ILLEGAL_ON((fetchdat & 0xff) == 0x90);
CLOCK_CYCLES(4);
PREFETCH_PREFIX();
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
#else
static int static int
opLOCK(uint32_t fetchdat) opLOCK(uint32_t fetchdat)
{ {
@@ -740,6 +756,7 @@ opLOCK(uint32_t fetchdat)
PREFETCH_PREFIX(); PREFETCH_PREFIX();
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
} }
#endif
static int static int
opBOUND_w_a16(uint32_t fetchdat) opBOUND_w_a16(uint32_t fetchdat)

View File

@@ -82,18 +82,41 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
static int static int
opMOV_r_DRx_a16(uint32_t fetchdat) opMOV_r_DRx_a16(uint32_t fetchdat)
{ {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { if ((CPL > 0) && (cr0 & 1)) {
x86gpf(NULL, 0); x86gpf(NULL, 0);
return 1; return 1;
} }
fetch_ea_16(fetchdat); if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
if (cpu_reg == 4 || cpu_reg == 5) { trap |= 1;
if (cr4 & 0x8) return 1;
x86illegal(); }
else fetch_ea_16(fetchdat);
cpu_reg += 2; switch (cpu_reg) {
case 0 ... 3:
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
cpu_state.regs[cpu_rm].l = dr[6];
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
cpu_state.regs[cpu_rm].l = dr[7];
break;
default:
x86illegal();
return 1;
} }
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
CLOCK_CYCLES(6); CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0; return 0;
@@ -101,18 +124,41 @@ opMOV_r_DRx_a16(uint32_t fetchdat)
static int static int
opMOV_r_DRx_a32(uint32_t fetchdat) opMOV_r_DRx_a32(uint32_t fetchdat)
{ {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { if ((CPL > 0) && (cr0 & 1)) {
x86gpf(NULL, 0); x86gpf(NULL, 0);
return 1; return 1;
} }
fetch_ea_32(fetchdat); if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
if (cpu_reg == 4 || cpu_reg == 5) { trap |= 1;
if (cr4 & 0x8) return 1;
x86illegal(); }
else fetch_ea_32(fetchdat);
cpu_reg += 2; switch (cpu_reg) {
case 0 ... 3:
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
cpu_state.regs[cpu_rm].l = dr[6];
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
cpu_state.regs[cpu_rm].l = dr[7];
break;
default:
x86illegal();
return 1;
} }
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
CLOCK_CYCLES(6); CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0; return 0;
@@ -236,24 +282,41 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
static int static int
opMOV_DRx_r_a16(uint32_t fetchdat) opMOV_DRx_r_a16(uint32_t fetchdat)
{ {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { if ((CPL > 0) && (cr0 & 1)) {
x86gpf(NULL, 0); x86gpf(NULL, 0);
return 1; return 1;
} }
if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
dr[7] |= 0x2000; trap |= 1;
dr[6] &= ~0x2000;
x86gen();
return 1; return 1;
} }
fetch_ea_16(fetchdat); fetch_ea_16(fetchdat);
if (cpu_reg == 4 || cpu_reg == 5) { switch (cpu_reg) {
if (cr4 & 0x8) case 0 ... 3:
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f);
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400;
break;
default:
x86illegal(); x86illegal();
else return 1;
cpu_reg += 2;
} }
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(6); CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
CPU_BLOCK_END(); CPU_BLOCK_END();
@@ -262,18 +325,41 @@ opMOV_DRx_r_a16(uint32_t fetchdat)
static int static int
opMOV_DRx_r_a32(uint32_t fetchdat) opMOV_DRx_r_a32(uint32_t fetchdat)
{ {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { if ((CPL > 0) && (cr0 & 1)) {
x86gpf(NULL, 0); x86gpf(NULL, 0);
return 1; return 1;
} }
fetch_ea_16(fetchdat); if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
if (cpu_reg == 4 || cpu_reg == 5) { trap |= 1;
if (cr4 & 0x8) return 1;
x86illegal(); }
else fetch_ea_32(fetchdat);
cpu_reg += 2; switch (cpu_reg) {
case 0 ... 3:
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f);
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400;
break;
default:
x86illegal();
return 1;
} }
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(6); CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
CPU_BLOCK_END(); CPU_BLOCK_END();

View File

@@ -195,7 +195,11 @@ opMOV_seg_w_a16(uint32_t fetchdat)
cpu_state.pc++; cpu_state.pc++;
if (cpu_state.abrt) if (cpu_state.abrt)
return 1; return 1;
#ifdef OPS_286_386
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#else
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#endif
return 1; return 1;
case 0x20: /*FS*/ case 0x20: /*FS*/
op_loadseg(new_seg, &cpu_state.seg_fs); op_loadseg(new_seg, &cpu_state.seg_fs);
@@ -240,7 +244,11 @@ opMOV_seg_w_a32(uint32_t fetchdat)
cpu_state.pc++; cpu_state.pc++;
if (cpu_state.abrt) if (cpu_state.abrt)
return 1; return 1;
#ifdef OPS_286_386
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#else
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#endif
return 1; return 1;
case 0x20: /*FS*/ case 0x20: /*FS*/
op_loadseg(new_seg, &cpu_state.seg_fs); op_loadseg(new_seg, &cpu_state.seg_fs);

View File

@@ -0,0 +1,179 @@
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
static int op##name##_w_a16(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[fetchdat & 0xff]) \
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
} \
\
static int op##name##_l_a16(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
} \
\
static int op##name##_w_a32(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
} \
\
static int op##name##_l_a32(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
}
// clang-format off
op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes)
op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes)
op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes)
op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes)
op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes)
op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes)
op_seg(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes)
op_seg(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes)
op_seg(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes)
op_seg(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes)
op_seg(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes)
op_seg(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes)
op_seg(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes)
op_seg(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes)
op_seg(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes)
op_seg(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes)
op_seg(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes)
op_seg(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes)
// clang-format on
static int
op_66(uint32_t fetchdat) /*Data size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int
op_67(uint32_t fetchdat) /*Address size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int
op_66_REPE(uint32_t fetchdat) /*Data size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int
op_67_REPE(uint32_t fetchdat) /*Address size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int
op_66_REPNE(uint32_t fetchdat) /*Data size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int
op_67_REPNE(uint32_t fetchdat) /*Address size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}

View File

@@ -836,7 +836,7 @@ REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1)
static int static int
opREPNE(uint32_t fetchdat) opREPNE(uint32_t fetchdat)
{ {
fetchdat = fastreadl(cs + cpu_state.pc); fetchdat = fastreadl_fetch(cs + cpu_state.pc);
if (cpu_state.abrt) if (cpu_state.abrt)
return 1; return 1;
cpu_state.pc++; cpu_state.pc++;
@@ -850,7 +850,7 @@ opREPNE(uint32_t fetchdat)
static int static int
opREPE(uint32_t fetchdat) opREPE(uint32_t fetchdat)
{ {
fetchdat = fastreadl(cs + cpu_state.pc); fetchdat = fastreadl_fetch(cs + cpu_state.pc);
if (cpu_state.abrt) if (cpu_state.abrt)
return 1; return 1;
cpu_state.pc++; cpu_state.pc++;

View File

@@ -667,7 +667,11 @@ opPOP_SS_w(uint32_t fetchdat)
cpu_state.pc++; cpu_state.pc++;
if (cpu_state.abrt) if (cpu_state.abrt)
return 1; return 1;
#ifdef OPS_286_386
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#else
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#endif
return 1; return 1;
} }
@@ -695,7 +699,11 @@ opPOP_SS_l(uint32_t fetchdat)
cpu_state.pc++; cpu_state.pc++;
if (cpu_state.abrt) if (cpu_state.abrt)
return 1; return 1;
#ifdef OPS_286_386
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#else
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
#endif
return 1; return 1;
} }

View File

@@ -303,6 +303,7 @@ 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 uint32_t pages_sz; /* #pages in table */ extern uint32_t pages_sz; /* #pages in table */
extern int read_type;
extern int mem_a20_state; extern int mem_a20_state;
extern int mem_a20_alt; extern int mem_a20_alt;

View File

@@ -39,52 +39,43 @@
#include <86box/rom.h> #include <86box/rom.h>
#include <86box/gdbstub.h> #include <86box/gdbstub.h>
/* Set trap for data address breakpoints. */ /* As below, 1 = exec, 4 = read. */
void int read_type = 4;
mem_debug_check_addr(uint32_t addr, int write)
{
int i = 0;
int set_trap = 0;
if (!(dr[7] & 0xFF)) /* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */
void
mem_debug_check_addr(uint32_t addr, int flags)
{
uint32_t bp_addr;
uint32_t bp_mask;
uint32_t len_type_pair;
int bp_enabled;
uint8_t match_flags[4] = { 0, 2, 0, 6 };
char *bp_types[5] = { "N/A 0", "EXEC ", "WRITE", "N/A 3", "READ " };
if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG)))
return; return;
for (i = 0; i < 4; i++) { if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) {
uint32_t dr_addr = dr[i]; bp_addr = dr[i];
int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); bp_enabled = (dr[7] >> (i << 1)) & 0x03;
int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f;
if (!breakpoint_enabled) bp_mask = ~((len_type_pair >> 2) & 0x03);
continue;
if (!write && (len_type_pair & 3) != 3) if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) {
continue; /*
if ((len_type_pair & 3) != 1) From the Intel i386 documemntation:
continue;
(Note that the processor sets Bn regardless of whether Gn or
switch ((len_type_pair >> 2) & 3) Ln is set. If more than one breakpoint condition occurs at one time and if
{ the breakpoint trap occurs due to an enabled condition other than n, Bn may
case 0x00: be set, even though neither Gn nor Ln is set.)
if (dr_addr == addr) { */
set_trap = 1; dr[6] |= (1 << i);
dr[6] |= (1 << i); if (bp_enabled)
} trap |= (read_type == 1) ? 8 : 4;
break;
case 0x01:
if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) {
set_trap = 1;
dr[6] |= (1 << i);
}
break;
case 0x03:
dr_addr &= ~3;
if (addr >= dr_addr && addr < (dr_addr + 4)) {
set_trap = 1;
dr[6] |= (1 << i);
}
break;
} }
} }
if (set_trap)
trap |= 4;
} }
uint8_t uint8_t
@@ -291,7 +282,7 @@ readmembl_2386(uint32_t addr)
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
mem_debug_check_addr(addr, 0); mem_debug_check_addr(addr, read_type);
addr64 = (uint64_t) addr; addr64 = (uint64_t) addr;
mem_logical_addr = addr; mem_logical_addr = addr;
@@ -319,7 +310,7 @@ writemembl_2386(uint32_t addr, uint8_t val)
mem_mapping_t *map; mem_mapping_t *map;
uint64_t a; uint64_t a;
mem_debug_check_addr(addr, 1); mem_debug_check_addr(addr, 2);
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
addr64 = (uint64_t) addr; addr64 = (uint64_t) addr;
@@ -397,8 +388,8 @@ readmemwl_2386(uint32_t addr)
addr64a[0] = addr; addr64a[0] = addr;
addr64a[1] = addr + 1; addr64a[1] = addr + 1;
mem_debug_check_addr(addr, 0); mem_debug_check_addr(addr, read_type);
mem_debug_check_addr(addr + 1, 0); mem_debug_check_addr(addr + 1, read_type);
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2);
mem_logical_addr = addr; mem_logical_addr = addr;
@@ -419,7 +410,8 @@ readmemwl_2386(uint32_t addr)
} }
} }
return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); return readmembl_no_mmut_2386(addr, addr64a[0]) |
(((uint16_t) readmembl_no_mmut_2386(addr + 1, addr64a[1])) << 8);
} }
} }
@@ -454,8 +446,8 @@ writememwl_2386(uint32_t addr, uint16_t val)
addr64a[0] = addr; addr64a[0] = addr;
addr64a[1] = addr + 1; addr64a[1] = addr + 1;
mem_debug_check_addr(addr, 1); mem_debug_check_addr(addr, 2);
mem_debug_check_addr(addr + 1, 1); mem_debug_check_addr(addr + 1, 2);
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2);
mem_logical_addr = addr; mem_logical_addr = addr;
@@ -482,8 +474,8 @@ writememwl_2386(uint32_t addr, uint16_t val)
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
their result as a parameter to be used if needed. */ their result as a parameter to be used if needed. */
writemembl_no_mmut(addr, addr64a[0], val); writemembl_no_mmut_2386(addr, addr64a[0], val);
writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); writemembl_no_mmut_2386(addr + 1, addr64a[1], val >> 8);
return; return;
} }
} }
@@ -531,7 +523,8 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64)
return 0xffff; return 0xffff;
} }
return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); return readmembl_no_mmut_2386(addr, a64[0]) |
(((uint16_t) readmembl_no_mmut_2386(addr + 1, a64[1])) << 8);
} }
} }
@@ -574,8 +567,8 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val)
return; return;
} }
writemembl_no_mmut(addr, a64[0], val); writemembl_no_mmut_2386(addr, a64[0], val);
writemembl_no_mmut(addr + 1, a64[1], val >> 8); writemembl_no_mmut_2386(addr + 1, a64[1], val >> 8);
return; return;
} }
} }
@@ -611,7 +604,7 @@ readmemll_2386(uint32_t addr)
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
addr64a[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_debug_check_addr(addr + i, 0); mem_debug_check_addr(addr + i, read_type);
} }
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4);
@@ -619,8 +612,8 @@ readmemll_2386(uint32_t addr)
high_page = 0; high_page = 0;
if (addr & 3) { if (cpu_16bitbus || (addr & 3)) {
if (!cpu_cyrix_alignment || (addr & 7) > 4) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
@@ -647,7 +640,8 @@ readmemll_2386(uint32_t addr)
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
their result as a parameter to be used if needed. */ their result as a parameter to be used if needed. */
return readmemwl_no_mmut(addr, addr64a) | (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); return readmemwl_no_mmut_2386(addr, addr64a) |
(((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16);
} }
} }
@@ -684,7 +678,7 @@ writememll_2386(uint32_t addr, uint32_t val)
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
addr64a[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_debug_check_addr(addr + i, 1); mem_debug_check_addr(addr + i, 2);
} }
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4);
@@ -692,8 +686,8 @@ writememll_2386(uint32_t addr, uint32_t val)
high_page = 0; high_page = 0;
if (addr & 3) { if (cpu_16bitbus || (addr & 3)) {
if (!cpu_cyrix_alignment || (addr & 7) > 4) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
@@ -724,8 +718,8 @@ writememll_2386(uint32_t addr, uint32_t val)
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
their result as a parameter to be used if needed. */ their result as a parameter to be used if needed. */
writememwl_no_mmut(addr, &(addr64a[0]), val); writememwl_no_mmut_2386(addr, &(addr64a[0]), val);
writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); writememwl_no_mmut_2386(addr + 2, &(addr64a[2]), val >> 16);
return; return;
} }
} }
@@ -770,8 +764,8 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64)
mem_logical_addr = addr; mem_logical_addr = addr;
if (addr & 3) { if (cpu_16bitbus || (addr & 3)) {
if (!cpu_cyrix_alignment || (addr & 7) > 4) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
@@ -779,7 +773,8 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64)
return 0xffffffff; return 0xffffffff;
} }
return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); return readmemwl_no_mmut_2386(addr, a64) |
((uint32_t) (readmemwl_no_mmut_2386(addr + 2, &(a64[2]))) << 16);
} }
} }
@@ -815,8 +810,8 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val)
mem_logical_addr = addr; mem_logical_addr = addr;
if (addr & 3) { if (cpu_16bitbus || (addr & 3)) {
if (!cpu_cyrix_alignment || (addr & 7) > 4) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
@@ -824,8 +819,8 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val)
return; return;
} }
writememwl_no_mmut(addr, &(a64[0]), val); writememwl_no_mmut_2386(addr, &(a64[0]), val);
writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); writememwl_no_mmut_2386(addr + 2, &(a64[2]), val >> 16);
return; return;
} }
} }
@@ -867,7 +862,7 @@ readmemql_2386(uint32_t addr)
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
addr64a[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_debug_check_addr(addr + i, 0); mem_debug_check_addr(addr + i, read_type);
} }
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8);
@@ -902,7 +897,8 @@ readmemql_2386(uint32_t addr)
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
their result as a parameter to be used if needed. */ their result as a parameter to be used if needed. */
return readmemll_no_mmut(addr, addr64a) | (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); return readmemll_no_mmut_2386(addr, addr64a) |
(((uint64_t) readmemll_no_mmut_2386(addr + 4, &(addr64a[4]))) << 32);
} }
} }
@@ -932,7 +928,7 @@ writememql_2386(uint32_t addr, uint64_t val)
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
addr64a[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_debug_check_addr(addr + i, 1); mem_debug_check_addr(addr + i, 2);
} }
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8);
@@ -971,8 +967,8 @@ writememql_2386(uint32_t addr, uint64_t val)
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
their result as a parameter to be used if needed. */ their result as a parameter to be used if needed. */
writememll_no_mmut(addr, addr64a, val); writememll_no_mmut_2386(addr, addr64a, val);
writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); writememll_no_mmut_2386(addr + 4, &(addr64a[4]), val >> 32);
return; return;
} }
} }
@@ -1019,7 +1015,7 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write)
uint32_t last_addr = addr + (num - 1); uint32_t last_addr = addr + (num - 1);
uint64_t a = 0x0000000000000000ULL; uint64_t a = 0x0000000000000000ULL;
mem_debug_check_addr(addr, write); mem_debug_check_addr(addr, write ? 2 : read_type);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
a64[i] = (uint64_t) addr; a64[i] = (uint64_t) addr;

View File

@@ -296,6 +296,12 @@ rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t
fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
if (fread(ptr + addr, sz >> 1, 1, fp) > (sz >> 1)) if (fread(ptr + addr, sz >> 1, 1, fp) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n");
if (sz == 0x40000) {
if (fread(ptr + addr + 0x30000, 1, sz >> 1, fp) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
if (fread(ptr + addr + 0x20000, sz >> 1, 1, fp) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n");
}
} }
(void) fclose(fp); (void) fclose(fp);