mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
286/386 interpreter fixes - the correct opcode arrays are now used and fixed the debug registers.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
@@ -262,11 +263,10 @@ exec386_2386(int32_t cycs)
|
||||
CHECK_READ_CS(MIN(ol, 4));
|
||||
ins_fetch_fault = cpu_386_check_instruction_fault();
|
||||
|
||||
if (!cpu_state.abrt && ins_fetch_fault) {
|
||||
x86gen();
|
||||
/* Breakpoint fault has priority over other faults. */
|
||||
if (ins_fetch_fault) {
|
||||
ins_fetch_fault = 0;
|
||||
/* No instructions executed at this point. */
|
||||
goto block_ended;
|
||||
cpu_state.abrt = 1;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
@@ -279,7 +279,8 @@ exec386_2386(int32_t cycs)
|
||||
trap |= !!(cpu_state.flags & T_FLAG);
|
||||
|
||||
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)
|
||||
break;
|
||||
}
|
||||
@@ -319,8 +320,7 @@ block_ended:
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!x86_was_reset && ins_fetch_fault)
|
||||
x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */
|
||||
according to the manual. */
|
||||
} else if (trap) {
|
||||
flags_rebuild();
|
||||
if (trap & 2) dr[6] |= 0x8000;
|
||||
|
||||
@@ -1412,7 +1412,7 @@ x86_int(int num)
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
|
||||
if (msw & 1)
|
||||
is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0);
|
||||
cpu_use_exec ? pmodeint(num, 0) : pmodeint_2386(num, 0);
|
||||
else {
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
@@ -1445,7 +1445,7 @@ x86_int(int num)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
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;
|
||||
|
||||
if (msw & 1)
|
||||
is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1);
|
||||
cpu_use_exec ? pmodeint(num, 1) : pmodeint_2386(num, 1);
|
||||
else {
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
@@ -1487,7 +1487,7 @@ x86_int_sw(int num)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1529,7 +1529,7 @@ x86_int_sw_rm(int num)
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
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
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
|
||||
@@ -225,19 +225,37 @@ int checkio(uint32_t port, int mask);
|
||||
static __inline uint8_t
|
||||
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
|
||||
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
|
||||
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
|
||||
static __inline uint8_t
|
||||
@@ -342,31 +360,41 @@ extern int opcode_length[256];
|
||||
static __inline uint16_t
|
||||
fastreadw_fetch(uint32_t a)
|
||||
{
|
||||
uint16_t val;
|
||||
uint16_t ret;
|
||||
|
||||
if ((a & 0xFFF) > 0xFFE) {
|
||||
val = fastreadb(a);
|
||||
if (opcode_length[val & 0xff] > 1)
|
||||
val |= ((uint16_t) fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
ret = fastreadb(a);
|
||||
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1))
|
||||
ret |= ((uint16_t) fastreadb(a + 1) << 8);
|
||||
} 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
|
||||
fastreadl_fetch(uint32_t a)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t ret;
|
||||
|
||||
if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) {
|
||||
val = fastreadw_fetch(a);
|
||||
if (opcode_length[val & 0xff] > 2)
|
||||
val |= ((uint32_t) fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
ret = fastreadw_fetch(a);
|
||||
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 2))
|
||||
ret |= ((uint32_t) fastreadw(a + 2) << 16);
|
||||
} 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
|
||||
static __inline uint16_t
|
||||
|
||||
@@ -186,7 +186,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#else
|
||||
# include "x86_ops_flag.h"
|
||||
#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_int.h"
|
||||
#include "x86_ops_io.h"
|
||||
@@ -216,7 +220,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#endif
|
||||
#include "x86_ops_mul.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
|
||||
# include "x86_ops_rep_dyn.h"
|
||||
#else
|
||||
|
||||
@@ -174,6 +174,7 @@ typedef struct {
|
||||
#define VIP_FLAG 0x0010 /* in EFLAGS */
|
||||
#define VID_FLAG 0x0020 /* in EFLAGS */
|
||||
|
||||
#define EM_FLAG 0x00004 /* in CR0 */
|
||||
#define WP_FLAG 0x10000 /* in CR0 */
|
||||
|
||||
#define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */
|
||||
|
||||
@@ -275,6 +275,12 @@ reset_common(int hard)
|
||||
cr4 = 0;
|
||||
cpu_state.eflags = 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 (is486)
|
||||
loadcs(0xF000);
|
||||
|
||||
113
src/cpu/x86_ops_fpu_2386.h
Normal file
113
src/cpu/x86_ops_fpu_2386.h
Normal 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;
|
||||
}
|
||||
@@ -726,6 +726,22 @@ opHLT(uint32_t fetchdat)
|
||||
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
|
||||
opLOCK(uint32_t fetchdat)
|
||||
{
|
||||
@@ -740,6 +756,7 @@ opLOCK(uint32_t fetchdat)
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
opBOUND_w_a16(uint32_t fetchdat)
|
||||
|
||||
@@ -82,18 +82,41 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
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);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
@@ -101,18 +124,41 @@ opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_r_DRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
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);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
@@ -236,24 +282,41 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
dr[7] |= 0x2000;
|
||||
dr[6] &= ~0x2000;
|
||||
x86gen();
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
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();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
return 1;
|
||||
}
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
CPU_BLOCK_END();
|
||||
@@ -262,18 +325,41 @@ opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
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);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
CPU_BLOCK_END();
|
||||
|
||||
@@ -195,7 +195,11 @@ opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
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);
|
||||
#endif
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
op_loadseg(new_seg, &cpu_state.seg_fs);
|
||||
@@ -240,7 +244,11 @@ opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
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);
|
||||
#endif
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
op_loadseg(new_seg, &cpu_state.seg_fs);
|
||||
|
||||
179
src/cpu/x86_ops_prefix_2386.h
Normal file
179
src/cpu/x86_ops_prefix_2386.h
Normal 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);
|
||||
}
|
||||
@@ -836,7 +836,7 @@ REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1)
|
||||
static int
|
||||
opREPNE(uint32_t fetchdat)
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
@@ -850,7 +850,7 @@ opREPNE(uint32_t fetchdat)
|
||||
static int
|
||||
opREPE(uint32_t fetchdat)
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
@@ -667,7 +667,11 @@ opPOP_SS_w(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
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);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -695,7 +699,11 @@ opPOP_SS_l(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
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);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user