From 4676daade40d6226f754cfa669e29da9d743b528 Mon Sep 17 00:00:00 2001 From: TomW Date: Wed, 5 Nov 2014 21:24:16 +0000 Subject: [PATCH] Initial commit of dynamic recompiler. Various CPU changes to support dynamic recompiler. --- src/386.c | 205 +----- src/386_common.h | 196 +++++ src/386_dynarec.c | 1492 +++++++++++++++++++++++++++++++++++++++ src/386_dynarec_ops.c | 139 ++++ src/386_ops.h | 60 +- src/808x.c | 5 +- src/Makefile.mingw | 6 +- src/codegen.h | 53 ++ src/codegen_x86.c | 602 ++++++++++++++++ src/codegen_x86.h | 13 + src/cpu.c | 29 +- src/mem.c | 28 + src/pc.c | 29 + src/win-status.c | 42 +- src/win.c | 6 + src/x86.h | 9 + src/x86_flags.h | 6 +- src/x86_ops.h | 16 + src/x86_ops_arith.h | 114 +-- src/x86_ops_atomic.h | 72 +- src/x86_ops_bit.h | 40 +- src/x86_ops_bitscan.h | 16 +- src/x86_ops_call.h | 169 +++-- src/x86_ops_flag.h | 30 +- src/x86_ops_fpu.h | 16 +- src/x86_ops_inc_dec.h | 12 +- src/x86_ops_int.h | 45 +- src/x86_ops_io.h | 24 +- src/x86_ops_jump.h | 109 ++- src/x86_ops_misc.h | 91 ++- src/x86_ops_mmx.h | 12 +- src/x86_ops_mmx_arith.h | 68 +- src/x86_ops_mmx_logic.h | 16 +- src/x86_ops_mmx_mov.h | 32 +- src/x86_ops_mmx_pack.h | 36 +- src/x86_ops_mmx_shift.h | 38 +- src/x86_ops_mov.h | 104 +-- src/x86_ops_mov_ctrl.h | 24 +- src/x86_ops_mov_seg.h | 78 +- src/x86_ops_movx.h | 28 +- src/x86_ops_msr.h | 4 +- src/x86_ops_mul.h | 40 +- src/x86_ops_pmode.h | 91 ++- src/x86_ops_prefix.h | 110 +-- src/x86_ops_rep.h | 6 +- src/x86_ops_ret.h | 27 +- src/x86_ops_set.h | 4 +- src/x86_ops_shift.h | 94 +-- src/x86_ops_stack.h | 126 ++-- src/x86_ops_string.h | 96 +-- src/x86_ops_xchg.h | 24 +- src/x87.c | 153 ++-- 52 files changed, 3743 insertions(+), 1142 deletions(-) create mode 100644 src/386_common.h create mode 100644 src/386_dynarec.c create mode 100644 src/386_dynarec_ops.c create mode 100644 src/codegen.h create mode 100644 src/codegen_x86.c create mode 100644 src/codegen_x86.h diff --git a/src/386.c b/src/386.c index 9a5ab79..2ba378c 100644 --- a/src/386.c +++ b/src/386.c @@ -1,3 +1,4 @@ +#ifndef DYNAREC #include #include #include @@ -9,6 +10,9 @@ #include "fdc.h" #include "timer.h" +#include "386_common.h" + +#define CPU_BLOCK_END() x86seg *ea_seg; @@ -19,48 +23,6 @@ uint32_t oldpc2; int trap; -#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ - { \ - int tempi = checkio(port); \ - if (abrt) return 0; \ - if (tempi) \ - { \ - x86gpf(NULL,0); \ - return 0; \ - } \ - } - -#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ - { \ - tempi = checkio(port); \ - if (abrt) break; \ - if (tempi) \ - { \ - x86gpf(NULL,0); \ - break; \ - } \ - } - -#define CHECK_READ(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ - { \ - x86gpf("Limit check", 0); \ - return 0; \ - } - -#define CHECK_WRITE(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ - { \ - x86gpf("Limit check", 0); \ - return 0; \ - } - -#define CHECK_WRITE_REP(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ - { \ - x86gpf("Limit check", 0); \ - break; \ - } int cpl_override=0; @@ -74,16 +36,6 @@ uint16_t ea_rseg; int is486; int cgate32; -#undef readmemb -#undef writememb - - -#define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[((s)+(a))>>12] + (s) + (a)) ) - -#define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v - -#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v -#define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v uint8_t romext[32768]; @@ -102,126 +54,8 @@ uint32_t oldcs2; uint32_t oldecx; uint32_t op32; -static inline uint8_t fastreadb(uint32_t a) -{ - if ((a >> 12) == pccache) - return *((uint8_t *)&pccache2[a]); - pccache2 = getpccache(a); - if (abrt) - return; - pccache = a >> 12; - return *((uint8_t *)&pccache2[a]); -} - -static inline uint16_t fastreadw(uint32_t a) -{ - uint32_t t; - if ((a&0xFFF)>0xFFE) - { - t=readmemb(0,a); - t|=(readmemb(0,a+1)<<8); - return t; - } - if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); - pccache2=getpccache(a); - if (abrt) - return; - pccache=a>>12; - return *((uint16_t *)&pccache2[a]); -} - -static inline uint32_t fastreadl(uint32_t a) -{ - uint8_t *t; - uint32_t val; - if ((a&0xFFF)<0xFFD) - { - if ((a>>12)!=pccache) - { - t = getpccache(a); - if (abrt) return 0; - pccache2 = t; - pccache=a>>12; - //return *((uint32_t *)&pccache2[a]); - } - return *((uint32_t *)&pccache2[a]); - } - val =readmemb(0,a); - val |=(readmemb(0,a+1)<<8); - val |=(readmemb(0,a+2)<<16); - val |=(readmemb(0,a+3)<<24); - return val; -} - - -static inline uint8_t getbyte() -{ - pc++; - return fastreadb(cs + (pc - 1)); -} - -static inline uint16_t getword() -{ - pc+=2; - return fastreadw(cs+(pc-2)); -} - -static inline uint32_t getlong() -{ - pc+=4; - return fastreadl(cs+(pc-4)); -} uint32_t *eal_r, *eal_w; -static inline uint8_t geteab() -{ - if (mod==3) - return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l; - if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg,eaaddr); -} - -static inline uint16_t geteaw() -{ - if (mod==3) - return regs[rm].w; -// cycles-=3; - if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg,eaaddr); -} - -static inline uint32_t geteal() -{ - if (mod==3) - return regs[rm].l; -// cycles-=3; - if (eal_r) return *eal_r; - return readmeml(easeg,eaaddr); -} - -static inline uint8_t geteab_mem() -{ - if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg,eaaddr); -} -static inline uint16_t geteaw_mem() -{ - if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg,eaaddr); -} -static inline uint32_t geteal_mem() -{ - if (eal_r) return *eal_r; - return readmeml(easeg,eaaddr); -} - -#define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v -#define seteaw(v) if (mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); } else regs[rm].w=v -#define seteal(v) if (mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); } else regs[rm].l=v - -#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); -#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); -#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; @@ -379,6 +213,7 @@ void x86_int(int num) loadcs(readmemw(0,addr+2)); } cycles-=70; + CPU_BLOCK_END(); } void x86_int_sw(int num) @@ -416,6 +251,7 @@ void x86_int_sw(int num) } cycles-=70; trap = 0; + CPU_BLOCK_END(); } void x86illegal() @@ -431,13 +267,7 @@ void x86illegal() } -#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ - { \ - x86_int(6); \ - break; \ - } - -void rep386(int fv) +int rep386(int fv) { uint8_t temp; uint32_t c;//=CX; @@ -1150,6 +980,7 @@ void rep386(int fv) if (rep32&0x200) ECX=c; else CX=c; // if (output) pclog("%03X %03X\n",rep32,use32); + return 1; } int checkio(int port) @@ -1183,12 +1014,12 @@ int xout=0; x86_int(0); \ } -void divl(uint32_t val) +int divl(uint32_t val) { if (val==0) { divexcp(); - return; + return 1; } uint64_t num=(((uint64_t)EDX)<<32)|EAX; uint64_t quo=num/val; @@ -1197,17 +1028,18 @@ void divl(uint32_t val) if (quo!=(uint64_t)quo32) { divexcp(); - return; + return 1; } EDX=rem; EAX=quo32; + return 0; } -void idivl(int32_t val) +int idivl(int32_t val) { if (val==0) { divexcp(); - return; + return 1; } int64_t num=(((uint64_t)EDX)<<32)|EAX; int64_t quo=num/val; @@ -1216,10 +1048,11 @@ void idivl(int32_t val) if (quo!=(int64_t)quo32) { divexcp(); - return; + return 1; } EDX=rem; EAX=quo32; + return 0; } @@ -1244,6 +1077,8 @@ int dontprint=0; return 0; \ } +#define OP_TABLE(name) ops_ ## name + #include "386_ops.h" #undef NOTRM @@ -1302,8 +1137,7 @@ opcodestart: pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]); } pc++; - if (x86_opcodes[(opcode | op32) & 0x3ff](fetchdat)) - goto opcodestart; + x86_opcodes[(opcode | op32) & 0x3ff](fetchdat); } if (!use32) pc &= 0xffff; @@ -1420,3 +1254,4 @@ opcodestart: timer_end_period(cycles); } } +#endif diff --git a/src/386_common.h b/src/386_common.h new file mode 100644 index 0000000..7c97b5d --- /dev/null +++ b/src/386_common.h @@ -0,0 +1,196 @@ +extern uint16_t ea_rseg; + +#undef readmemb +#undef writememb + + +#define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[((s)+(a))>>12] + (s) + (a)) ) + +#define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v + +#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v +#define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v + + +#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ + { \ + int tempi = checkio(port); \ + if (abrt) return 1; \ + if (tempi) \ + { \ + x86gpf(NULL,0); \ + return 1; \ + } \ + } + +#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ + { \ + tempi = checkio(port); \ + if (abrt) break; \ + if (tempi) \ + { \ + x86gpf(NULL,0); \ + break; \ + } \ + } + +#define CHECK_READ(seg, low, high) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ + { \ + x86gpf("Limit check", 0); \ + return 1; \ + } + +#define CHECK_WRITE(seg, low, high) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ + { \ + x86gpf("Limit check", 0); \ + return 1; \ + } + +#define CHECK_WRITE_REP(seg, low, high) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ + { \ + x86gpf("Limit check", 0); \ + break; \ + } + + +#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ + { \ + x86_int(6); \ + return 1; \ + } + + + + +static inline uint8_t fastreadb(uint32_t a) +{ + if ((a >> 12) == pccache) + return *((uint8_t *)&pccache2[a]); + pccache2 = getpccache(a); + if (abrt) + return; + pccache = a >> 12; + return *((uint8_t *)&pccache2[a]); +} + +static inline uint16_t fastreadw(uint32_t a) +{ + uint32_t t; + if ((a&0xFFF)>0xFFE) + { + t=readmemb(0,a); + t|=(readmemb(0,a+1)<<8); + return t; + } + if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); + pccache2=getpccache(a); + if (abrt) + return; + pccache=a>>12; + return *((uint16_t *)&pccache2[a]); +} + +static inline uint32_t fastreadl(uint32_t a) +{ + uint8_t *t; + uint32_t val; + if ((a&0xFFF)<0xFFD) + { + if ((a>>12)!=pccache) + { + t = getpccache(a); + if (abrt) return 0; + pccache2 = t; + pccache=a>>12; + //return *((uint32_t *)&pccache2[a]); + } + return *((uint32_t *)&pccache2[a]); + } + val =readmemb(0,a); + val |=(readmemb(0,a+1)<<8); + val |=(readmemb(0,a+2)<<16); + val |=(readmemb(0,a+3)<<24); + return val; +} + +static inline uint8_t getbyte() +{ + pc++; + return fastreadb(cs + (pc - 1)); +} + +static inline uint16_t getword() +{ + pc+=2; + return fastreadw(cs+(pc-2)); +} + +static inline uint32_t getlong() +{ + pc+=4; + return fastreadl(cs+(pc-4)); +} + + + +static inline uint8_t geteab() +{ + if (mod==3) + return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l; + if (eal_r) return *(uint8_t *)eal_r; + return readmemb(easeg,eaaddr); +} + +static inline uint16_t geteaw() +{ + if (mod==3) + return regs[rm].w; +// cycles-=3; + if (eal_r) return *(uint16_t *)eal_r; + return readmemw(easeg,eaaddr); +} + +static inline uint32_t geteal() +{ + if (mod==3) + return regs[rm].l; +// cycles-=3; + if (eal_r) return *eal_r; + return readmeml(easeg,eaaddr); +} + +static inline uint8_t geteab_mem() +{ + if (eal_r) return *(uint8_t *)eal_r; + return readmemb(easeg,eaaddr); +} +static inline uint16_t geteaw_mem() +{ + if (eal_r) return *(uint16_t *)eal_r; + return readmemw(easeg,eaaddr); +} +static inline uint32_t geteal_mem() +{ + if (eal_r) return *eal_r; + return readmeml(easeg,eaaddr); +} + +#define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v +#define seteaw(v) if (mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); } else regs[rm].w=v +#define seteal(v) if (mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); } else regs[rm].l=v + +#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); +#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); +#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); + +#define getbytef() ((uint8_t)(fetchdat)); pc++ +#define getwordf() ((uint16_t)(fetchdat)); pc+=2 +#define getbyte2f() ((uint8_t)(fetchdat>>8)); pc++ +#define getword2f() ((uint16_t)(fetchdat>>8)); pc+=2 + + +#define rmdat rmdat32 +#define fetchdat rmdat32 diff --git a/src/386_dynarec.c b/src/386_dynarec.c new file mode 100644 index 0000000..5906d50 --- /dev/null +++ b/src/386_dynarec.c @@ -0,0 +1,1492 @@ +#ifdef DYNAREC +#include +#include +#include +#include "ibm.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "codegen.h" +#include "mem.h" +#include "cpu.h" +#include "fdc.h" +#include "timer.h" +#include "video.h" + +#include "386_common.h" + +#define CPU_BLOCK_END() cpu_block_end = 1 + +int cpu_reps, cpu_reps_latched; +int cpu_notreps, cpu_notreps_latched; + +int inrecomp = 0; +int cpu_recomp_blocks, cpu_recomp_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_new_blocks_latched; + +int cpu_block_end = 0; + +x86seg *ea_seg; + +int nmi_enable = 1; + +int inscounts[256]; +uint32_t oldpc2; + +int trap; + + + +int cpl_override=0; + +int has_fpu; +int fpucount=0; +int times; +uint16_t rds; +uint16_t ea_rseg; + +int is486; +int cgate32; + + +uint8_t romext[32768]; +uint8_t *ram,*rom; +uint16_t biosmask; + +uint32_t rmdat32; +uint32_t backupregs[16]; +int oddeven=0; +int inttype,abrt; + + +uint32_t oldcs2; +uint32_t oldecx; +uint32_t op32; + + + + +uint32_t *eal_r, *eal_w; + +uint16_t *mod1add[2][8]; +uint32_t *mod1seg[8]; + +static inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = ea_seg->base; + ea_rseg = ea_seg->seg; + if (rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (mod) + { + case 0: + eaaddr = regs[sib & 7].l; + pc++; + break; + case 1: + pc++; + eaaddr = ((uint32_t)(int8_t)getbyte()) + regs[sib & 7].l; +// pc++; + break; + case 2: + eaaddr = (fastreadl(cs + pc + 1)) + regs[sib & 7].l; + pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !mod) + eaaddr = getlong(); + else if ((sib & 6) == 4 && !ssegs) + { + easeg = ss; + ea_rseg = SS; + ea_seg = &_ss; + } + if (((sib >> 3) & 7) != 4) + eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + eaaddr = regs[rm].l; + if (mod) + { + if (rm == 5 && !ssegs) + { + easeg = ss; + ea_rseg = SS; + ea_seg = &_ss; + } + if (mod == 1) + { + eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + pc++; + } + else + { + eaaddr += getlong(); + } + } + else if (rm == 5) + { + eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) + { + if ( readlookup2[(easeg + eaaddr) >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + if (writelookup2[(easeg + eaaddr) >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + } +} + +static inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = ea_seg->base; + ea_rseg = ea_seg->seg; + if (!mod && rm == 6) + { + eaaddr = getword(); + } + else + { + switch (mod) + { + case 0: + eaaddr = 0; + break; + case 1: + eaaddr = (uint16_t)(int8_t)(rmdat >> 8); pc++; + break; + case 2: + eaaddr = getword(); + break; + } + eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]); + if (mod1seg[rm] == &ss && !ssegs) + { + easeg = ss; + ea_rseg = SS; + ea_seg = &_ss; + } + eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) + { + if ( readlookup2[(easeg + eaaddr) >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + if (writelookup2[(easeg + eaaddr) >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + } +} + +#define fetch_ea_16(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 1; } +#define fetch_ea_32(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_32_long(rmdat); } if (abrt) return 1 + +#include "x86_flags.h" + +void x86_int(int num) +{ + uint32_t addr; +// pclog("x86_int %02x %04x:%04x\n", num, CS,pc); + flags_rebuild(); + pc=oldpc; + if (msw&1) + { + pmodeint(num,0); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),pc); + SP-=6; + } + addr = (num << 2) + idt.base; + + flags&=~I_FLAG; + flags&=~T_FLAG; + oxpc=pc; + pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + cycles-=70; + CPU_BLOCK_END(); +} + +void x86_int_sw(int num) +{ + uint32_t addr; +// pclog("x86_int_sw %02x %04x:%04x\n", num, CS,pc); +// pclog("x86_int\n"); + flags_rebuild(); + if (msw&1) + { + pmodeint(num,1); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),pc); + SP-=6; + } + addr = (num << 2) + idt.base; + + flags&=~I_FLAG; + flags&=~T_FLAG; + oxpc=pc; + pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + cycles-=70; + trap = 0; + CPU_BLOCK_END(); +} + +void x86illegal() +{ + uint16_t addr; + pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); + +// if (output) +// { +// dumpregs(); +// exit(-1); +// } + x86_int(6); +} + + +int rep386(int fv) +{ + uint8_t temp; + uint32_t c;//=CX; + uint8_t temp2; + uint16_t tempw,tempw2,of; + uint32_t ipc=oldpc;//pc-1; + uint32_t oldds; + uint32_t rep32=op32; + uint32_t templ,templ2; + int tempz; + int tempi; + + cpu_reps++; + + flags_rebuild(); + of = flags; +// if (inrecomp) pclog("REP32 %04X %04X ",use32,rep32); + startrep: + temp=opcode2=readmemb(cs,pc); pc++; +// if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); +// if (inrecomp) pclog("REP %02X %04X\n",temp,ipc); + c=(rep32&0x200)?ECX:CX; +/* if (rep32 && (msw&1)) + { + if (temp!=0x67 && temp!=0x66 && (rep32|temp)!=0x1AB && (rep32|temp)!=0x3AB) pclog("32-bit REP %03X %08X %04X:%06X\n",temp|rep32,c,CS,pc); + }*/ + switch (temp|rep32) + { + case 0xC3: case 0x1C3: case 0x2C3: case 0x3C3: + pc--; + break; + case 0x08: + pc=ipc+1; + break; + case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/ + ea_seg = &_es; + goto startrep; + break; + case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/ + ea_seg = &_cs; + goto startrep; + case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/ + ea_seg = &_ss; + goto startrep; + case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/ + ea_seg = &_ds; + goto startrep; + case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/ + ea_seg = &_fs; + goto startrep; + case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/ + ea_seg = &_gs; + goto startrep; + case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/ + rep32^=0x100; + goto startrep; + case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/ + rep32^=0x200; + goto startrep; + case 0x6C: case 0x16C: /*REP INSB*/ +// cpu_notreps++; + if (c>0) + { + checkio_perm(DX); + temp2=inb(DX); + writememb(es,DI,temp2); + if (abrt) break; + if (flags&D_FLAG) DI--; + else DI++; + c--; + cycles-=15; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x26C: case 0x36C: /*REP INSB*/ +// cpu_notreps++; + if (c>0) + { + checkio_perm(DX); + temp2=inb(DX); + writememb(es,EDI,temp2); + if (abrt) break; + if (flags&D_FLAG) EDI--; + else EDI++; + c--; + cycles-=15; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x6D: /*REP INSW*/ +// cpu_notreps++; + if (c>0) + { +// pclog("REP INSW %04x %04x:%04x %04x\n", DX, ES, DI, CX); + tempw=inw(DX); + writememw(es,DI,tempw); + if (abrt) break; + if (flags&D_FLAG) DI-=2; + else DI+=2; + c--; + cycles-=15; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x16D: /*REP INSL*/ +// cpu_notreps++; + if (c>0) + { + templ=inl(DX); + writememl(es,DI,templ); + if (abrt) break; + if (flags&D_FLAG) DI-=4; + else DI+=4; + c--; + cycles-=15; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x26D: /*REP INSW*/ +// cpu_notreps++; + if (c>0) + { + tempw=inw(DX); + writememw(es,EDI,tempw); + if (abrt) break; + if (flags&D_FLAG) EDI-=2; + else EDI+=2; + c--; + cycles-=15; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x36D: /*REP INSL*/ +// cpu_notreps++; + if (c>0) + { + templ=inl(DX); + writememl(es,EDI,templ); + if (abrt) break; + if (flags&D_FLAG) EDI-=4; + else EDI+=4; + c--; + cycles-=15; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x6E: case 0x16E: /*REP OUTSB*/ +// cpu_notreps++; + if (c>0) + { + temp2 = readmemb(ea_seg->base, SI); + if (abrt) break; + checkio_perm(DX); + outb(DX,temp2); + if (flags&D_FLAG) SI--; + else SI++; + c--; + cycles-=14; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x26E: case 0x36E: /*REP OUTSB*/ +// cpu_notreps++; + if (c>0) + { + temp2 = readmemb(ea_seg->base, ESI); + if (abrt) break; + checkio_perm(DX); + outb(DX,temp2); + if (flags&D_FLAG) ESI--; + else ESI++; + c--; + cycles-=14; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x6F: /*REP OUTSW*/ +// cpu_notreps++; + if (c>0) + { + tempw = readmemw(ea_seg->base, SI); + if (abrt) break; +// pclog("OUTSW %04X -> %04X\n",SI,tempw); + outw(DX,tempw); + if (flags&D_FLAG) SI-=2; + else SI+=2; + c--; + cycles-=14; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x16F: /*REP OUTSL*/ +// cpu_notreps++; + if (c > 0) + { + templ = readmeml(ea_seg->base, SI); + if (abrt) break; + outl(DX, templ); + if (flags & D_FLAG) SI -= 4; + else SI += 4; + c--; + cycles -= 14; + } + if (c > 0) { firstrepcycle = 0; pc = ipc; } + else firstrepcycle = 1; + break; + case 0x26F: /*REP OUTSW*/ +// cpu_notreps++; + if (c>0) + { + tempw = readmemw(ea_seg->base, ESI); + if (abrt) break; + outw(DX,tempw); + if (flags&D_FLAG) ESI-=2; + else ESI+=2; + c--; + cycles-=14; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x36F: /*REP OUTSL*/ +// cpu_notreps++; + if (c > 0) + { + templ = readmeml(ea_seg->base, ESI); + if (abrt) break; + outl(DX, templ); + if (flags & D_FLAG) ESI -= 4; + else ESI += 4; + c--; + cycles -= 14; + } + if (c > 0) { firstrepcycle = 0; pc = ipc; } + else firstrepcycle = 1; + break; + case 0x90: case 0x190: /*REP NOP*/ + case 0x290: case 0x390: +// cpu_notreps++; + break; + case 0xA4: case 0x1A4: /*REP MOVSB*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, DI, DI); + temp2 = readmemb(ea_seg->base, SI); if (abrt) break; + writememb(es,DI,temp2); if (abrt) break; +// if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2); + if (flags&D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + c--; + cycles-=(is486)?3:4; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x2A4: case 0x3A4: /*REP MOVSB*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, EDI, EDI); + temp2 = readmemb(ea_seg->base, ESI); if (abrt) break; + writememb(es,EDI,temp2); if (abrt) break; + if (flags&D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + c--; + cycles-=(is486)?3:4; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0xA5: /*REP MOVSW*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, DI, DI+1); + tempw = readmemw(ea_seg->base, SI); if (abrt) break; + writememw(es,DI,tempw); if (abrt) break; + if (flags&D_FLAG) { DI-=2; SI-=2; } + else { DI+=2; SI+=2; } + c--; + cycles-=(is486)?3:4; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x1A5: /*REP MOVSL*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, DI, DI+3); + templ = readmeml(ea_seg->base, SI); if (abrt) break; +// pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc); + writememl(es,DI,templ); if (abrt) break; + if (flags&D_FLAG) { DI-=4; SI-=4; } + else { DI+=4; SI+=4; } + c--; + cycles-=(is486)?3:4; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x2A5: /*REP MOVSW*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, EDI, EDI+1); + tempw = readmemw(ea_seg->base, ESI); if (abrt) break; + writememw(es,EDI,tempw); if (abrt) break; +// if (output) pclog("Written %04X from %08X to %08X %i %08X %04X %08X %04X\n",tempw,ds+ESI,es+EDI,c,ds,ES,es,ES); + if (flags&D_FLAG) { EDI-=2; ESI-=2; } + else { EDI+=2; ESI+=2; } + c--; + cycles-=(is486)?3:4; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x3A5: /*REP MOVSL*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, EDI, EDI+3); + templ = readmeml(ea_seg->base, ESI); if (abrt) break; +// if ((EDI&0xFFFF0000)==0xA0000) cycles-=12; + writememl(es,EDI,templ); if (abrt) break; +// if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es); + if (flags&D_FLAG) { EDI-=4; ESI-=4; } + else { EDI+=4; ESI+=4; } + c--; + cycles-=(is486)?3:4; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0xA6: case 0x1A6: /*REP CMPSB*/ +// cpu_notreps++; + tempz = (fv) ? 1 : 0; + if ((c>0) && (fv==tempz)) + { + temp = readmemb(ea_seg->base, SI); + temp2=readmemb(es,DI); + if (abrt) { flags=of; break; } + if (flags&D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + c--; + cycles-=(is486)?7:9; + setsub8(temp,temp2); + tempz = (ZF_SET()) ? 1 : 0; + } + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x2A6: case 0x3A6: /*REP CMPSB*/ +// cpu_notreps++; + tempz = (fv) ? 1 : 0; + if ((c>0) && (fv==tempz)) + { + temp = readmemb(ea_seg->base, ESI); + temp2=readmemb(es,EDI); + if (abrt) { flags=of; break; } + if (flags&D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + c--; + cycles-=(is486)?7:9; + setsub8(temp,temp2); + tempz = (ZF_SET()) ? 1 : 0; + } + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0xA7: /*REP CMPSW*/ +// cpu_notreps++; + tempz = (fv) ? 1 : 0; + if ((c>0) && (fv==tempz)) + { +// pclog("CMPSW (%04x:%04x)%05X (%04x:%04x)%05X ", DS,SI, ds+SI, ES,DI, es+DI); + tempw = readmemw(ea_seg->base, SI); + tempw2=readmemw(es,DI); +// pclog("%04X %04X %c%c %c%c\n", tempw, tempw2, tempw & 0xff, tempw >> 8, tempw2 & 0xff, tempw2 >> 8); + + if (abrt) { flags=of; break; } + if (flags&D_FLAG) { DI-=2; SI-=2; } + else { DI+=2; SI+=2; } + c--; + cycles-=(is486)?7:9; + setsub16(tempw,tempw2); + tempz = (ZF_SET()) ? 1 : 0; + } + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x1A7: /*REP CMPSL*/ +// cpu_notreps++; + tempz = (fv) ? 1 : 0; + if ((c>0) && (fv==tempz)) + { + templ = readmeml(ea_seg->base, SI); + templ2=readmeml(es,DI); + if (abrt) { flags=of; break; } + if (flags&D_FLAG) { DI-=4; SI-=4; } + else { DI+=4; SI+=4; } + c--; + cycles-=(is486)?7:9; + setsub32(templ,templ2); + tempz = (ZF_SET()) ? 1 : 0; + } + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x2A7: /*REP CMPSW*/ +// cpu_notreps++; + tempz = (fv) ? 1 : 0; + if ((c>0) && (fv==tempz)) + { + tempw = readmemw(ea_seg->base, ESI); + tempw2=readmemw(es,EDI); + if (abrt) { flags=of; break; } + if (flags&D_FLAG) { EDI-=2; ESI-=2; } + else { EDI+=2; ESI+=2; } + c--; + cycles-=(is486)?7:9; + setsub16(tempw,tempw2); + tempz = (ZF_SET()) ? 1 : 0; + } + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x3A7: /*REP CMPSL*/ +// cpu_notreps++; + tempz = (fv) ? 1 : 0; + if ((c>0) && (fv==tempz)) + { + templ = readmeml(ea_seg->base, ESI); + templ2=readmeml(es,EDI); + if (abrt) { flags=of; break; } + if (flags&D_FLAG) { EDI-=4; ESI-=4; } + else { EDI+=4; ESI+=4; } + c--; + cycles-=(is486)?7:9; + setsub32(templ,templ2); + tempz = (ZF_SET()) ? 1 : 0; + } + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + + case 0xAA: case 0x1AA: /*REP STOSB*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, DI, DI); + writememb(es,DI,AL); + if (abrt) break; + if (flags&D_FLAG) DI--; + else DI++; + c--; + cycles-=(is486)?4:5; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x2AA: case 0x3AA: /*REP STOSB*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, EDI, EDI); + writememb(es,EDI,AL); + if (abrt) break; + if (flags&D_FLAG) EDI--; + else EDI++; + c--; + cycles-=(is486)?4:5; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0xAB: /*REP STOSW*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, DI, DI+1); + writememw(es,DI,AX); + if (abrt) break; + if (flags&D_FLAG) DI-=2; + else DI+=2; + c--; + cycles-=(is486)?4:5; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x2AB: /*REP STOSW*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, EDI, EDI+1); + writememw(es,EDI,AX); + if (abrt) break; + if (flags&D_FLAG) EDI-=2; + else EDI+=2; + c--; + cycles-=(is486)?4:5; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x1AB: /*REP STOSL*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, DI, DI+3); + writememl(es,DI,EAX); + if (abrt) break; + if (flags&D_FLAG) DI-=4; + else DI+=4; + c--; + cycles-=(is486)?4:5; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x3AB: /*REP STOSL*/ + while (c > 0 && cycles > 0) + { + CHECK_WRITE_REP(&_es, EDI, EDI+3); + writememl(es,EDI,EAX); + if (abrt) break; + if (flags&D_FLAG) EDI-=4; + else EDI+=4; + c--; + cycles-=(is486)?4:5; + ins++; + } + ins--; + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0xAC: case 0x1AC: /*REP LODSB*/ +// cpu_notreps++; +// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc); + if (c>0) + { + AL = readmemb(ea_seg->base, SI); + if (abrt) break; + if (flags&D_FLAG) SI--; + else SI++; + c--; + cycles-=5; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x2AC: case 0x3AC: /*REP LODSB*/ +// cpu_notreps++; +// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc); + if (c>0) + { + AL = readmemb(ea_seg->base, ESI); + if (abrt) break; + if (flags&D_FLAG) ESI--; + else ESI++; + c--; + cycles-=5; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0xAD: /*REP LODSW*/ +// cpu_notreps++; +// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc); + if (c>0) + { + AX = readmemw(ea_seg->base, SI); + if (abrt) break; + if (flags&D_FLAG) SI-=2; + else SI+=2; + c--; + cycles-=5; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x1AD: /*REP LODSL*/ +// cpu_notreps++; +// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc); + if (c>0) + { + EAX = readmeml(ea_seg->base, SI); + if (abrt) break; + if (flags&D_FLAG) SI-=4; + else SI+=4; + c--; + cycles-=5; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x2AD: /*REP LODSW*/ +// cpu_notreps++; +// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc); + if (c>0) + { + AX = readmemw(ea_seg->base, ESI); + if (abrt) break; + if (flags&D_FLAG) ESI-=2; + else ESI+=2; + c--; + cycles-=5; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0x3AD: /*REP LODSL*/ +// cpu_notreps++; +// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc); + if (c>0) + { + EAX = readmeml(ea_seg->base, ESI); + if (abrt) break; + if (flags&D_FLAG) ESI-=4; + else ESI+=4; + c--; + cycles-=5; + } + if (c>0) { firstrepcycle=0; pc=ipc; } + else firstrepcycle=1; + break; + case 0xAE: case 0x1AE: /*REP SCASB*/ + cpu_notreps++; +// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); +// tempz=(fv)?1:0; + tempz = (fv) ? 1 : 0; + while ((c > 0) && (fv == tempz) && (cycles > 0)) + { + temp2=readmemb(es,DI); + if (abrt) { flags=of; break; } + setsub8(AL,temp2); + tempz = (ZF_SET()) ? 1 : 0; + if (flags&D_FLAG) DI--; + else DI++; + c--; + cycles-=(is486)?5:8; + ins++; + } + ins--; + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x2AE: case 0x3AE: /*REP SCASB*/ + cpu_notreps++; +// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); +// tempz=(fv)?1:0; + tempz = (fv) ? 1 : 0; + while ((c > 0) && (fv == tempz) && (cycles > 0)) + { + temp2=readmemb(es,EDI); + if (abrt) { flags=of; break; } +// if (output) pclog("Compare %02X,%02X\n",temp2,AL); + setsub8(AL,temp2); + tempz = (ZF_SET()) ? 1 : 0; + if (flags&D_FLAG) EDI--; + else EDI++; + c--; + cycles-=(is486)?5:8; + ins++; + } + ins--; + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0xAF: /*REP SCASW*/ + cpu_notreps++; +// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); + tempz = (fv) ? 1 : 0; + while ((c > 0) && (fv == tempz) && (cycles > 0)) + { + tempw=readmemw(es,DI); + if (abrt) { flags=of; break; } + setsub16(AX,tempw); + tempz = (ZF_SET()) ? 1 : 0; + if (flags&D_FLAG) DI-=2; + else DI+=2; + c--; + cycles-=(is486)?5:8; + ins++; + } + ins--; + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x1AF: /*REP SCASL*/ + cpu_notreps++; +// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc); + tempz = (fv) ? 1 : 0; + while ((c > 0) && (fv == tempz) && (cycles > 0)) + { + templ=readmeml(es,DI); + if (abrt) { flags=of; break; } + setsub32(EAX,templ); + tempz = (ZF_SET()) ? 1 : 0; + if (flags&D_FLAG) DI-=4; + else DI+=4; + c--; + cycles-=(is486)?5:8; + ins++; + } + ins--; + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x2AF: /*REP SCASW*/ + cpu_notreps++; +// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); + tempz = (fv) ? 1 : 0; + while ((c > 0) && (fv == tempz) && (cycles > 0)) + { + tempw=readmemw(es,EDI); + if (abrt) { flags=of; break; } + setsub16(AX,tempw); + tempz = (ZF_SET()) ? 1 : 0; + if (flags&D_FLAG) EDI-=2; + else EDI+=2; + c--; + cycles-=(is486)?5:8; + ins++; + } + ins--; + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + case 0x3AF: /*REP SCASL*/ + cpu_notreps++; +// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc); + tempz = (fv) ? 1 : 0; + while ((c > 0) && (fv == tempz) && (cycles > 0)) + { + templ=readmeml(es,EDI); + if (abrt) { flags=of; break; } + setsub32(EAX,templ); + tempz = (ZF_SET()) ? 1 : 0; + if (flags&D_FLAG) EDI-=4; + else EDI+=4; + c--; + cycles-=(is486)?5:8; + ins++; + } + ins--; + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; } + else firstrepcycle=1; + break; + + + default: + pc=ipc; + cycles-=20; + pclog("Bad REP %02X %i\n", temp, rep32 >> 8); + x86illegal(); + } + if (rep32&0x200) ECX=c; + else CX=c; + CPU_BLOCK_END(); + return abrt; +//pclog("rep cpu_block_end=%d %p\n", cpu_block_end, (void *)&cpu_block_end); +// if (output) pclog("%03X %03X\n",rep32,use32); +} + +int checkio(int port) +{ + uint16_t t; + uint8_t d; + cpl_override = 1; + t = readmemw(tr.base, 0x66); + cpl_override = 0; +// pclog("CheckIO 1 %08X %04x %02x\n",tr.base, eflags, _cs.access); + if (abrt) return 0; +// pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3)); + if ((t+(port>>3))>tr.limit) return 1; + cpl_override = 1; + d = readmemb386l(0, tr.base + t + (port >> 3)); +// d=readmemb(tr.base,t+(port>>3)); + cpl_override = 0; +// pclog("%02X %02X\n",d,d&(1<<(port&7))); + return d&(1<<(port&7)); +} + +int xout=0; + + +#define divexcp() { \ + pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,pc); \ + x86_int(0); \ +} + +int divl(uint32_t val) +{ + if (val==0) + { + divexcp(); + return 1; + } + uint64_t num=(((uint64_t)EDX)<<32)|EAX; + uint64_t quo=num/val; + uint32_t rem=num%val; + uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF); + if (quo!=(uint64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} +int idivl(int32_t val) +{ + if (val==0) + { + divexcp(); + return 1; + } + int64_t num=(((uint64_t)EDX)<<32)|EAX; + int64_t quo=num/val; + int32_t rem=num%val; + int32_t quo32=(int32_t)(quo&0xFFFFFFFF); + if (quo!=(int64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} + + +void cpu_386_flags_extract() +{ + flags_extract(); +} +void cpu_386_flags_rebuild() +{ + flags_rebuild(); +} + +int oldi; + +uint32_t testr[9]; +int dontprint=0; + +#define OP_TABLE(name) ops_ ## name + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/) +//#define CACHE_ON() 0 + +static int cycles_main = 0; +void exec386(int cycs) +{ + uint8_t temp; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + int trap = flags & T_FLAG; +//output = 3; + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += 1000; + cycles_start = cycles; + + timer_start_period(cycles); +// output=3; + while (cycles>0) + { + int stack_check = 0; + +// if ((pc & 0xf0000000) == 0x26470948) +// fatal("Bad\n"); + +/* if (SS != 0x30) + stack_check = 1; + if (SS == 0x30 && ESP < 0x100) + output = 3;*/ +// if (stack32 && (ESP >= 2 && ESP < 0x10)) +// stack_check = 1; +// if (CS == 0x117) +// output = 3; +// if (cs+pc == 0x7c00) +// output = 3; +// if (output) +// dump_block(); +// if (ins > 19428567) +// output = 3; +// if (ins > 161000000) +// output = 3; +/* if (ins > 363365892) + { + if (!output) + timetolive = 15000; + output = 3; + }*/ +/* if (cr0 & (1 << 31)) + output = 3; + else + output = 0;*/ + +// if (CS == 0x28 && pc == 0x8000A89D) +// fatal("Over\n"); +// if (CS == 0xFDC8 && pc == 0x00005488) +// output = 3; +// if (ins >= 265000000) output = 1; + + oldcs = CS; + oldpc = pc; + oldcpl = CPL; + op32 = use32; + + + cycdiff=0; + oldcyc=cycles; + if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x %i\n", CS, pc, SS,ESP, codeblock_page_dirty[0x1de]); + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, DX, SI, DI, SP); + while (!cpu_block_end) + { + oldcs=CS; + oldpc=pc; + oldcpl=CPL; + op32=use32; + + ea_seg = &_ds; + ssegs = 0; + + opcodestart: + fetchdat = fastreadl(cs + pc); +// if (!fetchdat) +// fatal("Dead with cache off\n"); + if (!abrt) + { + tempc = CF_SET(); + trap = flags & T_FLAG; + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + if (output == 3) + pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], ram[0x8f140]); + + pc++; + x86_opcodes[(opcode | op32) & 0x3ff](fetchdat); + } + + if (!use32) pc &= 0xffff; + + if (((cs + pc) >> 12) != pccache) + CPU_BLOCK_END(); + +/* if (ssegs) + { + ds=oldds; + ss=oldss; + ssegs=0; + }*/ + if (abrt) + CPU_BLOCK_END(); + + ins++; + insc++; + +/* if ((cs + pc) == 4) + fatal("4\n");*/ +/* if (ins >= 141400000) + output = 3;*/ + } + } + else + { + int dirty = 0; + uint32_t phys_addr = get_phys(cs+pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + +// if ((cs+pc) == 0x100030) +// pclog("160070 : phys=%08x %04x(%08x):%08x\n", phys_addr, SS, ss, ESP); + if (block) + { +// if ((cs+pc) == 0x100030) +// pclog("160070 : block\n", phys_addr); + + valid_block = (block->pc == cs + pc) && (block->_cs == cs) && + (block->use32 == use32) && (block->phys == phys_addr); + + if (valid_block && codeblock_page_dirty[phys_addr >> 12]) + dirty = codegen_check_dirty(phys_addr); + +// if (pc == 0x804003f0) +// if (!(valid_block && !dirty)) +// if ((pc & 0xffffff00) == 0xe00 || (pc & 0xffffff00) == 0xd00) +// if ((cs+pc) == 0x100030) +// pclog("this block pc=%08x,%08x cs=%08x,%08x use32=%03x,%03x phys=%08x,%08x v=%i d=%i\n", +// cs+pc, block->pc, cs, block->_cs, use32, block->use32, phys_addr, block->phys, valid_block, dirty); + } +//pclog("block - %08x:%08x %08x %03x %08x %08x %08x %i\n", cs, pc, phys_addr, hash, codeblock_hash_pc[hash], codeblock_hash_cs[hash], codeblock_hash_phys[hash], codeblock_page_dirty[phys_addr >> 12]); + if (valid_block && !dirty) + { + void (*code)() = (void *)&block->data[BLOCK_START]; +/* if ((cs+pc) == 0xfe771) + output = 1;*/ +// if (output && pc != 0xe790 && pc != 0xe798) pclog("Calling block %i %08X for %08X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", codeblock_hash_pnt[HASH(cs + pc)], code, cs+pc, EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); +/* if (pc == 0xe79e) + { + fatal("Here\n"); + }*/ + if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x %08x %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0], get_phys(cs+pc), block->phys); +/* if (CS == 0xfef1 && pc == 0x0c07) + { + int a=1; + }*/ + oldcs = CS; + oldcpl = CPL; +inrecomp=1; + code(); +inrecomp=0; + if (!use32) pc &= 0xffff; +// cpu_recomp_ins += block->ins; + cpu_recomp_blocks++; +/* ins += codeblock_ins[index]; + insc += codeblock_ins[index];*/ +/* pclog("Exit block now %04X:%04X\n", CS, pc);*/ + } + else if (!abrt) + { +// pclog("Hash %08x %i\n", codeblock_hash_pc[HASH(cs + pc)], codeblock_page_dirty[(cs + pc) >> 12]); + cpu_block_end = 0; + + cpu_new_blocks++; + + codegen_block_init(phys_addr); + +// if (CS == 0x70 && pc == 0x84a) +// output = 3; +// if (((cs + pc) & ~0x1f) == 0x0010A182) +// output |= 2; +// if ((cs+pc) == 0xfe771) +// output = 1; + if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); + while (!cpu_block_end) + { + oldcs=CS; + oldpc=pc; + oldcpl=CPL; + op32=use32; + + ea_seg = &_ds; + ssegs = 0; + + opcodestart_compile: + fetchdat = fastreadl(cs + pc); +// if (fetchdat == 0xffffffff) +// fatal("Dead ffffffff\n"); +// if (!fetchdat) +// fatal("Dead\n"); + if (!abrt) + { + tempc = CF_SET(); + trap = flags & T_FLAG; + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + if (output == 3) + pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache); + + if (((cs + pc) >> 12) != pccache) + CPU_BLOCK_END(); + + pc++; +/* if (opcode == 0xf2 || opcode == 0xf3 || ((opcode & ~7) == 0xd8)*/ +// codegen_set_op32(); + + codegen_generate_call(opcode, x86_opcodes[(opcode | op32) & 0x3ff], fetchdat, pc, pc-1); + + x86_opcodes[(opcode | op32) & 0x3ff](fetchdat); + } + + if (!use32) pc &= 0xffff; + + if (((cs + pc) >> 12) != pccache) + CPU_BLOCK_END(); +//pclog("cpu_block_end=%d %p\n", cpu_block_end, (void *)&cpu_block_end); +/* if (ssegs) + { + ds=oldds; + ss=oldss; + ssegs=0; + codegen_generate_seg_restore(); + }*/ + //codegen_check_abrt(); + if (abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } +//if (pc==0x5b42) +// cpu_block_end = 1; + ins++; + insc++; + } + + if (!abrt) + codegen_block_end(); +// output &= ~2; + } +// if (output && (SP & 1)) +// fatal("odd SP\n"); + } +//if (CS == 0x9087 && pc == 0x3763) +// fatal("Here\n"); + cycdiff=oldcyc-cycles; + tsc += cycdiff; + +// timer_end_period(cycles); + + if (abrt) + { + flags_rebuild(); + tempi = abrt; + abrt = 0; + x86_doabrt(tempi); + if (abrt) + { + abrt = 0; + CS = oldcs; + pc = oldpc; + pclog("Double fault %i\n", ins); + pmodeint(8, 0); + if (abrt) + { + abrt = 0; + softresetx86(); + fatal("Triple fault - reset\n"); + } + } + } + + if ((flags&I_FLAG) && pic_intpending) + { + temp=picinterrupt(); + if (temp!=0xFF) + { +// pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc); + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(temp,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,pc); + SP-=6; + addr=temp<<2; + flags&=~I_FLAG; + flags&=~T_FLAG; + oxpc=pc; + pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } +/* if (SS == 0x30 && stack_check) + pclog("Load stack %04x(%08x):%08x\n", SS, ss, ESP);*/ + } + timer_end_period(cycles); +//if ((cs + pc) == 0x2ea5e) +// fatal(""); + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c new file mode 100644 index 0000000..89b9df2 --- /dev/null +++ b/src/386_dynarec_ops.c @@ -0,0 +1,139 @@ +#ifdef DYNAREC +#include "ibm.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "x86_flags.h" +#include "codegen.h" + +#define CPU_BLOCK_END() cpu_block_end = 1 + +#include "386_common.h" + + +extern uint16_t *mod1add[2][8]; +extern uint32_t *mod1seg[8]; + +/*Copy-and-pasted from 386_dynarec.c, is not in a header file because it will + eventually be different for the dynarec ops*/ +static inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = ea_seg->base; + ea_rseg = ea_seg->seg; + if (rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (mod) + { + case 0: + eaaddr = regs[sib & 7].l; + pc++; + break; + case 1: + pc++; + eaaddr = ((uint32_t)(int8_t)getbyte()) + regs[sib & 7].l; +// pc++; + break; + case 2: + eaaddr = (fastreadl(cs + pc + 1)) + regs[sib & 7].l; + pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !mod) + eaaddr = getlong(); + else if ((sib & 6) == 4 && !ssegs) + { + easeg = ss; + ea_rseg = SS; + ea_seg = &_ss; + } + if (((sib >> 3) & 7) != 4) + eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + eaaddr = regs[rm].l; + if (mod) + { + if (rm == 5 && !ssegs) + { + easeg = ss; + ea_rseg = SS; + ea_seg = &_ss; + } + if (mod == 1) + { + eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + pc++; + } + else + { + eaaddr += getlong(); + } + } + else if (rm == 5) + { + eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) + { + if ( readlookup2[(easeg + eaaddr) >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + if (writelookup2[(easeg + eaaddr) >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + } +} + +static inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = ea_seg->base; + ea_rseg = ea_seg->seg; + if (!mod && rm == 6) + { + eaaddr = getword(); + } + else + { + switch (mod) + { + case 0: + eaaddr = 0; + break; + case 1: + eaaddr = (uint16_t)(int8_t)(rmdat >> 8); pc++; + break; + case 2: + eaaddr = getword(); + break; + } + eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]); + if (mod1seg[rm] == &ss && !ssegs) + { + easeg = ss; + ea_rseg = SS; + ea_seg = &_ss; + } + eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) + { + if ( readlookup2[(easeg + eaaddr) >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + if (writelookup2[(easeg + eaaddr) >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr); + } +} + +#define fetch_ea_16(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 1; } +#define fetch_ea_32(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_32_long(rmdat); } if (abrt) return 1 + +#define OP_TABLE(name) dynarec_ops_ ## name + +#include "386_ops.h" +#endif diff --git a/src/386_ops.h b/src/386_ops.h index e04bd66..5e80cbd 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -2,6 +2,10 @@ OpFn *x86_opcodes; OpFn *x86_opcodes_0f; +#ifdef DYNAREC +OpFn *x86_dynarec_opcodes; +OpFn *x86_dynarec_opcodes_0f; +#endif #define ILLEGAL_ON(cond) \ do \ @@ -180,13 +184,7 @@ static int op0F_l_a32(uint32_t fetchdat) return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } -void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f) -{ - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; -} - -OpFn ops_286_0f[1024] = +OpFn OP_TABLE(286_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -277,7 +275,7 @@ OpFn ops_286_0f[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -OpFn ops_386_0f[1024] = +OpFn OP_TABLE(386_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -368,7 +366,7 @@ OpFn ops_386_0f[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -OpFn ops_winchip_0f[1024] = +OpFn OP_TABLE(winchip_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -459,14 +457,14 @@ OpFn ops_winchip_0f[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -OpFn ops_286[1024] = +OpFn OP_TABLE(286)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, /*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, /*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, /*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, @@ -487,8 +485,8 @@ OpFn ops_286[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, /*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, /*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, /*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, @@ -509,8 +507,8 @@ OpFn ops_286[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, /*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, /*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, /*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, @@ -531,8 +529,8 @@ OpFn ops_286[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, /*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, /*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, /*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, @@ -550,18 +548,18 @@ OpFn ops_286[1024] = /*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, }; -OpFn ops_386[1024] = +OpFn OP_TABLE(386)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, /*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, /*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, /*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, op_FS, op_GS, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, opFS_w_a16, opGS_w_a16, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, /*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, /*80*/ op80_a16, op81_w_a16, op80_a16, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, @@ -578,12 +576,12 @@ OpFn ops_386[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_l_rmw_a16,opADD_b_rm_a16, opADD_l_rm_a16, opADD_AL_imm, opADD_EAX_imm, opPUSH_ES_l, opPOP_ES_l, opOR_b_rmw_a16, opOR_l_rmw_a16, opOR_b_rm_a16, opOR_l_rm_a16, opOR_AL_imm, opOR_EAX_imm, opPUSH_CS_l, op0F_l_a16, /*10*/ opADC_b_rmw_a16,opADC_l_rmw_a16,opADC_b_rm_a16, opADC_l_rm_a16, opADC_AL_imm, opADC_EAX_imm, opPUSH_SS_l, opPOP_SS_l, opSBB_b_rmw_a16,opSBB_l_rmw_a16,opSBB_b_rm_a16, opSBB_l_rm_a16, opSBB_AL_imm, opSBB_EAX_imm, opPUSH_DS_l, opPOP_DS_l, -/*20*/ opAND_b_rmw_a16,opAND_l_rmw_a16,opAND_b_rm_a16, opAND_l_rm_a16, opAND_AL_imm, opAND_EAX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_l_rmw_a16,opSUB_b_rm_a16, opSUB_l_rm_a16, opSUB_AL_imm, opSUB_EAX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_l_rmw_a16,opXOR_b_rm_a16, opXOR_l_rm_a16, opXOR_AL_imm, opXOR_EAX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_l_rmw_a16,opCMP_b_rm_a16, opCMP_l_rm_a16, opCMP_AL_imm, opCMP_EAX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a16,opAND_l_rmw_a16,opAND_b_rm_a16, opAND_l_rm_a16, opAND_AL_imm, opAND_EAX_imm, opES_l_a16, opDAA, opSUB_b_rmw_a16,opSUB_l_rmw_a16,opSUB_b_rm_a16, opSUB_l_rm_a16, opSUB_AL_imm, opSUB_EAX_imm, opCS_l_a16, opDAS, +/*30*/ opXOR_b_rmw_a16,opXOR_l_rmw_a16,opXOR_b_rm_a16, opXOR_l_rm_a16, opXOR_AL_imm, opXOR_EAX_imm, opSS_l_a16, opAAA, opCMP_b_rmw_a16,opCMP_l_rmw_a16,opCMP_b_rm_a16, opCMP_l_rm_a16, opCMP_AL_imm, opCMP_EAX_imm, opDS_l_a16, opAAS, /*40*/ opINC_EAX, opINC_ECX, opINC_EDX, opINC_EBX, opINC_ESP, opINC_EBP, opINC_ESI, opINC_EDI, opDEC_EAX, opDEC_ECX, opDEC_EDX, opDEC_EBX, opDEC_ESP, opDEC_EBP, opDEC_ESI, opDEC_EDI, /*50*/ opPUSH_EAX, opPUSH_ECX, opPUSH_EDX, opPUSH_EBX, opPUSH_ESP, opPUSH_EBP, opPUSH_ESI, opPUSH_EDI, opPOP_EAX, opPOP_ECX, opPOP_EDX, opPOP_EBX, opPOP_ESP, opPOP_EBP, opPOP_ESI, opPOP_EDI, -/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a16, opARPL_a16, op_FS, op_GS, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a16,opPUSH_imm_bl, opIMUL_l_ib_a16,opINSB_a16, opINSL_a16, opOUTSB_a16, opOUTSL_a16, +/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a16, opARPL_a16, opFS_l_a16, opGS_l_a16, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a16,opPUSH_imm_bl, opIMUL_l_ib_a16,opINSB_a16, opINSL_a16, opOUTSB_a16, opOUTSL_a16, /*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, /*80*/ op80_a16, op81_l_a16, op80_a16, op83_l_a16, opTEST_b_a16, opTEST_l_a16, opXCHG_b_a16, opXCHG_l_a16, opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, opMOV_l_seg_a16,opLEA_l_a16, opMOV_seg_w_a16,opPOPL_a16, @@ -600,12 +598,12 @@ OpFn ops_386[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a32,opADD_w_rmw_a32,opADD_b_rm_a32, opADD_w_rm_a32, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a32, opOR_w_rmw_a32, opOR_b_rm_a32, opOR_w_rm_a32, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a32, /*10*/ opADC_b_rmw_a32,opADC_w_rmw_a32,opADC_b_rm_a32, opADC_w_rm_a32, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a32,opSBB_w_rmw_a32,opSBB_b_rm_a32, opSBB_w_rm_a32, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a32,opAND_w_rmw_a32,opAND_b_rm_a32, opAND_w_rm_a32, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a32,opSUB_w_rmw_a32,opSUB_b_rm_a32, opSUB_w_rm_a32, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a32,opXOR_w_rmw_a32,opXOR_b_rm_a32, opXOR_w_rm_a32, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a32,opCMP_w_rmw_a32,opCMP_b_rm_a32, opCMP_w_rm_a32, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a32,opAND_w_rmw_a32,opAND_b_rm_a32, opAND_w_rm_a32, opAND_AL_imm, opAND_AX_imm, opES_w_a32, opDAA, opSUB_b_rmw_a32,opSUB_w_rmw_a32,opSUB_b_rm_a32, opSUB_w_rm_a32, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a32, opDAS, +/*30*/ opXOR_b_rmw_a32,opXOR_w_rmw_a32,opXOR_b_rm_a32, opXOR_w_rm_a32, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a32, opAAA, opCMP_b_rmw_a32,opCMP_w_rmw_a32,opCMP_b_rm_a32, opCMP_w_rm_a32, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a32, opAAS, /*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, /*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a32, opARPL_a32, op_FS, op_GS, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a32,opPUSH_imm_bw, opIMUL_w_ib_a32,opINSB_a32, opINSW_a32, opOUTSB_a32, opOUTSW_a32, +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a32, opARPL_a32, opFS_w_a32, opGS_w_a32, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a32,opPUSH_imm_bw, opIMUL_w_ib_a32,opINSB_a32, opINSW_a32, opOUTSB_a32, opOUTSW_a32, /*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, /*80*/ op80_a32, op81_w_a32, op80_a32, op83_w_a32, opTEST_b_a32, opTEST_w_a32, opXCHG_b_a32, opXCHG_w_a32, opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, opMOV_w_seg_a32,opLEA_w_a32, opMOV_seg_w_a32,opPOPW_a32, @@ -622,12 +620,12 @@ OpFn ops_386[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a32,opADD_l_rmw_a32,opADD_b_rm_a32, opADD_l_rm_a32, opADD_AL_imm, opADD_EAX_imm, opPUSH_ES_l, opPOP_ES_l, opOR_b_rmw_a32, opOR_l_rmw_a32, opOR_b_rm_a32, opOR_l_rm_a32, opOR_AL_imm, opOR_EAX_imm, opPUSH_CS_l, op0F_l_a32, /*10*/ opADC_b_rmw_a32,opADC_l_rmw_a32,opADC_b_rm_a32, opADC_l_rm_a32, opADC_AL_imm, opADC_EAX_imm, opPUSH_SS_l, opPOP_SS_l, opSBB_b_rmw_a32,opSBB_l_rmw_a32,opSBB_b_rm_a32, opSBB_l_rm_a32, opSBB_AL_imm, opSBB_EAX_imm, opPUSH_DS_l, opPOP_DS_l, -/*20*/ opAND_b_rmw_a32,opAND_l_rmw_a32,opAND_b_rm_a32, opAND_l_rm_a32, opAND_AL_imm, opAND_EAX_imm, op_ES, opDAA, opSUB_b_rmw_a32,opSUB_l_rmw_a32,opSUB_b_rm_a32, opSUB_l_rm_a32, opSUB_AL_imm, opSUB_EAX_imm, op_CS, opDAS, -/*30*/ opXOR_b_rmw_a32,opXOR_l_rmw_a32,opXOR_b_rm_a32, opXOR_l_rm_a32, opXOR_AL_imm, opXOR_EAX_imm, op_SS, opAAA, opCMP_b_rmw_a32,opCMP_l_rmw_a32,opCMP_b_rm_a32, opCMP_l_rm_a32, opCMP_AL_imm, opCMP_EAX_imm, op_DS, opAAS, +/*20*/ opAND_b_rmw_a32,opAND_l_rmw_a32,opAND_b_rm_a32, opAND_l_rm_a32, opAND_AL_imm, opAND_EAX_imm, opES_l_a32, opDAA, opSUB_b_rmw_a32,opSUB_l_rmw_a32,opSUB_b_rm_a32, opSUB_l_rm_a32, opSUB_AL_imm, opSUB_EAX_imm, opCS_l_a32, opDAS, +/*30*/ opXOR_b_rmw_a32,opXOR_l_rmw_a32,opXOR_b_rm_a32, opXOR_l_rm_a32, opXOR_AL_imm, opXOR_EAX_imm, opSS_l_a32, opAAA, opCMP_b_rmw_a32,opCMP_l_rmw_a32,opCMP_b_rm_a32, opCMP_l_rm_a32, opCMP_AL_imm, opCMP_EAX_imm, opDS_l_a32, opAAS, /*40*/ opINC_EAX, opINC_ECX, opINC_EDX, opINC_EBX, opINC_ESP, opINC_EBP, opINC_ESI, opINC_EDI, opDEC_EAX, opDEC_ECX, opDEC_EDX, opDEC_EBX, opDEC_ESP, opDEC_EBP, opDEC_ESI, opDEC_EDI, /*50*/ opPUSH_EAX, opPUSH_ECX, opPUSH_EDX, opPUSH_EBX, opPUSH_ESP, opPUSH_EBP, opPUSH_ESI, opPUSH_EDI, opPOP_EAX, opPOP_ECX, opPOP_EDX, opPOP_EBX, opPOP_ESP, opPOP_EBP, opPOP_ESI, opPOP_EDI, -/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a32, opARPL_a32, op_FS, op_GS, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a32,opPUSH_imm_bl, opIMUL_l_ib_a32,opINSB_a32, opINSL_a32, opOUTSB_a32, opOUTSL_a32, +/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a32, opARPL_a32, opFS_l_a32, opGS_l_a32, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a32,opPUSH_imm_bl, opIMUL_l_ib_a32,opINSB_a32, opINSL_a32, opOUTSB_a32, opOUTSL_a32, /*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, /*80*/ op80_a32, op81_l_a32, op80_a32, op83_l_a32, opTEST_b_a32, opTEST_l_a32, opXCHG_b_a32, opXCHG_l_a32, opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, opMOV_l_seg_a32,opLEA_l_a32, opMOV_seg_w_a32,opPOPL_a32, diff --git a/src/808x.c b/src/808x.c index 339aeee..bbfdaf8 100644 --- a/src/808x.c +++ b/src/808x.c @@ -630,7 +630,10 @@ void resetx86() // cs=0xFFFF0; pc=0; msw=0; - cr0=0; + if (is486) + cr0 = 1 << 30; + else + cr0 = 0; cr4 = 0; eflags=0; cgate32=0; diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 47d04ff..cf4cd3d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,9 @@ VPATH = . dosbox resid-fp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=i686 -fomit-frame-pointer -OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \ - config.o cpu.o dac.o device.o dma.o fdc.o gameport.o \ +CFLAGS = -O3 -march=i686 -fomit-frame-pointer -DDYNAREC +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \ + codegen_x86.o config.o cpu.o dac.o device.o dma.o fdc.o gameport.o \ headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o \ mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/codegen.h b/src/codegen.h new file mode 100644 index 0000000..20c00cb --- /dev/null +++ b/src/codegen.h @@ -0,0 +1,53 @@ +#ifdef DYNAREC + +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#include "codegen_x86.h" +#else +#error Dynamic recompiler not implemented on your platform +#endif + +typedef struct codeblock_t +{ + struct codeblock_t *prev, *next; + + uint32_t pc; + uint32_t _cs; + uint32_t endpc; + uint32_t checksum; + uint32_t phys; + uint32_t use32; + int pnt; + int ins; + + uint8_t data[8192]; +} codeblock_t; + +extern codeblock_t *codeblock; + +extern codeblock_t **codeblock_hash; +extern uint8_t *codeblock_page_dirty; + +void codegen_init(); +void codegen_block_init(uint32_t phys_addr); +void codegen_block_remove(); +void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +void codegen_generate_seg_restore(); +void codegen_check_abrt(); +void codegen_set_op32(); +void codegen_flush(); +void codegen_dirty(uint32_t addr); +int codegen_check_dirty(uint32_t phys_addr); + +extern int cpu_block_end; + +extern int cpu_recomp_blocks, cpu_recomp_ins, cpu_new_blocks; +extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_new_blocks_latched; +extern int cpu_recomp_flushes, cpu_recomp_flushes_latched; +extern int cpu_recomp_evicted, cpu_recomp_evicted_latched; +extern int cpu_recomp_reuse, cpu_recomp_reuse_latched; +extern int cpu_recomp_removed, cpu_recomp_removed_latched; + +extern int cpu_reps, cpu_reps_latched; +extern int cpu_notreps, cpu_notreps_latched; + +#endif diff --git a/src/codegen_x86.c b/src/codegen_x86.c new file mode 100644 index 0000000..d7bb793 --- /dev/null +++ b/src/codegen_x86.c @@ -0,0 +1,602 @@ +#define CHECKSUM + +#ifdef DYNAREC +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + +#include +#include "ibm.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" + +#include "codegen.h" + +#include "386_common.h" + +#define BLOCK_EXIT_OFFSET 0x1ff0 + +#define CPU_BLOCK_END() cpu_block_end = 1 + + + + +codeblock_t *codeblock; +codeblock_t **codeblock_hash; + +typedef struct page_t +{ + codeblock_t *block; +} page_t; + +page_t *pages; + +uint8_t *codeblock_page_dirty; + +static int block_current = 0; +static int block_num; +static int block_pos; + +int cpu_recomp_flushes, cpu_recomp_flushes_latched; +int cpu_recomp_evicted, cpu_recomp_evicted_latched; +int cpu_recomp_reuse, cpu_recomp_reuse_latched; +int cpu_recomp_removed, cpu_recomp_removed_latched; + +static uint32_t codegen_endpc; + + +static uint32_t last_op32; +static x86seg *last_ea_seg; +static int last_ssegs; + +static inline void addbyte(uint8_t val) +{ +// pclog("Addbyte %02X at %i %i\n", val, block_pos, cpu_block_end); + codeblock[block_current].data[block_pos++] = val; + if (block_pos >= 8000) + { + CPU_BLOCK_END(); + } +} + +static inline void addlong(uint32_t val) +{ +// pclog("Addlong %08X at %i %i\n", val, block_pos, cpu_block_end); + *(uint32_t *)&codeblock[block_current].data[block_pos] = val; + block_pos += 4; + if (block_pos >= 8000) + { + CPU_BLOCK_END(); + } +} + + +void codegen_init() +{ + int c; + + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + pages = malloc(((256 * 1024 * 1024) >> 12) * sizeof(page_t)); + + memset(codeblock, 0, sizeof(BLOCK_SIZE * sizeof(codeblock_t))); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(pages, 0, ((256 * 1024 * 1024) >> 12) * sizeof(page_t)); + + codeblock_page_dirty = malloc(1 << 20); + memset(codeblock_page_dirty, 1, 1 << 20); + + pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); +} + +void dump_block() +{ + codeblock_t *block = pages[0x119000 >> 12].block; + + pclog("dump_block:\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); + if (!block->pc) + fatal("Dead PC=0\n"); + + block = block->next; + } + pclog("dump_block done\n"); +} + +int codegen_check_dirty(uint32_t phys_addr) +{ +#ifdef CHECKSUM + int has_evicted = 0; + int dirty = 0; + codeblock_t *block = pages[phys_addr >> 12].block; +//pclog("codegen_check_dirty %08x %08x\n", phys_addr, pages[phys_addr >> 12].block); +// if ((phys_addr & ~0xfff) == 0x119000) pclog("dirty start\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + uint32_t checksum = 0; +// if ((phys_addr & ~0xfff) == 0x119000) pclog(" %08x\n", block->pc); + if (!block->pc) + fatal("!PC\n"); + +// if ((phys_addr & ~0xfff) == 0x119000) dump_block(); + +// if ((phys_addr & ~0xfff) == 0x119000) pclog(" %08x-%08x %08x-%08x\n", start_pc, end_pc, block->pc, block->endpc); + if (end_pc > start_pc) + { + for (; start_pc <= end_pc; start_pc += 4) + checksum += *(uint32_t *)&ram[start_pc]; + } + else + checksum = ~block->checksum; + + if (checksum != block->checksum) + { +// if ((phys_addr & ~0xfff) == 0x119000) pclog(" evict %08x %08x %p\n", checksum, block->checksum, (void *)block->prev); + if (block->pc == (cs+pc)) + dirty = 1; + + block->pc = 0;//xffffffff; + + if (block->prev) + { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + else + { + pages[block->phys >> 12].block = block->next; + if (block->next) + block->next->prev = NULL; + } + + has_evicted = 1; + + codeblock_hash[HASH(block->phys)] = NULL; + } + + block = block->next; + } +// if ((phys_addr & ~0xfff) == 0x8f000) pclog("dirty end\n"); + if (has_evicted) + { + cpu_recomp_evicted++; + + } + + mem_flush_write_page(phys_addr, cs+pc); + + codeblock_page_dirty[phys_addr >> 12] = 0; + return dirty; +#else + return 1; +#endif +} + +void codegen_block_init(uint32_t phys_addr) +{ + codeblock_t *block; + int has_evicted = 0; +// pclog("block_init %08x:%08x hash=%04x %08x\n", cs, pc, HASH(cs + pc), phys_addr); +//if (phys_addr > 0x100000) +// dump_block(); + if (codeblock_page_dirty[phys_addr >> 12]) + { + codeblock_t *last_block = NULL; + block = pages[phys_addr >> 12].block; +// pages[phys_addr >> 12].block = NULL; +// if ((phys_addr & ~0xfff) == 0x119000) pclog("Flush %08x\n", phys_addr); +//pclog("init start\n"); + while (block) + { + codeblock_t *old_block = block; + codeblock_t *next_block = block->next; + + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + uint32_t checksum = 0; + + if (!block->pc) + fatal("!PC on init\n"); + +//if ((phys_addr & ~0xfff) == 0x119000) dump_block(); + +// if ((phys_addr & ~0xfff) == 0x119000) pclog(" %p : %08x-%08x %08x-%08x\n", (void *)block, start_pc, end_pc, block->pc, block->endpc); + if (end_pc > start_pc) + { + for (; start_pc <= end_pc; start_pc += 4) + checksum += *(uint32_t *)&ram[start_pc]; + } + else + checksum = ~block->checksum; + + if (checksum != block->checksum) + { + if ((phys_addr & ~0xfff) == 0x119000) pclog(" evict %08x %08x %08x %p %p\n", block->pc, checksum, block->checksum, (void *)block->prev, (void *)last_block); + block->pc = 0;//xffffffff; + + if (block->prev) + { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + else + { + pages[block->phys >> 12].block = block->next; + if (block->next) + block->next->prev = NULL; + } + + codeblock_hash[HASH(block->phys)] = NULL; + + block->next = NULL; + } + + block = next_block; + last_block = old_block; + } +//if ((phys_addr & ~0xfff) == 0x119000) pclog("init end\n"); + codeblock_page_dirty[phys_addr >> 12] = 0; + mem_flush_write_page(phys_addr, cs+pc); + } + +/* if (has_evicted) + cpu_recomp_evicted++;*/ +// pclog("Build %08x\n",cs+pc); + + block_current = (block_current + 1) & BLOCK_MASK; + block = &codeblock[block_current]; + if (block->pc != 0)//xffffffff) + { +// if ((phys_addr & ~0xfff) == 0x119000) pclog("Block reuse - %04x old_pc=%08x new_pc=%08x\n", block_current, block->pc, cs+pc); +// if ((phys_addr & ~0xfff) == 0x119000) dump_block(); + /*Block currently used - throw out contents*/ + if (block->prev) + { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + else + { + pages[block->phys >> 12].block = block->next; + if (block->next) + block->next->prev = NULL; + } + codeblock_hash[HASH(block->phys)] = NULL; + cpu_recomp_reuse++; +// if ((phys_addr & ~0xfff) == 0x119000) pclog("Block reuse end\n"); +// if ((phys_addr & ~0xfff) == 0x119000) dump_block(); + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; + block->ins = 0; + block->pc = cs + pc; + block->_cs = cs; + block->pnt = block_current; + block->phys = phys_addr; + block->use32 = use32; + block->next = block->prev = NULL; + + block_pos = 0; + + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x83); /*ADDL $8,%esp*/ + addbyte(0xC4); + addbyte(0x08); + addbyte(0xC3); /*RET*/ + cpu_block_end = 0; + block_pos = 0; /*Entry code*/ + addbyte(0x83); /*SUBL $8,%esp*/ + addbyte(0xEC); + addbyte(0x08); + +// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); + + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; +} + +void codegen_block_remove() +{ + codeblock_t *block = &codeblock[block_current]; +//if ((block->phys & ~0xfff) == 0x119000) pclog("codegen_block_remove %08x\n", block->pc); + codeblock_hash[block_num] = NULL; + block->pc = 0;//xffffffff; + cpu_recomp_removed++; +// pclog("Remove block %i\n", block_num); +} + +void codegen_block_end() +{ + codeblock_t *block = &codeblock[block_current]; + codeblock_t *block_prev = pages[block->phys >> 12].block; + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = ((codegen_endpc + 3) & 0xffc) | (block->phys & ~0xfff); + uint32_t checksum = 0; + + block->endpc = end_pc; + +//if ((block->phys & ~0xfff) == 0x119000) pclog("codegen_block_end start\n"); +//if ((block->phys & ~0xfff) == 0x119000) dump_block(); + if (block_prev) + { + block->next = block_prev; + block_prev->prev = block; + pages[block->phys >> 12].block = block; + } + else + { + block->next = NULL; + pages[block->phys >> 12].block = block; + } + +//if ((block->phys & ~0xfff) == 0x119000) pclog("codegen_block_end end\n"); +//if ((block->phys & ~0xfff) == 0x119000) dump_block(); + +#ifdef CHECKSUM + if (end_pc > start_pc) + { +// pclog("block_end %08x-%08x %08x-%08x\n", start_pc, end_pc, block->pc, block->endpc); + for (; start_pc <= end_pc; start_pc += 4) + checksum += *(uint32_t *)&ram[start_pc]; +// pclog(" %08x\n", checksum); + } +#endif + + block->checksum = checksum; +// pclog("Checksum for %08x - %08x = %08x\n", codeblock_hash_pc[block_num] & ~3, end_pc, checksum); + + addbyte(0x83); /*ADDL $8,%esp*/ + addbyte(0xC4); + addbyte(0x08); + addbyte(0xC3); /*RET*/ +// pclog("End block %i\n", block_num); +} + +void codegen_flush() +{ + return; +} + +void codegen_dirty(uint32_t addr) +{ + codeblock_page_dirty[addr >> 12] = 1; +// pclog("codegen_dirty : %08x %04x:%04x\n", addr, CS, pc); +// if ((addr >> 12) == 0x152) +// pclog("Dirty : %08x %08x\n", addr, cs+pc); +/* int c; + int offset = HASH(addr & ~0xfff); +// pclog("codegen_dirty %08X\n", addr); + for (c = 0; c < 0x1000; c++) + { + if (!((codeblock_hash_pc[(c + offset) & HASH_MASK] ^ addr) & ~0xfff)) + { +// pclog("Throwing out %08X\n", codeblock_hash_pc[(c + offset) & HASH_MASK]); + codeblock_hash_pc[(c + offset) & HASH_MASK] = 0xffffffff; + } + }*/ +} + +static int opcode_needs_tempc[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*00*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*20*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*c0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*e0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*f0*/ +}; + +static int opcode_conditional_jump[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*60*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*d0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ +}; + +void codegen_debug() +{ + if (output) + { + pclog("At %04x(%08x):%04x %04x(%08x):%04x EAX=%08x BX=%04x BP=%04x EDX=%08x\n", CS, cs, pc, SS, ss, ESP, EAX, BX,BP, EDX); + } +} + +void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t op_32 = use32; + uint32_t op_pc = new_pc; + OpFn *op_table = x86_dynarec_opcodes; + x86seg *op_ea_seg = &_ds; + int op_ssegs = 0; + + while (1) + { + + switch (opcode) + { + case 0x0f: + op_table = x86_dynarec_opcodes_0f; + break; + + case 0x26: /*ES:*/ + op_ea_seg = &_es; + op_ssegs = 1; + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(4); + break; + case 0x2e: /*CS:*/ + op_ea_seg = &_cs; + op_ssegs = 1; + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(4); + break; + case 0x36: /*SS:*/ + op_ea_seg = &_ss; + op_ssegs = 1; + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(4); + break; + case 0x3e: /*DS:*/ + op_ea_seg = &_ds; + op_ssegs = 1; + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(4); + break; + case 0x64: /*FS:*/ + op_ea_seg = &_fs; + op_ssegs = 1; + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(4); + break; + case 0x65: /*GS:*/ + op_ea_seg = &_gs; + op_ssegs = 1; + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(4); + break; + + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(2); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(2); + break; + + case 0xf0: /*LOCK*/ + addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(2); + break; + + default: + goto generate_call; + } + + fetchdat = fastreadl(cs + op_pc); + if (abrt) + return; + opcode = fetchdat & 0xff; + fetchdat >>= 8; + + op_pc++; + } + +generate_call: + op = op_table[(opcode | op_32) & 0x3ff]; +// if (output) +// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); + if (opcode_needs_tempc[opcode]) + { + addbyte(0xa1); /*MOVL (flags), %eax*/ + addlong((uint32_t)&flags); + addbyte(0x83); /*ANDL $1, %eax*/ + addbyte(0xe0); + addbyte(0x01); + addbyte(0xa3); /*MOVL %eax, (tempc)*/ + addlong((uint32_t)&tempc); + } + if (op_ssegs != last_ssegs) + { + last_ssegs = op_ssegs; + addbyte(0xC7); /*MOVL $0,(ssegs)*/ + addbyte(0x05); + addlong((uint32_t)&ssegs); + addlong(op_ssegs); + } +// if (op_ea_seg != last_ea_seg) +// { +// last_ea_seg = op_ea_seg; + addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ + addbyte(0x05); + addlong((uint32_t)&ea_seg); + addlong((uint32_t)op_ea_seg); +// } + addbyte(0xC7); /*MOVL $new_pc,(pc)*/ + addbyte(0x05); + addlong((uint32_t)&pc); + addlong(op_pc); + addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0x05); + addlong((uint32_t)&oldpc); + addlong(old_pc); + if (op_32 != last_op32) + { + last_op32 = op_32; + addbyte(0xC7); /*MOVL $use32,(op32)*/ + addbyte(0x05); + addlong((uint32_t)&op32); + addlong(op_32); + } + + addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ + addbyte(0x04); + addbyte(0x24); + addlong(fetchdat); + + addbyte(0x83); /*ADD $1,ins*/ + addbyte(0x05); + addlong((uint32_t)&cpu_recomp_ins); + addbyte(1); + + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4]))); + + block->ins++; + + addbyte(0x09); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); + +// addbyte(0xE8); /*CALL*/ +// addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4]))); + + codegen_endpc = (cs + pc) + 8; +} + +void codegen_check_abrt() +{ + codeblock_t *block = &codeblock[block_current]; +// pclog("Generate check abrt at %08X\n", &codeblock[block_current][block_pos]); + addbyte(0xf7); addbyte(0x05); /*TESTL $-1, (abrt)*/ + addlong((uint32_t)&abrt); addlong(0xffffffff); + addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); +} + +#endif +#endif diff --git a/src/codegen_x86.h b/src/codegen_x86.h new file mode 100644 index 0000000..eb162a2 --- /dev/null +++ b/src/codegen_x86.h @@ -0,0 +1,13 @@ +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 + +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff + +#define HASH(l) ((l) & 0x1ffff) + +enum +{ + OP_RET = 0xc3 +}; diff --git a/src/cpu.c b/src/cpu.c index e0ce645..75ae0b8 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -281,8 +281,11 @@ void cpu_set() pclog("hasfpu - %i\n",hasfpu); pclog("is486 - %i %i\n",is486,cpu_s->cpu_type); +#ifdef DYNAREC + x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); +#else x86_setopcodes(ops_386, ops_386_0f); - +#endif memset(&msr, 0, sizeof(msr)); switch (cpu_s->cpu_type) @@ -292,7 +295,11 @@ void cpu_set() break; case CPU_286: +#ifdef DYNAREC + x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); +#else x86_setopcodes(ops_286, ops_286_0f); +#endif timing_rr = 2; /*register dest - register src*/ timing_rm = 7; /*register dest - memory src*/ timing_mr = 7; /*memory dest - register src*/ @@ -405,7 +412,11 @@ void cpu_set() break; case CPU_WINCHIP: +#ifdef DYNAREC + x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); +#else x86_setopcodes(ops_386, ops_winchip_0f); +#endif timing_rr = 1; /*register dest - register src*/ timing_rm = 2; /*register dest - memory src*/ timing_mr = 3; /*memory dest - register src*/ @@ -611,3 +622,19 @@ uint8_t cyrix_read(uint16_t addr, void *priv) } return 0xff; } + +#ifdef DYNAREC +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f) +{ + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; + x86_dynarec_opcodes = dynarec_opcodes; + x86_dynarec_opcodes_0f = dynarec_opcodes_0f; +} +#else +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f) +{ + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; +} +#endif diff --git a/src/mem.c b/src/mem.c index 966b1f5..fb0b7a3 100644 --- a/src/mem.c +++ b/src/mem.c @@ -15,6 +15,10 @@ #include "x86.h" #include "cpu.h" #include "rom.h" +#if DYNAREC +#include "x86_ops.h" +#include "codegen.h" +#endif static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); @@ -492,6 +496,9 @@ void flushmmucache() exit(-1); } }*/ +#if DYNAREC + codegen_flush(); +#endif } void flushmmucache_nopc() @@ -546,6 +553,23 @@ void flushmmucache_cr3() }*/ } + +void mem_flush_write_page(uint32_t addr, uint32_t virt) +{ + int c; + + for (c = 0; c < 256; c++) + { + uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xFFF) - (uintptr_t)(writelookup[c] << 12)]; + + if (writelookup2[writelookup[c]] == target) + { + writelookup2[writelookup[c]] = 0xffffffff; + writelookup[c] = 0xffffffff; + } + } +} + extern int output; #define mmutranslate_read(addr) mmutranslatereal(addr,0) @@ -716,6 +740,10 @@ void addwritelookup(uint32_t virt, uint32_t phys) writelookupp[writelnext]=mmu_perm; writelookup[writelnext++]=virt>>12; writelnext&=(cachesize-1); + +#if DYNAREC + codegen_dirty(phys); +#endif } #undef printf diff --git a/src/pc.c b/src/pc.c index f419174..1cb07f4 100644 --- a/src/pc.c +++ b/src/pc.c @@ -7,6 +7,10 @@ #include "ali1429.h" #include "amstrad.h" #include "cdrom-ioctl.h" +#ifdef DYNAREC +#include "x86_ops.h" +#include "codegen.h" +#endif #include "cdrom-null.h" #include "config.h" #include "cpu.h" @@ -201,6 +205,10 @@ void initpc() loadconfig(NULL); pclog("Config loaded\n"); + +#if DYNAREC + codegen_init(); +#endif cpuspeed2=(AT)?2:1; // cpuspeed2=cpuspeed; @@ -363,6 +371,27 @@ void runpc() segareads=egareads; segawrites=egawrites; scycles_lost = cycles_lost; +#if DYNAREC + cpu_recomp_blocks_latched = cpu_recomp_blocks; + cpu_recomp_ins_latched = cpu_recomp_ins; + cpu_new_blocks_latched = cpu_new_blocks; + cpu_recomp_flushes_latched = cpu_recomp_flushes; + cpu_recomp_evicted_latched = cpu_recomp_evicted; + cpu_recomp_reuse_latched = cpu_recomp_reuse; + cpu_recomp_removed_latched = cpu_recomp_removed; + cpu_reps_latched = cpu_reps; + cpu_notreps_latched = cpu_notreps; + + cpu_recomp_blocks = 0; + cpu_recomp_ins = 0; + cpu_new_blocks = 0; + cpu_recomp_flushes = 0; + cpu_recomp_evicted = 0; + cpu_recomp_reuse = 0; + cpu_recomp_removed = 0; + cpu_reps = 0; + cpu_notreps = 0; +#endif updatestatus=1; readlnum=writelnum=0; egareads=egawrites=0; diff --git a/src/win-status.c b/src/win-status.c index 0189bda..d817f55 100644 --- a/src/win-status.c +++ b/src/win-status.c @@ -8,11 +8,19 @@ #include "video.h" #include "resources.h" #include "win.h" +#ifdef DYNAREC +#include "x86_ops.h" +#include "codegen.h" +#endif HWND status_hwnd; int status_is_open = 0; extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; + +extern uint64_t main_time; +static uint64_t status_time; + static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { char device_s[4096]; @@ -21,27 +29,53 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR case WM_INITDIALOG: status_is_open = 1; case WM_USER: + { + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; sprintf(device_s, "CPU speed : %f MIPS\n" "FPU speed : %f MFLOPS\n\n" +#ifndef DYNAREC "Cache misses (read) : %i/sec\n" "Cache misses (write) : %i/sec\n\n" +#endif "Video throughput (read) : %i bytes/sec\n" "Video throughput (write) : %i bytes/sec\n\n" "Effective clockspeed : %iHz\n\n" - "Timer 0 frequency : %fHz\n\n", - mips, + "Timer 0 frequency : %fHz\n\n" + "CPU time : %f%% (%f%%)\n" +#ifdef DYNAREC + "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" + "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS\nREP : %i\nnot REP : %i\n" +#endif + ,mips, flops, +#ifndef DYNAREC sreadlnum, swritelnum, +#endif segareads, segawrites, clockrate - (sreadlnum*memwaitstate) - (swritelnum*memwaitstate) - scycles_lost, - pit_timer0_freq() + pit_timer0_freq(), + ((double)main_time * 100.0) / status_diff, + ((double)main_time * 100.0) / timer_freq +#ifdef DYNAREC + , cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched/cpu_recomp_blocks_latched, + cpu_recomp_flushes_latched, cpu_recomp_evicted_latched, + cpu_recomp_reuse_latched, cpu_recomp_removed_latched, + + ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq), + cpu_reps_latched, cpu_notreps_latched +#endif ); - + main_time = 0; +#ifndef DYNAREC device_add_status_info(device_s, 4096); +#endif SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + } return TRUE; case WM_COMMAND: diff --git a/src/win.c b/src/win.c index 38f0ad1..b3961a3 100644 --- a/src/win.c +++ b/src/win.c @@ -133,6 +133,8 @@ void leave_fullscreen() leave_fullscreen_flag = 1; } +uint64_t main_time; + void mainthread(LPVOID param) { int t = 0; @@ -155,6 +157,8 @@ void mainthread(LPVOID param) old_time = new_time; if (drawits > 0 && !pause) { + uint64_t start_time = timer_read(); + uint64_t end_time; drawits-=10; if (drawits>50) drawits=0; runpc(); frames++; @@ -164,6 +168,8 @@ void mainthread(LPVOID param) nvr_dosave = 0; savenvr(); } + end_time = timer_read(); + main_time += end_time - start_time; } else Sleep(1); diff --git a/src/x86.h b/src/x86.h index 3d1d851..1335cd7 100644 --- a/src/x86.h +++ b/src/x86.h @@ -101,3 +101,12 @@ extern int inscounts[256]; void x86illegal(); void x86seg_reset(); + + +static inline get_phys(uint32_t addr) +{ + if (!(cr0 >> 31)) + return addr & rammask; + + return mmutranslatereal(addr, 0) & rammask; +} diff --git a/src/x86_flags.h b/src/x86_flags.h index 61fe0c9..ff23dfa 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -27,9 +27,9 @@ enum FLAGS_SAR32, }; -static int flags_op; -static uint32_t flags_res; -static uint32_t flags_op1, flags_op2; +int flags_op; +uint32_t flags_res; +uint32_t flags_op1, flags_op2; static inline int ZF_SET() { diff --git a/src/x86_ops.h b/src/x86_ops.h index b5d9713..08c66be 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -1,6 +1,22 @@ typedef int (*OpFn)(uint32_t fetchdat); +#ifdef DYNAREC +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f); + +extern OpFn *x86_dynarec_opcodes; +extern OpFn *x86_dynarec_opcodes_0f; + +extern OpFn dynarec_ops_286[1024]; +extern OpFn dynarec_ops_286_0f[1024]; + +extern OpFn dynarec_ops_386[1024]; +extern OpFn dynarec_ops_386_0f[1024]; + +extern OpFn dynarec_ops_winchip_0f[1024]; + +#else void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f); +#endif extern OpFn *x86_opcodes; extern OpFn *x86_opcodes_0f; diff --git a/src/x86_ops_arith.h b/src/x86_ops_arith.h index e047878..632aca4 100644 --- a/src/x86_ops_arith.h +++ b/src/x86_ops_arith.h @@ -13,9 +13,9 @@ } \ else \ { \ - uint8_t dst = geteab(); if (abrt) return 0; \ + uint8_t dst = geteab(); if (abrt) return 1; \ uint8_t src = getr8(reg); \ - seteab(operation); if (abrt) return 0; \ + seteab(operation); if (abrt) return 1; \ setflags ## 8 flagops; \ cycles -= timing_mr; \ } \ @@ -35,9 +35,9 @@ } \ else \ { \ - uint8_t dst = geteab(); if (abrt) return 0; \ + uint8_t dst = geteab(); if (abrt) return 1; \ uint8_t src = getr8(reg); \ - seteab(operation); if (abrt) return 0; \ + seteab(operation); if (abrt) return 1; \ setflags ## 8 flagops; \ cycles -= timing_mr; \ } \ @@ -58,9 +58,9 @@ } \ else \ { \ - uint16_t dst = geteaw(); if (abrt) return 0; \ + uint16_t dst = geteaw(); if (abrt) return 1; \ uint16_t src = regs[reg].w; \ - seteaw(operation); if (abrt) return 0; \ + seteaw(operation); if (abrt) return 1; \ setflags ## 16 flagops; \ cycles -= timing_mr; \ } \ @@ -80,9 +80,9 @@ } \ else \ { \ - uint16_t dst = geteaw(); if (abrt) return 0; \ + uint16_t dst = geteaw(); if (abrt) return 1; \ uint16_t src = regs[reg].w; \ - seteaw(operation); if (abrt) return 0; \ + seteaw(operation); if (abrt) return 1; \ setflags ## 16 flagops; \ cycles -= timing_mr; \ } \ @@ -103,9 +103,9 @@ } \ else \ { \ - uint32_t dst = geteal(); if (abrt) return 0; \ + uint32_t dst = geteal(); if (abrt) return 1; \ uint32_t src = regs[reg].l; \ - seteal(operation); if (abrt) return 0; \ + seteal(operation); if (abrt) return 1; \ setflags ## 32 flagops; \ cycles -= timing_mrl; \ } \ @@ -125,9 +125,9 @@ } \ else \ { \ - uint32_t dst = geteal(); if (abrt) return 0; \ + uint32_t dst = geteal(); if (abrt) return 1; \ uint32_t src = regs[reg].l; \ - seteal(operation); if (abrt) return 0; \ + seteal(operation); if (abrt) return 1; \ setflags ## 32 flagops; \ cycles -= timing_mrl; \ } \ @@ -140,7 +140,7 @@ uint8_t dst, src; \ fetch_ea_16(fetchdat); \ dst = getr8(reg); \ - src = geteab(); if (abrt) return 0; \ + src = geteab(); if (abrt) return 1; \ setflags ## 8 flagops; \ setr8(reg, operation); \ cycles -= (mod == 3) ? timing_rr : timing_rm; \ @@ -152,7 +152,7 @@ uint8_t dst, src; \ fetch_ea_32(fetchdat); \ dst = getr8(reg); \ - src = geteab(); if (abrt) return 0; \ + src = geteab(); if (abrt) return 1; \ setflags ## 8 flagops; \ setr8(reg, operation); \ cycles -= (mod == 3) ? timing_rr : timing_rm; \ @@ -165,7 +165,7 @@ uint16_t dst, src; \ fetch_ea_16(fetchdat); \ dst = regs[reg].w; \ - src = geteaw(); if (abrt) return 0; \ + src = geteaw(); if (abrt) return 1; \ setflags ## 16 flagops; \ regs[reg].w = operation; \ cycles -= (mod == 3) ? timing_rr : timing_rm; \ @@ -177,7 +177,7 @@ uint16_t dst, src; \ fetch_ea_32(fetchdat); \ dst = regs[reg].w; \ - src = geteaw(); if (abrt) return 0; \ + src = geteaw(); if (abrt) return 1; \ setflags ## 16 flagops; \ regs[reg].w = operation; \ cycles -= (mod == 3) ? timing_rr : timing_rm; \ @@ -190,7 +190,7 @@ uint32_t dst, src; \ fetch_ea_16(fetchdat); \ dst = regs[reg].l; \ - src = geteal(); if (abrt) return 0; \ + src = geteal(); if (abrt) return 1; \ setflags ## 32 flagops; \ regs[reg].l = operation; \ cycles -= (mod == 3) ? timing_rr : timing_rml; \ @@ -202,7 +202,7 @@ uint32_t dst, src; \ fetch_ea_32(fetchdat); \ dst = regs[reg].l; \ - src = geteal(); if (abrt) return 0; \ + src = geteal(); if (abrt) return 1; \ setflags ## 32 flagops; \ regs[reg].l = operation; \ cycles -= (mod == 3) ? timing_rr : timing_rml; \ @@ -235,7 +235,7 @@ { \ int tempc = CF_SET(); \ uint32_t dst = EAX; \ - uint32_t src = getlong(); \ + uint32_t src = getlong(); if (abrt) return 1; \ setflags ## 32 flagops; \ EAX = operation; \ cycles -= timing_rr; \ @@ -254,7 +254,7 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat) { uint8_t dst; fetch_ea_16(fetchdat); - dst = geteab(); if (abrt) return 0; + dst = geteab(); if (abrt) return 1; setsub8(dst, getr8(reg)); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); @@ -264,7 +264,7 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat) { uint8_t dst; fetch_ea_32(fetchdat); - dst = geteab(); if (abrt) return 0; + dst = geteab(); if (abrt) return 1; setsub8(dst, getr8(reg)); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); @@ -275,7 +275,7 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat) { uint16_t dst; fetch_ea_16(fetchdat); - dst = geteaw(); if (abrt) return 0; + dst = geteaw(); if (abrt) return 1; setsub16(dst, regs[reg].w); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); @@ -285,7 +285,7 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat) { uint16_t dst; fetch_ea_32(fetchdat); - dst = geteaw(); if (abrt) return 0; + dst = geteaw(); if (abrt) return 1; setsub16(dst, regs[reg].w); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); @@ -296,7 +296,7 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat) { uint32_t dst; fetch_ea_16(fetchdat); - dst = geteal(); if (abrt) return 0; + dst = geteal(); if (abrt) return 1; setsub32(dst, regs[reg].l); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); @@ -306,7 +306,7 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat) { uint32_t dst; fetch_ea_32(fetchdat); - dst = geteal(); if (abrt) return 0; + dst = geteal(); if (abrt) return 1; setsub32(dst, regs[reg].l); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); @@ -317,7 +317,7 @@ static int opCMP_b_rm_a16(uint32_t fetchdat) { uint8_t src; fetch_ea_16(fetchdat); - src = geteab(); if (abrt) return 0; + src = geteab(); if (abrt) return 1; setsub8(getr8(reg), src); cycles -= (mod == 3) ? timing_rr : timing_rm; return 0; @@ -326,7 +326,7 @@ static int opCMP_b_rm_a32(uint32_t fetchdat) { uint8_t src; fetch_ea_32(fetchdat); - src = geteab(); if (abrt) return 0; + src = geteab(); if (abrt) return 1; setsub8(getr8(reg), src); cycles -= (mod == 3) ? timing_rr : timing_rm; return 0; @@ -336,7 +336,7 @@ static int opCMP_w_rm_a16(uint32_t fetchdat) { uint16_t src; fetch_ea_16(fetchdat); - src = geteaw(); if (abrt) return 0; + src = geteaw(); if (abrt) return 1; setsub16(regs[reg].w, src); cycles -= (mod == 3) ? timing_rr : timing_rm; return 0; @@ -345,7 +345,7 @@ static int opCMP_w_rm_a32(uint32_t fetchdat) { uint16_t src; fetch_ea_32(fetchdat); - src = geteaw(); if (abrt) return 0; + src = geteaw(); if (abrt) return 1; setsub16(regs[reg].w, src); cycles -= (mod == 3) ? timing_rr : timing_rm; return 0; @@ -355,7 +355,7 @@ static int opCMP_l_rm_a16(uint32_t fetchdat) { uint32_t src; fetch_ea_16(fetchdat); - src = geteal(); if (abrt) return 0; + src = geteal(); if (abrt) return 1; setsub32(regs[reg].l, src); cycles -= (mod == 3) ? timing_rr : timing_rml; return 0; @@ -364,7 +364,7 @@ static int opCMP_l_rm_a32(uint32_t fetchdat) { uint32_t src; fetch_ea_32(fetchdat); - src = geteal(); if (abrt) return 0; + src = geteal(); if (abrt) return 1; setsub32(regs[reg].l, src); cycles -= (mod == 3) ? timing_rr : timing_rml; return 0; @@ -388,7 +388,7 @@ static int opCMP_AX_imm(uint32_t fetchdat) static int opCMP_EAX_imm(uint32_t fetchdat) { - uint32_t src = getlong(); + uint32_t src = getlong(); if (abrt) return 1; setsub32(EAX, src); cycles -= timing_rr; return 0; @@ -398,7 +398,7 @@ static int opTEST_b_a16(uint32_t fetchdat) { uint8_t temp, temp2; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; temp2 = getr8(reg); setznp8(temp & temp2); if (is486) cycles -= ((mod == 3) ? 1 : 2); @@ -409,7 +409,7 @@ static int opTEST_b_a32(uint32_t fetchdat) { uint8_t temp, temp2; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; temp2 = getr8(reg); setznp8(temp & temp2); if (is486) cycles -= ((mod == 3) ? 1 : 2); @@ -421,7 +421,7 @@ static int opTEST_w_a16(uint32_t fetchdat) { uint16_t temp, temp2; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; temp2 = regs[reg].w; setznp16(temp & temp2); if (is486) cycles -= ((mod == 3) ? 1 : 2); @@ -432,7 +432,7 @@ static int opTEST_w_a32(uint32_t fetchdat) { uint16_t temp, temp2; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; temp2 = regs[reg].w; setznp16(temp & temp2); if (is486) cycles -= ((mod == 3) ? 1 : 2); @@ -444,7 +444,7 @@ static int opTEST_l_a16(uint32_t fetchdat) { uint32_t temp, temp2; fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; temp2 = regs[reg].l; setznp32(temp & temp2); if (is486) cycles -= ((mod == 3) ? 1 : 2); @@ -455,7 +455,7 @@ static int opTEST_l_a32(uint32_t fetchdat) { uint32_t temp, temp2; fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; temp2 = regs[reg].l; setznp32(temp & temp2); if (is486) cycles -= ((mod == 3) ? 1 : 2); @@ -479,7 +479,7 @@ static int opTEST_AX(uint32_t fetchdat) } static int opTEST_EAX(uint32_t fetchdat) { - uint32_t temp = getlong(); if (abrt) return 0; + uint32_t temp = getlong(); if (abrt) return 1; setznp32(EAX & temp); cycles -= timing_rr; return 0; @@ -487,44 +487,44 @@ static int opTEST_EAX(uint32_t fetchdat) #define ARITH_MULTI(ea_width, flag_width) \ - dst = getea ## ea_width(); if (abrt) return 0; \ + dst = getea ## ea_width(); if (abrt) return 1; \ switch (rmdat&0x38) \ { \ case 0x00: /*ADD ea, #*/ \ - setea ## ea_width(dst + src); if (abrt) return 0; \ + setea ## ea_width(dst + src); if (abrt) return 1; \ setadd ## flag_width(dst, src); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ case 0x08: /*OR ea, #*/ \ dst |= src; \ - setea ## ea_width(dst); if (abrt) return 0; \ + setea ## ea_width(dst); if (abrt) return 1; \ setznp ## flag_width(dst); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ case 0x10: /*ADC ea, #*/ \ - setea ## ea_width(dst + src + tempc); if (abrt) return 0; \ + setea ## ea_width(dst + src + tempc); if (abrt) return 1; \ setadc ## flag_width(dst, src); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ case 0x18: /*SBB ea, #*/ \ - setea ## ea_width(dst - (src + tempc)); if (abrt) return 0; \ + setea ## ea_width(dst - (src + tempc)); if (abrt) return 1; \ setsbc ## flag_width(dst, src); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ case 0x20: /*AND ea, #*/ \ dst &= src; \ - setea ## ea_width(dst); if (abrt) return 0; \ + setea ## ea_width(dst); if (abrt) return 1; \ setznp ## flag_width(dst); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ case 0x28: /*SUB ea, #*/ \ - setea ## ea_width(dst - src); if (abrt) return 0; \ + setea ## ea_width(dst - src); if (abrt) return 1; \ setsub ## flag_width(dst, src); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ case 0x30: /*XOR ea, #*/ \ dst ^= src; \ - setea ## ea_width(dst); if (abrt) return 0; \ + setea ## ea_width(dst); if (abrt) return 1; \ setznp ## flag_width(dst); \ cycles -= (mod == 3) ? timing_rr : timing_mr; \ break; \ @@ -541,7 +541,7 @@ static int op80_a16(uint32_t fetchdat) uint8_t src, dst; fetch_ea_16(fetchdat); - src = getbyte(); if (abrt) return 0; + src = getbyte(); if (abrt) return 1; ARITH_MULTI(b, 8); return 0; @@ -551,7 +551,7 @@ static int op80_a32(uint32_t fetchdat) uint8_t src, dst; fetch_ea_32(fetchdat); - src = getbyte(); if (abrt) return 0; + src = getbyte(); if (abrt) return 1; ARITH_MULTI(b, 8); return 0; @@ -561,7 +561,7 @@ static int op81_w_a16(uint32_t fetchdat) uint16_t src, dst; fetch_ea_16(fetchdat); - src = getword(); if (abrt) return 0; + src = getword(); if (abrt) return 1; ARITH_MULTI(w, 16); return 0; @@ -571,7 +571,7 @@ static int op81_w_a32(uint32_t fetchdat) uint16_t src, dst; fetch_ea_32(fetchdat); - src = getword(); if (abrt) return 0; + src = getword(); if (abrt) return 1; ARITH_MULTI(w, 16); return 0; @@ -581,7 +581,7 @@ static int op81_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); - src = getlong(); if (abrt) return 0; + src = getlong(); if (abrt) return 1; ARITH_MULTI(l, 32); return 0; @@ -591,7 +591,7 @@ static int op81_l_a32(uint32_t fetchdat) uint32_t src, dst; fetch_ea_32(fetchdat); - src = getlong(); if (abrt) return 0; + src = getlong(); if (abrt) return 1; ARITH_MULTI(l, 32); return 0; @@ -602,7 +602,7 @@ static int op83_w_a16(uint32_t fetchdat) uint16_t src, dst; fetch_ea_16(fetchdat); - src = getbyte(); if (abrt) return 0; + src = getbyte(); if (abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); @@ -613,7 +613,7 @@ static int op83_w_a32(uint32_t fetchdat) uint16_t src, dst; fetch_ea_32(fetchdat); - src = getbyte(); if (abrt) return 0; + src = getbyte(); if (abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); @@ -625,7 +625,7 @@ static int op83_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); - src = getbyte(); if (abrt) return 0; + src = getbyte(); if (abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); @@ -636,7 +636,7 @@ static int op83_l_a32(uint32_t fetchdat) uint32_t src, dst; fetch_ea_32(fetchdat); - src = getbyte(); if (abrt) return 0; + src = getbyte(); if (abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); diff --git a/src/x86_ops_atomic.h b/src/x86_ops_atomic.h index 0f8c8ee..6627c4a 100644 --- a/src/x86_ops_atomic.h +++ b/src/x86_ops_atomic.h @@ -5,13 +5,13 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; if (AL == temp) seteab(getr8(reg)); else AL = temp; - if (abrt) return 0; + if (abrt) return 1; setsub8(temp2, temp); cycles -= (mod == 3) ? 6 : 10; return 0; @@ -23,13 +23,13 @@ static int opCMPXCHG_b_a32(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; if (AL == temp) seteab(getr8(reg)); else AL = temp; - if (abrt) return 0; + if (abrt) return 1; setsub8(temp2, temp); cycles -= (mod == 3) ? 6 : 10; return 0; @@ -42,13 +42,13 @@ static int opCMPXCHG_w_a16(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; if (AX == temp) seteaw(regs[reg].w); else AX = temp; - if (abrt) return 0; + if (abrt) return 1; setsub16(temp2, temp); cycles -= (mod == 3) ? 6 : 10; return 0; @@ -60,13 +60,13 @@ static int opCMPXCHG_w_a32(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; if (AX == temp) seteaw(regs[reg].w); else AX = temp; - if (abrt) return 0; + if (abrt) return 1; setsub16(temp2, temp); cycles -= (mod == 3) ? 6 : 10; return 0; @@ -79,13 +79,13 @@ static int opCMPXCHG_l_a16(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; if (EAX == temp) seteal(regs[reg].l); else EAX = temp; - if (abrt) return 0; + if (abrt) return 1; setsub32(temp2, temp); cycles -= (mod == 3) ? 6 : 10; return 0; @@ -97,13 +97,13 @@ static int opCMPXCHG_l_a32(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; if (EAX == temp) seteal(regs[reg].l); else EAX = temp; - if (abrt) return 0; + if (abrt) return 1; setsub32(temp2, temp); cycles -= (mod == 3) ? 6 : 10; return 0; @@ -116,11 +116,11 @@ static int opXADD_b_a16(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; - seteab(temp + getr8(reg)); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; + seteab(temp + getr8(reg)); if (abrt) return 1; setadd8(temp, getr8(reg)); setr8(reg, temp); return 0; @@ -132,11 +132,11 @@ static int opXADD_b_a32(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; - seteab(temp + getr8(reg)); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; + seteab(temp + getr8(reg)); if (abrt) return 1; setadd8(temp, getr8(reg)); setr8(reg, temp); return 0; @@ -149,11 +149,11 @@ static int opXADD_w_a16(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; - seteaw(temp + regs[reg].w); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(temp + regs[reg].w); if (abrt) return 1; setadd16(temp, regs[reg].w); regs[reg].w = temp; return 0; @@ -165,11 +165,11 @@ static int opXADD_w_a32(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; - seteaw(temp + regs[reg].w); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(temp + regs[reg].w); if (abrt) return 1; setadd16(temp, regs[reg].w); regs[reg].w = temp; return 0; @@ -182,11 +182,11 @@ static int opXADD_l_a16(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; - seteal(temp + regs[reg].l); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(temp + regs[reg].l); if (abrt) return 1; setadd32(temp, regs[reg].l); regs[reg].l = temp; return 0; @@ -198,11 +198,11 @@ static int opXADD_l_a32(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; - seteal(temp + regs[reg].l); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(temp + regs[reg].l); if (abrt) return 1; setadd32(temp, regs[reg].l); regs[reg].l = temp; return 0; diff --git a/src/x86_ops_bit.h b/src/x86_ops_bit.h index df0e2c7..8eee1bf 100644 --- a/src/x86_ops_bit.h +++ b/src/x86_ops_bit.h @@ -5,7 +5,7 @@ static int opBT_w_r_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); eaaddr += ((regs[reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; flags_rebuild(); if (temp & (1 << (regs[reg].w & 15))) flags |= C_FLAG; else flags &= ~C_FLAG; @@ -19,7 +19,7 @@ static int opBT_w_r_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); eaaddr += ((regs[reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; flags_rebuild(); if (temp & (1 << (regs[reg].w & 15))) flags |= C_FLAG; else flags &= ~C_FLAG; @@ -33,7 +33,7 @@ static int opBT_l_r_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); eaaddr += ((regs[reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; flags_rebuild(); if (temp & (1 << (regs[reg].l & 31))) flags |= C_FLAG; else flags &= ~C_FLAG; @@ -47,7 +47,7 @@ static int opBT_l_r_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); eaaddr += ((regs[reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; flags_rebuild(); if (temp & (1 << (regs[reg].l & 31))) flags |= C_FLAG; else flags &= ~C_FLAG; @@ -64,10 +64,10 @@ static int opBT_l_r_a32(uint32_t fetchdat) \ fetch_ea_16(fetchdat); \ eaaddr += ((regs[reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (abrt) return 0; \ + temp = geteaw(); if (abrt) return 1; \ tempc = (temp & (1 << (regs[reg].w & 15))) ? 1 : 0; \ temp operation (1 << (regs[reg].w & 15)); \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ else flags &= ~C_FLAG; \ @@ -82,10 +82,10 @@ static int opBT_l_r_a32(uint32_t fetchdat) \ fetch_ea_32(fetchdat); \ eaaddr += ((regs[reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (abrt) return 0; \ + temp = geteaw(); if (abrt) return 1; \ tempc = (temp & (1 << (regs[reg].w & 15))) ? 1 : 0; \ temp operation (1 << (regs[reg].w & 15)); \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ else flags &= ~C_FLAG; \ @@ -100,10 +100,10 @@ static int opBT_l_r_a32(uint32_t fetchdat) \ fetch_ea_16(fetchdat); \ eaaddr += ((regs[reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (abrt) return 0; \ + temp = geteal(); if (abrt) return 1; \ tempc = (temp & (1 << (regs[reg].l & 31))) ? 1 : 0; \ temp operation (1 << (regs[reg].l & 31)); \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ else flags &= ~C_FLAG; \ @@ -118,10 +118,10 @@ static int opBT_l_r_a32(uint32_t fetchdat) \ fetch_ea_32(fetchdat); \ eaaddr += ((regs[reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (abrt) return 0; \ + temp = geteal(); if (abrt) return 1; \ tempc = (temp & (1 << (regs[reg].l & 31))) ? 1 : 0; \ temp operation (1 << (regs[reg].l & 31)); \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ else flags &= ~C_FLAG; \ @@ -142,7 +142,7 @@ static int opBA_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); temp = geteaw(); - count = getbyte(); if (abrt) return 0; + count = getbyte(); if (abrt) return 1; tempc = temp & (1 << count); flags_rebuild(); switch (rmdat & 0x38) @@ -168,7 +168,7 @@ static int opBA_w_a16(uint32_t fetchdat) x86illegal(); break; } - seteaw(temp); if (abrt) return 0; + seteaw(temp); if (abrt) return 1; if (tempc) flags |= C_FLAG; else flags &= ~C_FLAG; cycles -= 6; @@ -182,7 +182,7 @@ static int opBA_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); temp = geteaw(); - count = getbyte(); if (abrt) return 0; + count = getbyte(); if (abrt) return 1; tempc = temp & (1 << count); flags_rebuild(); switch (rmdat & 0x38) @@ -208,7 +208,7 @@ static int opBA_w_a32(uint32_t fetchdat) x86illegal(); break; } - seteaw(temp); if (abrt) return 0; + seteaw(temp); if (abrt) return 1; if (tempc) flags |= C_FLAG; else flags &= ~C_FLAG; cycles -= 6; @@ -223,7 +223,7 @@ static int opBA_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); temp = geteal(); - count = getbyte(); if (abrt) return 0; + count = getbyte(); if (abrt) return 1; tempc = temp & (1 << count); flags_rebuild(); switch (rmdat & 0x38) @@ -249,7 +249,7 @@ static int opBA_l_a16(uint32_t fetchdat) x86illegal(); break; } - seteal(temp); if (abrt) return 0; + seteal(temp); if (abrt) return 1; if (tempc) flags |= C_FLAG; else flags &= ~C_FLAG; cycles -= 6; @@ -263,7 +263,7 @@ static int opBA_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); temp = geteal(); - count = getbyte(); if (abrt) return 0; + count = getbyte(); if (abrt) return 1; tempc = temp & (1 << count); flags_rebuild(); switch (rmdat & 0x38) @@ -289,7 +289,7 @@ static int opBA_l_a32(uint32_t fetchdat) x86illegal(); break; } - seteal(temp); if (abrt) return 0; + seteal(temp); if (abrt) return 1; if (tempc) flags |= C_FLAG; else flags &= ~C_FLAG; cycles -= 6; diff --git a/src/x86_ops_bitscan.h b/src/x86_ops_bitscan.h index 4c4a3db..5c314e0 100644 --- a/src/x86_ops_bitscan.h +++ b/src/x86_ops_bitscan.h @@ -22,7 +22,7 @@ static int opBSF_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; BS_common(0, 16, 1, regs[reg].w, (is486) ? 1 : 3); @@ -34,7 +34,7 @@ static int opBSF_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; BS_common(0, 16, 1, regs[reg].w, (is486) ? 1 : 3); @@ -46,7 +46,7 @@ static int opBSF_l_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; BS_common(0, 32, 1, regs[reg].l, (is486) ? 1 : 3); @@ -58,7 +58,7 @@ static int opBSF_l_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; BS_common(0, 32, 1, regs[reg].l, (is486) ? 1 : 3); @@ -71,7 +71,7 @@ static int opBSR_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; BS_common(15, -1, -1, regs[reg].w, 3); @@ -83,7 +83,7 @@ static int opBSR_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; BS_common(15, -1, -1, regs[reg].w, 3); @@ -95,7 +95,7 @@ static int opBSR_l_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; BS_common(31, -1, -1, regs[reg].l, 3); @@ -107,7 +107,7 @@ static int opBSR_l_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; BS_common(31, -1, -1, regs[reg].l, 3); diff --git a/src/x86_ops_call.h b/src/x86_ops_call.h index eb74305..3c697a8 100644 --- a/src/x86_ops_call.h +++ b/src/x86_ops_call.h @@ -8,19 +8,19 @@ if (msw & 1) loadcscall(new_seg); \ else loadcs(new_seg); \ optype = 0; \ - if (abrt) { cgate16 = cgate32 = 0; return 0; } \ + if (abrt) { cgate16 = cgate32 = 0; return 1; } \ oldss = ss; \ if (cgate32) \ { \ uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ - PUSH_L(old_pc); if (abrt) ESP = old_esp; \ + PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (abrt) { ESP = old_esp; return 1; } \ } \ else \ { \ uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ - PUSH_W(old_pc); if (abrt) ESP = old_esp; \ + PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (abrt) { ESP = old_esp; return 1; } \ } #define CALL_FAR_l(new_seg, new_pc) \ @@ -33,56 +33,32 @@ if (msw & 1) loadcscall(new_seg); \ else loadcs(new_seg); \ optype = 0; \ - if (abrt) { cgate16 = cgate32 = 0; return 0; } \ + if (abrt) { cgate16 = cgate32 = 0; return 1; } \ oldss = ss; \ if (cgate16) \ { \ uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ - PUSH_W(old_pc); if (abrt) ESP = old_esp; \ + PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (abrt) { ESP = old_esp; return 1; } \ } \ else \ { \ uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ - PUSH_L(old_pc); if (abrt) ESP = old_esp; \ + PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (abrt) { ESP = old_esp; return 1; } \ } - -#define CALL_FAR_nr(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = pc; \ - oxpc = pc; \ - pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else loadcs(new_seg); \ - optype = 0; \ - if (abrt) { cgate16 = cgate32 = 0; break; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; break; } \ - PUSH_L(old_pc); if (abrt) ESP = old_esp; \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; break; } \ - PUSH_W(old_pc); if (abrt) ESP = old_esp; \ - } \ - + static int opCALL_far_w(uint32_t fetchdat) { uint32_t old_cs, old_pc; uint16_t new_cs, new_pc; new_pc = getwordf(); - new_cs = getword(); if (abrt) return 0; - + new_cs = getword(); if (abrt) return 1; + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); cycles -= is486 ? 18 : 17; return 0; @@ -93,9 +69,10 @@ static int opCALL_far_l(uint32_t fetchdat) uint32_t new_cs, new_pc; new_pc = getlong(); - new_cs = getword(); if (abrt) return 0; + new_cs = getword(); if (abrt) return 1; CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); cycles -= is486 ? 18 : 17; return 0; @@ -114,48 +91,52 @@ static int opFF_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC w*/ - temp = geteaw(); if (abrt) return 0; - seteaw(temp + 1); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(temp + 1); if (abrt) return 1; setadd16nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x08: /*DEC w*/ - temp = geteaw(); if (abrt) return 0; - seteaw(temp - 1); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(temp - 1); if (abrt) return 1; setsub16nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x10: /*CALL*/ - new_pc = geteaw(); if (abrt) return 0; + new_pc = geteaw(); if (abrt) return 1; PUSH_W(pc); pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x18: /*CALL far*/ new_pc = readmemw(easeg, eaaddr); - new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 0; + new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 1; CALL_FAR_w(new_cs, new_pc); - + CPU_BLOCK_END(); + cycles -= is486 ? 17 : 22; break; case 0x20: /*JMP*/ - new_pc = geteaw(); if (abrt) return 0; + new_pc = geteaw(); if (abrt) return 1; pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x28: /*JMP far*/ oxpc = pc; new_pc = readmemw(easeg, eaaddr); - new_cs = readmemw(easeg, eaaddr + 2); if (abrt) return 0; + new_cs = readmemw(easeg, eaaddr + 2); if (abrt) return 1; pc = new_pc; - loadcsjmp(new_cs, oxpc); if (abrt) return 0; + loadcsjmp(new_cs, oxpc); if (abrt) return 1; + CPU_BLOCK_END(); cycles -= is486 ? 13 : 12; break; case 0x30: /*PUSH w*/ - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; PUSH_W(temp); cycles -= ((mod == 3) ? 2 : 5); break; @@ -164,7 +145,7 @@ static int opFF_w_a16(uint32_t fetchdat) // fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } - return 0; + return abrt; } static int opFF_w_a32(uint32_t fetchdat) { @@ -178,48 +159,52 @@ static int opFF_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC w*/ - temp = geteaw(); if (abrt) return 0; - seteaw(temp + 1); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(temp + 1); if (abrt) return 1; setadd16nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x08: /*DEC w*/ - temp = geteaw(); if (abrt) return 0; - seteaw(temp - 1); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(temp - 1); if (abrt) return 1; setsub16nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x10: /*CALL*/ - new_pc = geteaw(); if (abrt) return 0; + new_pc = geteaw(); if (abrt) return 1; PUSH_W(pc); pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x18: /*CALL far*/ new_pc = readmemw(easeg, eaaddr); - new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 0; + new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 1; CALL_FAR_w(new_cs, new_pc); - + CPU_BLOCK_END(); + cycles -= is486 ? 17 : 22; break; case 0x20: /*JMP*/ - new_pc = geteaw(); if (abrt) return 0; + new_pc = geteaw(); if (abrt) return 1; pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x28: /*JMP far*/ oxpc = pc; new_pc = readmemw(easeg, eaaddr); - new_cs = readmemw(easeg, eaaddr + 2); if (abrt) return 0; + new_cs = readmemw(easeg, eaaddr + 2); if (abrt) return 1; pc = new_pc; - loadcsjmp(new_cs, oxpc); if (abrt) return 0; + loadcsjmp(new_cs, oxpc); if (abrt) return 1; + CPU_BLOCK_END(); cycles -= is486 ? 13 : 12; break; case 0x30: /*PUSH w*/ - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; PUSH_W(temp); cycles -= ((mod == 3) ? 2 : 5); break; @@ -228,7 +213,7 @@ static int opFF_w_a32(uint32_t fetchdat) // fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } - return 0; + return abrt; } static int opFF_l_a16(uint32_t fetchdat) @@ -243,48 +228,52 @@ static int opFF_l_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC l*/ - temp = geteal(); if (abrt) return 0; - seteal(temp + 1); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(temp + 1); if (abrt) return 1; setadd32nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x08: /*DEC l*/ - temp = geteal(); if (abrt) return 0; - seteal(temp - 1); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(temp - 1); if (abrt) return 1; setsub32nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x10: /*CALL*/ - new_pc = geteal(); if (abrt) return 0; + new_pc = geteal(); if (abrt) return 1; PUSH_L(pc); pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x18: /*CALL far*/ new_pc = readmeml(easeg, eaaddr); - new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 0; + new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 1; CALL_FAR_l(new_cs, new_pc); - + CPU_BLOCK_END(); + cycles -= is486 ? 17 : 22; break; case 0x20: /*JMP*/ - new_pc = geteal(); if (abrt) return 0; + new_pc = geteal(); if (abrt) return 1; pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x28: /*JMP far*/ oxpc = pc; new_pc = readmeml(easeg, eaaddr); - new_cs = readmemw(easeg, eaaddr + 4); if (abrt) return 0; + new_cs = readmemw(easeg, eaaddr + 4); if (abrt) return 1; pc = new_pc; - loadcsjmp(new_cs, oxpc); if (abrt) return 0; + loadcsjmp(new_cs, oxpc); if (abrt) return 1; + CPU_BLOCK_END(); cycles -= is486 ? 13 : 12; break; case 0x30: /*PUSH l*/ - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; PUSH_L(temp); cycles -= ((mod == 3) ? 2 : 5); break; @@ -293,7 +282,7 @@ static int opFF_l_a16(uint32_t fetchdat) // fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } - return 0; + return abrt; } static int opFF_l_a32(uint32_t fetchdat) { @@ -307,48 +296,52 @@ static int opFF_l_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC l*/ - temp = geteal(); if (abrt) return 0; - seteal(temp + 1); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(temp + 1); if (abrt) return 1; setadd32nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x08: /*DEC l*/ - temp = geteal(); if (abrt) return 0; - seteal(temp - 1); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(temp - 1); if (abrt) return 1; setsub32nc(temp, 1); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x10: /*CALL*/ - new_pc = geteal(); if (abrt) return 0; - PUSH_L(pc); if (abrt) return 0; + new_pc = geteal(); if (abrt) return 1; + PUSH_L(pc); if (abrt) return 1; pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x18: /*CALL far*/ new_pc = readmeml(easeg, eaaddr); - new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 0; + new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 1; CALL_FAR_l(new_cs, new_pc); - + CPU_BLOCK_END(); + cycles -= is486 ? 17 : 22; break; case 0x20: /*JMP*/ - new_pc = geteal(); if (abrt) return 0; + new_pc = geteal(); if (abrt) return 1; pc = new_pc; + CPU_BLOCK_END(); if (is486) cycles -= 5; else cycles -= ((mod == 3) ? 7 : 10); break; case 0x28: /*JMP far*/ oxpc = pc; new_pc = readmeml(easeg, eaaddr); - new_cs = readmemw(easeg, eaaddr + 4); if (abrt) return 0; + new_cs = readmemw(easeg, eaaddr + 4); if (abrt) return 1; pc = new_pc; - loadcsjmp(new_cs, oxpc); if (abrt) return 0; + loadcsjmp(new_cs, oxpc); if (abrt) return 1; + CPU_BLOCK_END(); cycles -= is486 ? 13 : 12; break; case 0x30: /*PUSH l*/ - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; PUSH_L(temp); cycles -= ((mod == 3) ? 2 : 5); break; @@ -357,5 +350,5 @@ static int opFF_l_a32(uint32_t fetchdat) // fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } - return 0; + return abrt; } diff --git a/src/x86_ops_flag.h b/src/x86_ops_flag.h index 0c8e56f..bc50538 100644 --- a/src/x86_ops_flag.h +++ b/src/x86_ops_flag.h @@ -25,10 +25,13 @@ static int opCLI(uint32_t fetchdat) if (!IOPLp) { x86gpf(NULL,0); + return 1; } else flags &= ~I_FLAG; - + + CPU_BLOCK_END(); + cycles -= 3; return 0; } @@ -51,10 +54,13 @@ static int opSTI(uint32_t fetchdat) if (!IOPLp) { x86gpf(NULL,0); + return 1; } else flags |= I_FLAG; - + + CPU_BLOCK_END(); + cycles -= 2; return 0; } @@ -79,12 +85,12 @@ static int opPUSHF(uint32_t fetchdat) if ((eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL,0); - return 0; + return 1; } flags_rebuild(); PUSH_W(flags); cycles -= 4; - return 0; + return abrt; } static int opPUSHFD(uint32_t fetchdat) { @@ -92,14 +98,14 @@ static int opPUSHFD(uint32_t fetchdat) if ((eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); - return 0; + return 1; } if (CPUID) tempw = eflags & 0x24; else tempw = eflags & 4; flags_rebuild(); PUSH_L(flags | (tempw << 16)); cycles -= 4; - return 0; + return abrt; } static int opPOPF_286(uint32_t fetchdat) @@ -109,10 +115,10 @@ static int opPOPF_286(uint32_t fetchdat) if ((eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); - return 0; + return 1; } - tempw = POP_W(); if (abrt) return 0; + tempw = POP_W(); if (abrt) return 1; if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2; else if (!(CPL)) flags = (tempw & 0x7fd5) | 2; @@ -130,10 +136,10 @@ static int opPOPF(uint32_t fetchdat) if ((eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); - return 0; + return 1; } - tempw = POP_W(); if (abrt) return 0; + tempw = POP_W(); if (abrt) return 1; if (!(CPL) || !(msw & 1)) flags = (tempw & 0xffd5) | 2; else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0xcfd5) | 2; @@ -150,10 +156,10 @@ static int opPOPFD(uint32_t fetchdat) if ((eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); - return 0; + return 1; } - templ = POP_L(); if (abrt) return 0; + templ = POP_L(); if (abrt) return 1; if (!(CPL) || !(msw & 1)) flags = (templ & 0xffd5) | 2; else if (IOPLp) flags = (flags & 0x3000) | (templ & 0xcfd5) | 2; diff --git a/src/x86_ops_fpu.h b/src/x86_ops_fpu.h index 2252695..90e7f48 100644 --- a/src/x86_ops_fpu.h +++ b/src/x86_ops_fpu.h @@ -2,9 +2,10 @@ static int opESCAPE_ ## num ##_a16(uint32_t fetchdat) \ { \ flags_rebuild(); \ - if (cr0 & 0xc) \ + if (cr0 & 0xc) \ { \ x86_int(7); \ + return 1; \ } \ else \ { \ @@ -16,17 +17,18 @@ x87_pc_seg = CS; \ x87_op_off = eaaddr; \ x87_op_seg = ea_rseg; \ - x87_ ## num(); \ + x87_ ## num(fetchdat); \ } \ } \ - return 0; \ + return abrt; \ } \ static int opESCAPE_ ## num ## _a32(uint32_t fetchdat) \ { \ flags_rebuild(); \ - if (cr0 & 0xc) \ + if (cr0 & 0xc) \ { \ x86_int(7); \ + return 1; \ } \ else \ { \ @@ -38,10 +40,10 @@ x87_pc_seg = CS; \ x87_op_off = eaaddr; \ x87_op_seg = ea_rseg; \ - x87_ ## num(); \ + x87_ ## num(fetchdat); \ } \ } \ - return 0; \ + return abrt; \ } opESCAPE(d8); @@ -58,7 +60,7 @@ static int opWAIT(uint32_t fetchdat) if ((cr0 & 0xa) == 0xa) { x86_int(7); - return 0; + return 1; } cycles -= 4; return 0; diff --git a/src/x86_ops_inc_dec.h b/src/x86_ops_inc_dec.h index 1e8accf..b4dfd02 100644 --- a/src/x86_ops_inc_dec.h +++ b/src/x86_ops_inc_dec.h @@ -49,16 +49,16 @@ static int opINCDEC_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); - temp=geteab(); if (abrt) return 0; + temp=geteab(); if (abrt) return 1; if (rmdat&0x38) { - seteab(temp - 1); if (abrt) return 0; + seteab(temp - 1); if (abrt) return 1; setsub8nc(temp, 1); } else { - seteab(temp + 1); if (abrt) return 0; + seteab(temp + 1); if (abrt) return 1; setadd8nc(temp, 1); } cycles -= (mod == 3) ? timing_rr : timing_mm; @@ -69,16 +69,16 @@ static int opINCDEC_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); - temp=geteab(); if (abrt) return 0; + temp=geteab(); if (abrt) return 1; if (rmdat&0x38) { - seteab(temp - 1); if (abrt) return 0; + seteab(temp - 1); if (abrt) return 1; setsub8nc(temp, 1); } else { - seteab(temp + 1); if (abrt) return 0; + seteab(temp + 1); if (abrt) return 1; setadd8nc(temp, 1); } cycles -= (mod == 3) ? timing_rr : timing_mm; diff --git a/src/x86_ops_int.h b/src/x86_ops_int.h index 0ff27c7..2ec151d 100644 --- a/src/x86_ops_int.h +++ b/src/x86_ops_int.h @@ -3,11 +3,11 @@ static int opINT3(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); - return 0; + return 1; } x86_int_sw(3); cycles -= (is486) ? 44 : 59; - return 0; + return 1; } static int opINT(uint32_t fetchdat) @@ -18,12 +18,44 @@ static int opINT(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); - return 0; + return 1; } temp = getbytef(); - if (temp == 0x10 && AH == 0xe) pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc); +// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc); +// if (CS == 0x0028 && pc == 0xC03813C0) +// output = 3; +/* if (pc == 0x8028009A) + output = 3; + if (pc == 0x80282B6F) + { + __times++; + if (__times == 2) + fatal("WRONG\n"); + } + if (pc == 0x802809CE) + fatal("RIGHT\n");*/ +// if (CS == 0x0028 && pc == 0x80037FE9) +// output = 3; +//if (CS == 0x9087 && pc == 0x3763) +// fatal("Here\n"); +//if (CS==0x9087 && pc == 0x0850) +// output = 1; + +/* if (output && pc == 0x80033008) + { + __times++; + if (__times == 2) + fatal("WRONG\n"); + }*/ +/* if (output && pc == 0x80D8) + { + __times++; + if (__times == 2) + fatal("RIGHT\n"); + }*/ + x86_int_sw(temp); - return 0; + return 1; } static int opINTO(uint32_t fetchdat) @@ -31,12 +63,13 @@ static int opINTO(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); - return 0; + return 1; } if (VF_SET()) { oldpc = pc; x86_int_sw(4); + return 1; } cycles -= 3; return 0; diff --git a/src/x86_ops_io.h b/src/x86_ops_io.h index f7b1569..bf5b782 100644 --- a/src/x86_ops_io.h +++ b/src/x86_ops_io.h @@ -1,4 +1,4 @@ -int opIN_AL_imm(uint32_t fetchdat) +static int opIN_AL_imm(uint32_t fetchdat) { uint16_t port = (uint16_t)getbytef(); check_io_perm(port); @@ -6,7 +6,7 @@ int opIN_AL_imm(uint32_t fetchdat) cycles -= 12; return 0; } -int opIN_AX_imm(uint32_t fetchdat) +static int opIN_AX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t)getbytef(); check_io_perm(port); @@ -15,7 +15,7 @@ int opIN_AX_imm(uint32_t fetchdat) cycles -= 12; return 0; } -int opIN_EAX_imm(uint32_t fetchdat) +static int opIN_EAX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t)getbytef(); check_io_perm(port); @@ -27,7 +27,7 @@ int opIN_EAX_imm(uint32_t fetchdat) return 0; } -int opOUT_AL_imm(uint32_t fetchdat) +static int opOUT_AL_imm(uint32_t fetchdat) { uint16_t port = (uint16_t)getbytef(); check_io_perm(port); @@ -35,7 +35,7 @@ int opOUT_AL_imm(uint32_t fetchdat) cycles -= 10; return 0; } -int opOUT_AX_imm(uint32_t fetchdat) +static int opOUT_AX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t)getbytef(); check_io_perm(port); @@ -44,7 +44,7 @@ int opOUT_AX_imm(uint32_t fetchdat) cycles -= 10; return 0; } -int opOUT_EAX_imm(uint32_t fetchdat) +static int opOUT_EAX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t)getbytef(); check_io_perm(port); @@ -56,14 +56,14 @@ int opOUT_EAX_imm(uint32_t fetchdat) return 0; } -int opIN_AL_DX(uint32_t fetchdat) +static int opIN_AL_DX(uint32_t fetchdat) { check_io_perm(DX); AL = inb(DX); cycles -= 12; return 0; } -int opIN_AX_DX(uint32_t fetchdat) +static int opIN_AX_DX(uint32_t fetchdat) { check_io_perm(DX); check_io_perm(DX + 1); @@ -71,7 +71,7 @@ int opIN_AX_DX(uint32_t fetchdat) cycles -= 12; return 0; } -int opIN_EAX_DX(uint32_t fetchdat) +static int opIN_EAX_DX(uint32_t fetchdat) { check_io_perm(DX); check_io_perm(DX + 1); @@ -82,14 +82,14 @@ int opIN_EAX_DX(uint32_t fetchdat) return 0; } -int opOUT_AL_DX(uint32_t fetchdat) +static int opOUT_AL_DX(uint32_t fetchdat) { check_io_perm(DX); outb(DX, AL); cycles -= 11; return 0; } -int opOUT_AX_DX(uint32_t fetchdat) +static int opOUT_AX_DX(uint32_t fetchdat) { //pclog("OUT_AX_DX %04X %04X\n", DX, AX); check_io_perm(DX); @@ -98,7 +98,7 @@ int opOUT_AX_DX(uint32_t fetchdat) cycles -= 11; return 0; } -int opOUT_EAX_DX(uint32_t fetchdat) +static int opOUT_EAX_DX(uint32_t fetchdat) { check_io_perm(DX); check_io_perm(DX + 1); diff --git a/src/x86_ops_jump.h b/src/x86_ops_jump.h index 6c61cd7..f5b6870 100644 --- a/src/x86_ops_jump.h +++ b/src/x86_ops_jump.h @@ -19,36 +19,42 @@ static int opJ ## condition(uint32_t fetchdat) \ { \ int8_t offset = (int8_t)getbytef(); \ + cycles -= timing_bnt; \ if (cond_ ## condition) \ { \ pc += offset; \ cycles -= timing_bt; \ + CPU_BLOCK_END(); \ + return 1; \ } \ - cycles -= timing_bnt; \ return 0; \ } \ \ static int opJ ## condition ## _w(uint32_t fetchdat) \ { \ int16_t offset = (int16_t)getwordf(); \ + cycles -= timing_bnt; \ if (cond_ ## condition) \ { \ pc += offset; \ cycles -= timing_bt; \ + CPU_BLOCK_END(); \ + return 1; \ } \ - cycles -= timing_bnt; \ return 0; \ } \ \ static int opJ ## condition ## _l(uint32_t fetchdat) \ { \ - uint32_t offset = getlong(); \ + uint32_t offset = getlong(); if (abrt) return 1; \ + cycles -= timing_bnt; \ if (cond_ ## condition) \ { \ pc += offset; \ cycles -= timing_bt; \ + CPU_BLOCK_END(); \ + return 1; \ } \ - cycles -= timing_bnt; \ return 0; \ } \ @@ -75,18 +81,26 @@ static int opLOOPNE_w(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); CX--; - if (CX && !ZF_SET()) - pc += offset; cycles -= (is486) ? 7 : 11; + if (CX && !ZF_SET()) + { + pc += offset; + CPU_BLOCK_END(); + return 1; + } return 0; } static int opLOOPNE_l(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); ECX--; - if (ECX && !ZF_SET()) - pc += offset; cycles -= (is486) ? 7 : 11; + if (ECX && !ZF_SET()) + { + pc += offset; + CPU_BLOCK_END(); + return 1; + } return 0; } @@ -94,18 +108,26 @@ static int opLOOPE_w(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); CX--; - if (CX && ZF_SET()) - pc += offset; cycles -= (is486) ? 7 : 11; + if (CX && ZF_SET()) + { + pc += offset; + CPU_BLOCK_END(); + return 1; + } return 0; } static int opLOOPE_l(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); ECX--; - if (ECX && ZF_SET()) - pc += offset; cycles -= (is486) ? 7 : 11; + if (ECX && ZF_SET()) + { + pc += offset; + CPU_BLOCK_END(); + return 1; + } return 0; } @@ -113,41 +135,53 @@ static int opLOOP_w(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); CX--; - if (CX) - pc += offset; cycles -= (is486) ? 7 : 11; + if (CX) + { + pc += offset; + CPU_BLOCK_END(); + return 1; + } return 0; } static int opLOOP_l(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); ECX--; - if (ECX) - pc += offset; cycles -= (is486) ? 7 : 11; + if (ECX) + { + pc += offset; + CPU_BLOCK_END(); + return 1; + } return 0; } static int opJCXZ(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); + cycles -= 5; if (!CX) { pc += offset; cycles -= 4; + CPU_BLOCK_END(); + return 1; } - cycles -= 5; return 0; } static int opJECXZ(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); + cycles -= 5; if (!ECX) { pc += offset; cycles -= 4; + CPU_BLOCK_END(); + return 1; } - cycles -= 5; return 0; } @@ -156,6 +190,7 @@ static int opJMP_r8(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); pc += offset; + CPU_BLOCK_END(); cycles -= (is486) ? 3 : 7; return 0; } @@ -163,13 +198,15 @@ static int opJMP_r16(uint32_t fetchdat) { int16_t offset = (int16_t)getwordf(); pc += offset; + CPU_BLOCK_END(); cycles -= (is486) ? 3 : 7; return 0; } static int opJMP_r32(uint32_t fetchdat) { - int32_t offset = (int32_t)getlong(); if (abrt) return 0; + int32_t offset = (int32_t)getlong(); if (abrt) return 1; pc += offset; + CPU_BLOCK_END(); cycles -= (is486) ? 3 : 7; return 0; } @@ -177,84 +214,92 @@ static int opJMP_r32(uint32_t fetchdat) static int opJMP_far_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); - uint16_t seg = getword(); if (abrt) return 0; + uint16_t seg = getword(); if (abrt) return 1; uint32_t oxpc = pc; pc = addr; loadcsjmp(seg, oxpc); + CPU_BLOCK_END(); cycles -= (is486) ? 17 : 12; return 0; } static int opJMP_far_a32(uint32_t fetchdat) { uint32_t addr = getlong(); - uint16_t seg = getword(); if (abrt) return 0; + uint16_t seg = getword(); if (abrt) return 1; uint32_t oxpc = pc; pc = addr; loadcsjmp(seg, oxpc); + CPU_BLOCK_END(); cycles -= (is486) ? 17 : 12; return 0; } -int opCALL_r16(uint32_t fetchdat) +static int opCALL_r16(uint32_t fetchdat) { int16_t addr = (int16_t)getwordf(); PUSH_W(pc); pc += addr; + CPU_BLOCK_END(); cycles -= (is486) ? 3 : 7; return 0; } -int opCALL_r32(uint32_t fetchdat) +static int opCALL_r32(uint32_t fetchdat) { - int32_t addr = getlong(); if (abrt) return 0; + int32_t addr = getlong(); if (abrt) return 1; PUSH_L(pc); pc += addr; + CPU_BLOCK_END(); cycles -= (is486) ? 3 : 7; return 0; } -int opRET_w(uint32_t fetchdat) +static int opRET_w(uint32_t fetchdat) { uint16_t ret; - ret = POP_W(); if (abrt) return 0; + ret = POP_W(); if (abrt) return 1; pc = ret; + CPU_BLOCK_END(); cycles -= (is486) ? 5 : 10; return 0; } -int opRET_l(uint32_t fetchdat) +static int opRET_l(uint32_t fetchdat) { uint32_t ret; - ret = POP_L(); if (abrt) return 0; + ret = POP_L(); if (abrt) return 1; pc = ret; + CPU_BLOCK_END(); cycles -= (is486) ? 5 : 10; return 0; } -int opRET_w_imm(uint32_t fetchdat) +static int opRET_w_imm(uint32_t fetchdat) { uint16_t offset = getwordf(); uint16_t ret; - ret = POP_W(); if (abrt) return 0; + ret = POP_W(); if (abrt) return 1; if (stack32) ESP += offset; else SP += offset; pc = ret; + CPU_BLOCK_END(); cycles -= (is486) ? 5 : 10; return 0; } -int opRET_l_imm(uint32_t fetchdat) +static int opRET_l_imm(uint32_t fetchdat) { uint16_t offset = getwordf(); uint32_t ret; - ret = POP_L(); if (abrt) return 0; + ret = POP_L(); if (abrt) return 1; if (stack32) ESP += offset; else SP += offset; pc = ret; + CPU_BLOCK_END(); cycles -= (is486) ? 5 : 10; return 0; diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index 44ac83a..ba8eea9 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -46,22 +46,22 @@ static int opF6_a16(uint32_t fetchdat) int8_t temps; fetch_ea_16(fetchdat); - dst = geteab(); if (abrt) return 0; + dst = geteab(); if (abrt) return 1; switch (rmdat & 0x38) { case 0x00: /*TEST b,#8*/ - src = readmemb(cs, pc); pc++; if (abrt) return 0; + src = readmemb(cs, pc); pc++; if (abrt) return 1; setznp8(src & dst); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); break; case 0x10: /*NOT b*/ - seteab(~dst); + seteab(~dst); if (abrt) return 1; cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x18: /*NEG b*/ + seteab(0 - dst); if (abrt) return 1; setsub8(0, dst); - seteab(0 - dst); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x20: /*MUL AL,b*/ @@ -134,22 +134,22 @@ static int opF6_a32(uint32_t fetchdat) int8_t temps; fetch_ea_32(fetchdat); - dst = geteab(); if (abrt) return 0; + dst = geteab(); if (abrt) return 1; switch (rmdat & 0x38) { case 0x00: /*TEST b,#8*/ - src = readmemb(cs, pc); pc++; if (abrt) return 0; + src = readmemb(cs, pc); pc++; if (abrt) return 1; setznp8(src & dst); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); break; case 0x10: /*NOT b*/ - seteab(~dst); + seteab(~dst); if (abrt) return 1; cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x18: /*NEG b*/ + seteab(0 - dst); if (abrt) return 1; setsub8(0, dst); - seteab(0 - dst); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x20: /*MUL AL,b*/ @@ -225,22 +225,22 @@ static int opF7_w_a16(uint32_t fetchdat) uint16_t src, dst; fetch_ea_16(fetchdat); - dst = geteaw(); if (abrt) return 0; + dst = geteaw(); if (abrt) return 1; switch (rmdat & 0x38) { case 0x00: /*TEST w*/ - src = getword(); if (abrt) return 0; + src = getword(); if (abrt) return 1; setznp16(src & dst); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); break; case 0x10: /*NOT w*/ - seteaw(~dst); + seteaw(~dst); if (abrt) return 1; cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x18: /*NEG w*/ + seteaw(0 - dst); if (abrt) return 1; setsub16(0, dst); - seteaw(0 - dst); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x20: /*MUL AX,w*/ @@ -309,22 +309,22 @@ static int opF7_w_a32(uint32_t fetchdat) uint16_t src, dst; fetch_ea_32(fetchdat); - dst = geteaw(); if (abrt) return 0; + dst = geteaw(); if (abrt) return 1; switch (rmdat & 0x38) { case 0x00: /*TEST w*/ - src = getword(); if (abrt) return 0; + src = getword(); if (abrt) return 1; setznp16(src & dst); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); break; case 0x10: /*NOT w*/ - seteaw(~dst); + seteaw(~dst); if (abrt) return 1; cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x18: /*NEG w*/ + seteaw(0 - dst); if (abrt) return 1; setsub16(0, dst); - seteaw(0 - dst); cycles -= (mod == 3) ? timing_rr : timing_mm; break; case 0x20: /*MUL AX,w*/ @@ -392,23 +392,23 @@ static int opF7_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); - dst = geteal(); if (abrt) return 0; + dst = geteal(); if (abrt) return 1; switch (rmdat & 0x38) { case 0x00: /*TEST l*/ - src = getlong(); if (abrt) return 0; + src = getlong(); if (abrt) return 1; setznp32(src & dst); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); break; case 0x10: /*NOT l*/ - seteal(~dst); + seteal(~dst); if (abrt) return 1; cycles -= (mod == 3) ? timing_rr : timing_mml; break; case 0x18: /*NEG l*/ + seteal(0 - dst); if (abrt) return 1; setsub32(0, dst); - seteal(0 - dst); cycles -= (mod == 3) ? timing_rr : timing_mml; break; case 0x20: /*MUL EAX,l*/ @@ -430,12 +430,14 @@ static int opF7_l_a16(uint32_t fetchdat) cycles -= 38; break; case 0x30: /*DIV EAX,l*/ - divl(dst); + if (divl(dst)) + return 1; if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ cycles -= (is486) ? 40 : 38; break; case 0x38: /*IDIV EAX,l*/ - idivl((int32_t)dst); + if (idivl((int32_t)dst)) + return 1; if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ cycles -= 43; break; @@ -452,23 +454,23 @@ static int opF7_l_a32(uint32_t fetchdat) uint32_t src, dst; fetch_ea_32(fetchdat); - dst = geteal(); if (abrt) return 0; + dst = geteal(); if (abrt) return 1; switch (rmdat & 0x38) { case 0x00: /*TEST l*/ - src = getlong(); if (abrt) return 0; + src = getlong(); if (abrt) return 1; setznp32(src & dst); if (is486) cycles -= ((mod == 3) ? 1 : 2); else cycles -= ((mod == 3) ? 2 : 5); break; case 0x10: /*NOT l*/ - seteal(~dst); + seteal(~dst); if (abrt) return 1; cycles -= (mod == 3) ? timing_rr : timing_mml; break; case 0x18: /*NEG l*/ + seteal(0 - dst); if (abrt) return 1; setsub32(0, dst); - seteal(0 - dst); cycles -= (mod == 3) ? timing_rr : timing_mml; break; case 0x20: /*MUL EAX,l*/ @@ -490,12 +492,14 @@ static int opF7_l_a32(uint32_t fetchdat) cycles -= 38; break; case 0x30: /*DIV EAX,l*/ - divl(dst); + if (divl(dst)) + return 1; if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ cycles -= (is486) ? 40 : 38; break; case 0x38: /*IDIV EAX,l*/ - idivl((int32_t)dst); + if (idivl((int32_t)dst)) + return 1; if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ cycles -= 43; break; @@ -513,7 +517,7 @@ static int opHLT(uint32_t fetchdat) if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) { x86gpf(NULL,0); - return 0; + return 1; } if (!((flags&I_FLAG) && pic_intpending)) { @@ -522,6 +526,9 @@ static int opHLT(uint32_t fetchdat) } else cycles -= 5; + + CPU_BLOCK_END(); + return 0; } @@ -541,11 +548,12 @@ static int opBOUND_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(mod == 3); low = geteaw(); - high = readmemw(easeg, eaaddr + 2); if (abrt) return 0; + high = readmemw(easeg, eaaddr + 2); if (abrt) return 1; if (((int16_t)regs[reg].w < low) || ((int16_t)regs[reg].w > high)) { x86_int(5); + return 1; } cycles -= is486 ? 7 : 10; @@ -558,11 +566,12 @@ static int opBOUND_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(mod == 3); low = geteaw(); - high = readmemw(easeg, eaaddr + 2); if (abrt) return 0; + high = readmemw(easeg, eaaddr + 2); if (abrt) return 1; if (((int16_t)regs[reg].w < low) || ((int16_t)regs[reg].w > high)) { x86_int(5); + return 1; } cycles -= is486 ? 7 : 10; @@ -576,11 +585,12 @@ static int opBOUND_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(mod == 3); low = geteal(); - high = readmeml(easeg, eaaddr + 4); if (abrt) return 0; + high = readmeml(easeg, eaaddr + 4); if (abrt) return 1; if (((int32_t)regs[reg].l < low) || ((int32_t)regs[reg].l > high)) { x86_int(5); + return 1; } cycles -= is486 ? 7 : 10; @@ -593,11 +603,12 @@ static int opBOUND_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(mod == 3); low = geteal(); - high = readmeml(easeg, eaaddr + 4); if (abrt) return 0; + high = readmeml(easeg, eaaddr + 4); if (abrt) return 1; if (((int32_t)regs[reg].l < low) || ((int32_t)regs[reg].l > high)) { x86_int(5); + return 1; } cycles -= is486 ? 7 : 10; @@ -611,7 +622,7 @@ static int opCLTS(uint32_t fetchdat) { pclog("Can't CLTS\n"); x86gpf(NULL,0); - return 0; + return 1; } cr0 &= ~8; cycles -= 5; @@ -623,9 +634,10 @@ static int opINVD(uint32_t fetchdat) if (!is486) { x86illegal(); - return 0; + return 1; } cycles -= 1000; + CPU_BLOCK_END(); return 0; } static int opWBINVD(uint32_t fetchdat) @@ -633,9 +645,10 @@ static int opWBINVD(uint32_t fetchdat) if (!is486) { x86illegal(); - return 0; + return 1; } cycles -= 10000; + CPU_BLOCK_END(); return 0; } @@ -676,7 +689,7 @@ static int opCPUID(uint32_t fetchdat) } pc = oldpc; x86illegal(); - return 0; + return 1; } static int opRDMSR(uint32_t fetchdat) @@ -689,7 +702,7 @@ static int opRDMSR(uint32_t fetchdat) } pc = oldpc; x86illegal(); - return 0; + return 1; } static int opWRMSR(uint32_t fetchdat) @@ -702,6 +715,6 @@ static int opWRMSR(uint32_t fetchdat) } pc = oldpc; x86illegal(); - return 0; + return 1; } diff --git a/src/x86_ops_mmx.h b/src/x86_ops_mmx.h index 5e31d08..4a31c3f 100644 --- a/src/x86_ops_mmx.h +++ b/src/x86_ops_mmx.h @@ -12,7 +12,7 @@ else \ { \ src.l[0] = readmeml(easeg, eaaddr); \ - src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; \ + src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 1; \ cycles -= 2; \ } @@ -21,27 +21,27 @@ { \ pc = oldpc; \ x86illegal(); \ - return 0; \ + return 1; \ } \ if (cr0 & 0xc) \ { \ x86_int(7); \ - return 0; \ + return 1; \ } \ x87_set_mmx() -int opEMMS(uint32_t fetchdat) +static int opEMMS(uint32_t fetchdat) { if (!cpu_hasMMX) { pc = oldpc; x86illegal(); - return 0; + return 1; } if (cr0 & 4) { x86_int(7); - return 0; + return 1; } x87_emms(); cycles -= 100; /*Guess*/ diff --git a/src/x86_ops_mmx_arith.h b/src/x86_ops_mmx_arith.h index 203ae48..d98c6bf 100644 --- a/src/x86_ops_mmx_arith.h +++ b/src/x86_ops_mmx_arith.h @@ -1,4 +1,4 @@ -int opPADDB_a16(uint32_t fetchdat) +static int opPADDB_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -17,7 +17,7 @@ int opPADDB_a16(uint32_t fetchdat) return 0; } -int opPADDB_a32(uint32_t fetchdat) +static int opPADDB_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -37,7 +37,7 @@ int opPADDB_a32(uint32_t fetchdat) return 0; } -int opPADDW_a16(uint32_t fetchdat) +static int opPADDW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -52,7 +52,7 @@ int opPADDW_a16(uint32_t fetchdat) return 0; } -int opPADDW_a32(uint32_t fetchdat) +static int opPADDW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -68,7 +68,7 @@ int opPADDW_a32(uint32_t fetchdat) return 0; } -int opPADDD_a16(uint32_t fetchdat) +static int opPADDD_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -81,7 +81,7 @@ int opPADDD_a16(uint32_t fetchdat) return 0; } -int opPADDD_a32(uint32_t fetchdat) +static int opPADDD_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -95,7 +95,7 @@ int opPADDD_a32(uint32_t fetchdat) return 0; } -int opPADDSB_a16(uint32_t fetchdat) +static int opPADDSB_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -114,7 +114,7 @@ int opPADDSB_a16(uint32_t fetchdat) return 0; } -int opPADDSB_a32(uint32_t fetchdat) +static int opPADDSB_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -134,7 +134,7 @@ int opPADDSB_a32(uint32_t fetchdat) return 0; } -int opPADDUSB_a16(uint32_t fetchdat) +static int opPADDUSB_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -153,7 +153,7 @@ int opPADDUSB_a16(uint32_t fetchdat) return 0; } -int opPADDUSB_a32(uint32_t fetchdat) +static int opPADDUSB_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -173,7 +173,7 @@ int opPADDUSB_a32(uint32_t fetchdat) return 0; } -int opPADDSW_a16(uint32_t fetchdat) +static int opPADDSW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -188,7 +188,7 @@ int opPADDSW_a16(uint32_t fetchdat) return 0; } -int opPADDSW_a32(uint32_t fetchdat) +static int opPADDSW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -204,7 +204,7 @@ int opPADDSW_a32(uint32_t fetchdat) return 0; } -int opPADDUSW_a16(uint32_t fetchdat) +static int opPADDUSW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -219,7 +219,7 @@ int opPADDUSW_a16(uint32_t fetchdat) return 0; } -int opPADDUSW_a32(uint32_t fetchdat) +static int opPADDUSW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -235,7 +235,7 @@ int opPADDUSW_a32(uint32_t fetchdat) return 0; } -int opPMADDWD_a16(uint32_t fetchdat) +static int opPMADDWD_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -255,7 +255,7 @@ int opPMADDWD_a16(uint32_t fetchdat) return 0; } -int opPMADDWD_a32(uint32_t fetchdat) +static int opPMADDWD_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -277,7 +277,7 @@ int opPMADDWD_a32(uint32_t fetchdat) } -int opPMULLW_a16(uint32_t fetchdat) +static int opPMULLW_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -304,7 +304,7 @@ int opPMULLW_a16(uint32_t fetchdat) } return 0; } -int opPMULLW_a32(uint32_t fetchdat) +static int opPMULLW_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -332,7 +332,7 @@ int opPMULLW_a32(uint32_t fetchdat) return 0; } -int opPMULHW_a16(uint32_t fetchdat) +static int opPMULHW_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -359,7 +359,7 @@ int opPMULHW_a16(uint32_t fetchdat) } return 0; } -int opPMULHW_a32(uint32_t fetchdat) +static int opPMULHW_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -387,7 +387,7 @@ int opPMULHW_a32(uint32_t fetchdat) return 0; } -int opPSUBB_a16(uint32_t fetchdat) +static int opPSUBB_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -406,7 +406,7 @@ int opPSUBB_a16(uint32_t fetchdat) return 0; } -int opPSUBB_a32(uint32_t fetchdat) +static int opPSUBB_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -426,7 +426,7 @@ int opPSUBB_a32(uint32_t fetchdat) return 0; } -int opPSUBW_a16(uint32_t fetchdat) +static int opPSUBW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -441,7 +441,7 @@ int opPSUBW_a16(uint32_t fetchdat) return 0; } -int opPSUBW_a32(uint32_t fetchdat) +static int opPSUBW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -457,7 +457,7 @@ int opPSUBW_a32(uint32_t fetchdat) return 0; } -int opPSUBD_a16(uint32_t fetchdat) +static int opPSUBD_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -470,7 +470,7 @@ int opPSUBD_a16(uint32_t fetchdat) return 0; } -int opPSUBD_a32(uint32_t fetchdat) +static int opPSUBD_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -484,7 +484,7 @@ int opPSUBD_a32(uint32_t fetchdat) return 0; } -int opPSUBSB_a16(uint32_t fetchdat) +static int opPSUBSB_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -503,7 +503,7 @@ int opPSUBSB_a16(uint32_t fetchdat) return 0; } -int opPSUBSB_a32(uint32_t fetchdat) +static int opPSUBSB_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -523,7 +523,7 @@ int opPSUBSB_a32(uint32_t fetchdat) return 0; } -int opPSUBUSB_a16(uint32_t fetchdat) +static int opPSUBUSB_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -542,7 +542,7 @@ int opPSUBUSB_a16(uint32_t fetchdat) return 0; } -int opPSUBUSB_a32(uint32_t fetchdat) +static int opPSUBUSB_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -562,7 +562,7 @@ int opPSUBUSB_a32(uint32_t fetchdat) return 0; } -int opPSUBSW_a16(uint32_t fetchdat) +static int opPSUBSW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -577,7 +577,7 @@ int opPSUBSW_a16(uint32_t fetchdat) return 0; } -int opPSUBSW_a32(uint32_t fetchdat) +static int opPSUBSW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -593,7 +593,7 @@ int opPSUBSW_a32(uint32_t fetchdat) return 0; } -int opPSUBUSW_a16(uint32_t fetchdat) +static int opPSUBUSW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -608,7 +608,7 @@ int opPSUBUSW_a16(uint32_t fetchdat) return 0; } -int opPSUBUSW_a32(uint32_t fetchdat) +static int opPSUBUSW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); diff --git a/src/x86_ops_mmx_logic.h b/src/x86_ops_mmx_logic.h index e40df1c..9b55597 100644 --- a/src/x86_ops_mmx_logic.h +++ b/src/x86_ops_mmx_logic.h @@ -1,4 +1,4 @@ -int opPAND_a16(uint32_t fetchdat) +static int opPAND_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -9,7 +9,7 @@ int opPAND_a16(uint32_t fetchdat) MM[reg].q &= src.q; return 0; } -int opPAND_a32(uint32_t fetchdat) +static int opPAND_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -21,7 +21,7 @@ int opPAND_a32(uint32_t fetchdat) return 0; } -int opPANDN_a16(uint32_t fetchdat) +static int opPANDN_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -32,7 +32,7 @@ int opPANDN_a16(uint32_t fetchdat) MM[reg].q = ~MM[reg].q & src.q; return 0; } -int opPANDN_a32(uint32_t fetchdat) +static int opPANDN_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -44,7 +44,7 @@ int opPANDN_a32(uint32_t fetchdat) return 0; } -int opPOR_a16(uint32_t fetchdat) +static int opPOR_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -55,7 +55,7 @@ int opPOR_a16(uint32_t fetchdat) MM[reg].q |= src.q; return 0; } -int opPOR_a32(uint32_t fetchdat) +static int opPOR_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -67,7 +67,7 @@ int opPOR_a32(uint32_t fetchdat) return 0; } -int opPXOR_a16(uint32_t fetchdat) +static int opPXOR_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -78,7 +78,7 @@ int opPXOR_a16(uint32_t fetchdat) MM[reg].q ^= src.q; return 0; } -int opPXOR_a32(uint32_t fetchdat) +static int opPXOR_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); diff --git a/src/x86_ops_mmx_mov.h b/src/x86_ops_mmx_mov.h index cc62e27..30f169e 100644 --- a/src/x86_ops_mmx_mov.h +++ b/src/x86_ops_mmx_mov.h @@ -1,4 +1,4 @@ -int opMOVD_l_mm_a16(uint32_t fetchdat) +static int opMOVD_l_mm_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -13,7 +13,7 @@ int opMOVD_l_mm_a16(uint32_t fetchdat) { uint32_t dst; - dst = readmeml(easeg, eaaddr); if (abrt) return 0; + dst = readmeml(easeg, eaaddr); if (abrt) return 1; MM[reg].l[0] = dst; MM[reg].l[1] = 0; @@ -21,7 +21,7 @@ int opMOVD_l_mm_a16(uint32_t fetchdat) } return 0; } -int opMOVD_l_mm_a32(uint32_t fetchdat) +static int opMOVD_l_mm_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -36,7 +36,7 @@ int opMOVD_l_mm_a32(uint32_t fetchdat) { uint32_t dst; - dst = readmeml(easeg, eaaddr); if (abrt) return 0; + dst = readmeml(easeg, eaaddr); if (abrt) return 1; MM[reg].l[0] = dst; MM[reg].l[1] = 0; @@ -45,7 +45,7 @@ int opMOVD_l_mm_a32(uint32_t fetchdat) return 0; } -int opMOVD_mm_l_a16(uint32_t fetchdat) +static int opMOVD_mm_l_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -58,12 +58,12 @@ int opMOVD_mm_l_a16(uint32_t fetchdat) else { CHECK_WRITE(ea_seg, eaaddr, eaaddr + 3); - writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0; + writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 1; cycles -= 2; } return 0; } -int opMOVD_mm_l_a32(uint32_t fetchdat) +static int opMOVD_mm_l_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -76,13 +76,13 @@ int opMOVD_mm_l_a32(uint32_t fetchdat) else { CHECK_WRITE(ea_seg, eaaddr, eaaddr + 3); - writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0; + writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 1; cycles -= 2; } return 0; } -int opMOVQ_q_mm_a16(uint32_t fetchdat) +static int opMOVQ_q_mm_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -97,14 +97,14 @@ int opMOVQ_q_mm_a16(uint32_t fetchdat) uint32_t dst[2]; dst[0] = readmeml(easeg, eaaddr); - dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; + dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 1; MM[reg].l[0] = dst[0]; MM[reg].l[1] = dst[1]; cycles -= 2; } return 0; } -int opMOVQ_q_mm_a32(uint32_t fetchdat) +static int opMOVQ_q_mm_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -119,7 +119,7 @@ int opMOVQ_q_mm_a32(uint32_t fetchdat) uint32_t dst[2]; dst[0] = readmeml(easeg, eaaddr); - dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; + dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 1; MM[reg].l[0] = dst[0]; MM[reg].l[1] = dst[1]; cycles -= 2; @@ -127,7 +127,7 @@ int opMOVQ_q_mm_a32(uint32_t fetchdat) return 0; } -int opMOVQ_mm_q_a16(uint32_t fetchdat) +static int opMOVQ_mm_q_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -141,12 +141,12 @@ int opMOVQ_mm_q_a16(uint32_t fetchdat) { CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7); writememl(easeg, eaaddr, MM[reg].l[0]); - writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0; + writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 1; cycles -= 2; } return 0; } -int opMOVQ_mm_q_a32(uint32_t fetchdat) +static int opMOVQ_mm_q_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -160,7 +160,7 @@ int opMOVQ_mm_q_a32(uint32_t fetchdat) { CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7); writememl(easeg, eaaddr, MM[reg].l[0]); - writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0; + writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 1; cycles -= 2; } return 0; diff --git a/src/x86_ops_mmx_pack.h b/src/x86_ops_mmx_pack.h index 9f9cf18..b98cd9e 100644 --- a/src/x86_ops_mmx_pack.h +++ b/src/x86_ops_mmx_pack.h @@ -1,4 +1,4 @@ -int opPUNPCKLDQ_a16(uint32_t fetchdat) +static int opPUNPCKLDQ_a16(uint32_t fetchdat) { MMX_ENTER(); @@ -19,7 +19,7 @@ int opPUNPCKLDQ_a16(uint32_t fetchdat) } return 0; } -int opPUNPCKLDQ_a32(uint32_t fetchdat) +static int opPUNPCKLDQ_a32(uint32_t fetchdat) { MMX_ENTER(); @@ -41,7 +41,7 @@ int opPUNPCKLDQ_a32(uint32_t fetchdat) return 0; } -int opPUNPCKHDQ_a16(uint32_t fetchdat) +static int opPUNPCKHDQ_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -53,7 +53,7 @@ int opPUNPCKHDQ_a16(uint32_t fetchdat) return 0; } -int opPUNPCKHDQ_a32(uint32_t fetchdat) +static int opPUNPCKHDQ_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -66,7 +66,7 @@ int opPUNPCKHDQ_a32(uint32_t fetchdat) return 0; } -int opPUNPCKLBW_a16(uint32_t fetchdat) +static int opPUNPCKLBW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -85,7 +85,7 @@ int opPUNPCKLBW_a16(uint32_t fetchdat) return 0; } -int opPUNPCKLBW_a32(uint32_t fetchdat) +static int opPUNPCKLBW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -105,7 +105,7 @@ int opPUNPCKLBW_a32(uint32_t fetchdat) return 0; } -int opPUNPCKHBW_a16(uint32_t fetchdat) +static int opPUNPCKHBW_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -124,7 +124,7 @@ int opPUNPCKHBW_a16(uint32_t fetchdat) return 0; } -int opPUNPCKHBW_a32(uint32_t fetchdat) +static int opPUNPCKHBW_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -144,7 +144,7 @@ int opPUNPCKHBW_a32(uint32_t fetchdat) return 0; } -int opPUNPCKLWD_a16(uint32_t fetchdat) +static int opPUNPCKLWD_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -159,7 +159,7 @@ int opPUNPCKLWD_a16(uint32_t fetchdat) return 0; } -int opPUNPCKLWD_a32(uint32_t fetchdat) +static int opPUNPCKLWD_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -175,7 +175,7 @@ int opPUNPCKLWD_a32(uint32_t fetchdat) return 0; } -int opPUNPCKHWD_a16(uint32_t fetchdat) +static int opPUNPCKHWD_a16(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -190,7 +190,7 @@ int opPUNPCKHWD_a16(uint32_t fetchdat) return 0; } -int opPUNPCKHWD_a32(uint32_t fetchdat) +static int opPUNPCKHWD_a32(uint32_t fetchdat) { MMX_REG src; MMX_ENTER(); @@ -206,7 +206,7 @@ int opPUNPCKHWD_a32(uint32_t fetchdat) return 0; } -int opPACKSSWB_a16(uint32_t fetchdat) +static int opPACKSSWB_a16(uint32_t fetchdat) { MMX_REG src, dst; MMX_ENTER(); @@ -226,7 +226,7 @@ int opPACKSSWB_a16(uint32_t fetchdat) return 0; } -int opPACKSSWB_a32(uint32_t fetchdat) +static int opPACKSSWB_a32(uint32_t fetchdat) { MMX_REG src, dst; MMX_ENTER(); @@ -247,7 +247,7 @@ int opPACKSSWB_a32(uint32_t fetchdat) return 0; } -int opPACKUSWB_a16(uint32_t fetchdat) +static int opPACKUSWB_a16(uint32_t fetchdat) { MMX_REG src, dst; MMX_ENTER(); @@ -267,7 +267,7 @@ int opPACKUSWB_a16(uint32_t fetchdat) return 0; } -int opPACKUSWB_a32(uint32_t fetchdat) +static int opPACKUSWB_a32(uint32_t fetchdat) { MMX_REG src, dst; MMX_ENTER(); @@ -288,7 +288,7 @@ int opPACKUSWB_a32(uint32_t fetchdat) return 0; } -int opPACKSSDW_a16(uint32_t fetchdat) +static int opPACKSSDW_a16(uint32_t fetchdat) { MMX_REG src, dst; MMX_ENTER(); @@ -304,7 +304,7 @@ int opPACKSSDW_a16(uint32_t fetchdat) return 0; } -int opPACKSSDW_a32(uint32_t fetchdat) +static int opPACKSSDW_a32(uint32_t fetchdat) { MMX_REG src, dst; MMX_ENTER(); diff --git a/src/x86_ops_mmx_shift.h b/src/x86_ops_mmx_shift.h index 21c072b..e3e3a48 100644 --- a/src/x86_ops_mmx_shift.h +++ b/src/x86_ops_mmx_shift.h @@ -10,7 +10,7 @@ cycles -= 2; \ } -int opPSxxW_imm(uint32_t fetchdat) +static int opPSxxW_imm(uint32_t fetchdat) { int reg = fetchdat & 7; int op = fetchdat & 0x38; @@ -62,7 +62,7 @@ int opPSxxW_imm(uint32_t fetchdat) return 0; } -int opPSLLW_a16(uint32_t fetchdat) +static int opPSLLW_a16(uint32_t fetchdat) { int shift; @@ -83,7 +83,7 @@ int opPSLLW_a16(uint32_t fetchdat) return 0; } -int opPSLLW_a32(uint32_t fetchdat) +static int opPSLLW_a32(uint32_t fetchdat) { int shift; @@ -105,7 +105,7 @@ int opPSLLW_a32(uint32_t fetchdat) return 0; } -int opPSRLW_a16(uint32_t fetchdat) +static int opPSRLW_a16(uint32_t fetchdat) { int shift; @@ -126,7 +126,7 @@ int opPSRLW_a16(uint32_t fetchdat) return 0; } -int opPSRLW_a32(uint32_t fetchdat) +static int opPSRLW_a32(uint32_t fetchdat) { int shift; @@ -148,7 +148,7 @@ int opPSRLW_a32(uint32_t fetchdat) return 0; } -int opPSRAW_a16(uint32_t fetchdat) +static int opPSRAW_a16(uint32_t fetchdat) { int shift; @@ -167,7 +167,7 @@ int opPSRAW_a16(uint32_t fetchdat) return 0; } -int opPSRAW_a32(uint32_t fetchdat) +static int opPSRAW_a32(uint32_t fetchdat) { int shift; @@ -187,7 +187,7 @@ int opPSRAW_a32(uint32_t fetchdat) return 0; } -int opPSxxD_imm(uint32_t fetchdat) +static int opPSxxD_imm(uint32_t fetchdat) { int reg = fetchdat & 7; int op = fetchdat & 0x38; @@ -233,7 +233,7 @@ int opPSxxD_imm(uint32_t fetchdat) return 0; } -int opPSLLD_a16(uint32_t fetchdat) +static int opPSLLD_a16(uint32_t fetchdat) { int shift; @@ -252,7 +252,7 @@ int opPSLLD_a16(uint32_t fetchdat) return 0; } -int opPSLLD_a32(uint32_t fetchdat) +static int opPSLLD_a32(uint32_t fetchdat) { int shift; @@ -272,7 +272,7 @@ int opPSLLD_a32(uint32_t fetchdat) return 0; } -int opPSRLD_a16(uint32_t fetchdat) +static int opPSRLD_a16(uint32_t fetchdat) { int shift; @@ -291,7 +291,7 @@ int opPSRLD_a16(uint32_t fetchdat) return 0; } -int opPSRLD_a32(uint32_t fetchdat) +static int opPSRLD_a32(uint32_t fetchdat) { int shift; @@ -311,7 +311,7 @@ int opPSRLD_a32(uint32_t fetchdat) return 0; } -int opPSRAD_a16(uint32_t fetchdat) +static int opPSRAD_a16(uint32_t fetchdat) { int shift; @@ -328,7 +328,7 @@ int opPSRAD_a16(uint32_t fetchdat) return 0; } -int opPSRAD_a32(uint32_t fetchdat) +static int opPSRAD_a32(uint32_t fetchdat) { int shift; @@ -346,7 +346,7 @@ int opPSRAD_a32(uint32_t fetchdat) return 0; } -int opPSxxQ_imm(uint32_t fetchdat) +static int opPSxxQ_imm(uint32_t fetchdat) { int reg = fetchdat & 7; int op = fetchdat & 0x38; @@ -385,7 +385,7 @@ int opPSxxQ_imm(uint32_t fetchdat) return 0; } -int opPSLLQ_a16(uint32_t fetchdat) +static int opPSLLQ_a16(uint32_t fetchdat) { int shift; @@ -401,7 +401,7 @@ int opPSLLQ_a16(uint32_t fetchdat) return 0; } -int opPSLLQ_a32(uint32_t fetchdat) +static int opPSLLQ_a32(uint32_t fetchdat) { int shift; @@ -418,7 +418,7 @@ int opPSLLQ_a32(uint32_t fetchdat) return 0; } -int opPSRLQ_a16(uint32_t fetchdat) +static int opPSRLQ_a16(uint32_t fetchdat) { int shift; @@ -434,7 +434,7 @@ int opPSRLQ_a16(uint32_t fetchdat) return 0; } -int opPSRLQ_a32(uint32_t fetchdat) +static int opPSRLQ_a32(uint32_t fetchdat) { int shift; diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index 7a78533..884f7b4 100644 --- a/src/x86_ops_mov.h +++ b/src/x86_ops_mov.h @@ -98,56 +98,56 @@ static int opMOV_SP_imm(uint32_t fetchdat) static int opMOV_EAX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; EAX = templ; cycles -= timing_rr; return 0; } static int opMOV_EBX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; EBX = templ; cycles -= timing_rr; return 0; } static int opMOV_ECX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; ECX = templ; cycles -= timing_rr; return 0; } static int opMOV_EDX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; EDX = templ; cycles -= timing_rr; return 0; } static int opMOV_ESI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; ESI = templ; cycles -= timing_rr; return 0; } static int opMOV_EDI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; EDI = templ; cycles -= timing_rr; return 0; } static int opMOV_EBP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; EBP = templ; cycles -= timing_rr; return 0; } static int opMOV_ESP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (abrt) return 0; + uint32_t templ = getlong(); if (abrt) return 1; ESP = templ; cycles -= timing_rr; return 0; @@ -157,63 +157,63 @@ static int opMOV_b_imm_a16(uint32_t fetchdat) { uint8_t temp; fetch_ea_16(fetchdat); - temp = readmemb(cs,pc); pc++; if (abrt) return 0; + temp = readmemb(cs,pc); pc++; if (abrt) return 1; seteab(temp); cycles -= timing_rr; - return 0; + return abrt; } static int opMOV_b_imm_a32(uint32_t fetchdat) { uint8_t temp; fetch_ea_32(fetchdat); - temp = getbyte(); if (abrt) return 0; + temp = getbyte(); if (abrt) return 1; seteab(temp); cycles -= timing_rr; - return 0; + return abrt; } static int opMOV_w_imm_a16(uint32_t fetchdat) { uint16_t temp; fetch_ea_16(fetchdat); - temp = getword(); if (abrt) return 0; + temp = getword(); if (abrt) return 1; seteaw(temp); cycles -= timing_rr; - return 0; + return abrt; } static int opMOV_w_imm_a32(uint32_t fetchdat) { uint16_t temp; fetch_ea_32(fetchdat); - temp = getword(); if (abrt) return 0; + temp = getword(); if (abrt) return 1; seteaw(temp); cycles -= timing_rr; - return 0; + return abrt; } static int opMOV_l_imm_a16(uint32_t fetchdat) { uint32_t temp; fetch_ea_16(fetchdat); - temp = getlong(); if (abrt) return 0; + temp = getlong(); if (abrt) return 1; seteal(temp); cycles -= timing_rr; - return 0; + return abrt; } static int opMOV_l_imm_a32(uint32_t fetchdat) { uint32_t temp; fetch_ea_32(fetchdat); - temp = getlong(); if (abrt) return 0; + temp = getlong(); if (abrt) return 1; seteal(temp); cycles -= timing_rr; - return 0; + return abrt; } static int opMOV_AL_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); - uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 1; AL = temp; cycles -= (is486) ? 1 : 4; return 0; @@ -221,7 +221,7 @@ static int opMOV_AL_a16(uint32_t fetchdat) static int opMOV_AL_a32(uint32_t fetchdat) { uint32_t addr = getlong(); - uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 1; AL = temp; cycles -= (is486) ? 1 : 4; return 0; @@ -229,7 +229,7 @@ static int opMOV_AL_a32(uint32_t fetchdat) static int opMOV_AX_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); - uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 1; AX = temp; cycles -= (is486) ? 1 : 4; return 0; @@ -237,23 +237,23 @@ static int opMOV_AX_a16(uint32_t fetchdat) static int opMOV_AX_a32(uint32_t fetchdat) { uint32_t addr = getlong(); - uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 1; AX = temp; cycles -= (is486) ? 1 : 4; return 0; } static int opMOV_EAX_a16(uint32_t fetchdat) { - uint16_t addr = getwordf(); if (abrt) return 0; - uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 0; + uint16_t addr = getwordf(); + uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 1; EAX = temp; cycles -= (is486) ? 1 : 4; return 0; } static int opMOV_EAX_a32(uint32_t fetchdat) { - uint32_t addr = getlong(); if (abrt) return 0; - uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 0; + uint32_t addr = getlong(); + uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 1; EAX = temp; cycles -= (is486) ? 1 : 4; return 0; @@ -264,42 +264,42 @@ static int opMOV_a16_AL(uint32_t fetchdat) uint16_t addr = getwordf(); writememb(ea_seg->base, addr, AL); cycles -= (is486) ? 1 : 2; - return 0; + return abrt; } static int opMOV_a32_AL(uint32_t fetchdat) { uint32_t addr = getlong(); writememb(ea_seg->base, addr, AL); cycles -= (is486) ? 1 : 2; - return 0; + return abrt; } static int opMOV_a16_AX(uint32_t fetchdat) { uint16_t addr = getwordf(); writememw(ea_seg->base, addr, AX); cycles -= (is486) ? 1 : 2; - return 0; + return abrt; } static int opMOV_a32_AX(uint32_t fetchdat) { - uint32_t addr = getlong(); + uint32_t addr = getlong(); if (abrt) return 1; writememw(ea_seg->base, addr, AX); cycles -= (is486) ? 1 : 2; - return 0; + return abrt; } static int opMOV_a16_EAX(uint32_t fetchdat) { uint16_t addr = getwordf(); writememl(ea_seg->base, addr, EAX); cycles -= (is486) ? 1 : 2; - return 0; + return abrt; } static int opMOV_a32_EAX(uint32_t fetchdat) { - uint32_t addr = getlong(); + uint32_t addr = getlong(); if (abrt) return 1; writememl(ea_seg->base, addr, EAX); cycles -= (is486) ? 1 : 2; - return 0; + return abrt; } @@ -339,18 +339,18 @@ static int opLEA_l_a32(uint32_t fetchdat) -int opXLAT_a16(uint32_t fetchdat) +static int opXLAT_a16(uint32_t fetchdat) { uint32_t addr = (BX + AL)&0xFFFF; - uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 1; AL = temp; cycles -= 5; return 0; } -int opXLAT_a32(uint32_t fetchdat) +static int opXLAT_a32(uint32_t fetchdat) { uint32_t addr = EBX + AL; - uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 1; AL = temp; cycles -= 5; return 0; @@ -371,7 +371,7 @@ static int opMOV_b_r_a16(uint32_t fetchdat) seteab(getr8(reg)); cycles -= is486 ? 1 : 2; } - return 0; + return abrt; } static int opMOV_b_r_a32(uint32_t fetchdat) { @@ -388,7 +388,7 @@ static int opMOV_b_r_a32(uint32_t fetchdat) seteab(getr8(reg)); cycles -= is486 ? 1 : 2; } - return 0; + return abrt; } static int opMOV_w_r_a16(uint32_t fetchdat) { @@ -405,7 +405,7 @@ static int opMOV_w_r_a16(uint32_t fetchdat) seteaw(regs[reg].w); cycles -= is486 ? 1 : 2; } - return 0; + return abrt; } static int opMOV_w_r_a32(uint32_t fetchdat) { @@ -422,7 +422,7 @@ static int opMOV_w_r_a32(uint32_t fetchdat) seteaw(regs[reg].w); cycles -= is486 ? 1 : 2; } - return 0; + return abrt; } static int opMOV_l_r_a16(uint32_t fetchdat) { @@ -439,7 +439,7 @@ static int opMOV_l_r_a16(uint32_t fetchdat) seteal(regs[reg].l); cycles -= is486 ? 1 : 2; } - return 0; + return abrt; } static int opMOV_l_r_a32(uint32_t fetchdat) { @@ -456,7 +456,7 @@ static int opMOV_l_r_a32(uint32_t fetchdat) seteal(regs[reg].l); cycles -= is486 ? 1 : 2; } - return 0; + return abrt; } static int opMOV_r_b_a16(uint32_t fetchdat) @@ -472,7 +472,7 @@ static int opMOV_r_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); CHECK_READ(ea_seg, eaaddr, eaaddr); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; setr8(reg, temp); cycles -= is486 ? 1 : 4; } @@ -491,7 +491,7 @@ static int opMOV_r_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); CHECK_READ(ea_seg, eaaddr, eaaddr); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; setr8(reg, temp); cycles -= is486 ? 1 : 4; } @@ -510,7 +510,7 @@ static int opMOV_r_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); CHECK_READ(ea_seg, eaaddr, eaaddr+1); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].w = temp; cycles -= (is486) ? 1 : 4; } @@ -529,7 +529,7 @@ static int opMOV_r_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); CHECK_READ(ea_seg, eaaddr, eaaddr+1); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].w = temp; cycles -= (is486) ? 1 : 4; } @@ -548,7 +548,7 @@ static int opMOV_r_l_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); CHECK_READ(ea_seg, eaaddr, eaaddr+3); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; regs[reg].l = temp; cycles -= is486 ? 1 : 4; } @@ -567,7 +567,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); CHECK_READ(ea_seg, eaaddr, eaaddr+3); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; regs[reg].l = temp; cycles -= is486 ? 1 : 4; } diff --git a/src/x86_ops_mov_ctrl.h b/src/x86_ops_mov_ctrl.h index a32f0f8..5f08852 100644 --- a/src/x86_ops_mov_ctrl.h +++ b/src/x86_ops_mov_ctrl.h @@ -4,7 +4,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) { pclog("Can't load from CRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); switch (reg) @@ -40,7 +40,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) { pclog("Can't load from CRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_32(fetchdat); switch (reg) @@ -77,7 +77,7 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat) { pclog("Can't load from DRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); regs[rm].l = 0; @@ -90,7 +90,7 @@ static int opMOV_r_DRx_a32(uint32_t fetchdat) { pclog("Can't load from DRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_32(fetchdat); regs[rm].l = 0; @@ -104,7 +104,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) { pclog("Can't load CRx\n"); x86gpf(NULL,0); - return 0; + return 1; } fetch_ea_16(fetchdat); switch (reg) @@ -144,7 +144,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) { pclog("Can't load CRx\n"); x86gpf(NULL,0); - return 0; + return 1; } fetch_ea_32(fetchdat); switch (reg) @@ -185,7 +185,7 @@ static int opMOV_DRx_r_a16(uint32_t fetchdat) { pclog("Can't load DRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); cycles -= 6; @@ -197,7 +197,7 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat) { pclog("Can't load DRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); cycles -= 6; @@ -210,7 +210,7 @@ static int opMOV_r_TRx_a16(uint32_t fetchdat) { pclog("Can't load from TRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); regs[rm].l = 0; @@ -223,7 +223,7 @@ static int opMOV_r_TRx_a32(uint32_t fetchdat) { pclog("Can't load from TRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_32(fetchdat); regs[rm].l = 0; @@ -237,7 +237,7 @@ static int opMOV_TRx_r_a16(uint32_t fetchdat) { pclog("Can't load TRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); cycles -= 6; @@ -249,7 +249,7 @@ static int opMOV_TRx_r_a32(uint32_t fetchdat) { pclog("Can't load TRx\n"); x86gpf(NULL, 0); - return 0; + return 1; } fetch_ea_16(fetchdat); cycles -= 6; diff --git a/src/x86_ops_mov_seg.h b/src/x86_ops_mov_seg.h index dd03b89..866dcdc 100644 --- a/src/x86_ops_mov_seg.h +++ b/src/x86_ops_mov_seg.h @@ -25,7 +25,7 @@ static int opMOV_w_seg_a16(uint32_t fetchdat) } cycles -= ((mod == 3) ? 2 : 3); - return 0; + return abrt; } static int opMOV_w_seg_a32(uint32_t fetchdat) { @@ -54,7 +54,7 @@ static int opMOV_w_seg_a32(uint32_t fetchdat) } cycles -= ((mod == 3) ? 2 : 3); - return 0; + return abrt; } static int opMOV_l_seg_a16(uint32_t fetchdat) @@ -90,7 +90,7 @@ static int opMOV_l_seg_a16(uint32_t fetchdat) } cycles -= ((mod == 3) ? 2 : 3); - return 0; + return abrt; } static int opMOV_l_seg_a32(uint32_t fetchdat) { @@ -125,7 +125,7 @@ static int opMOV_l_seg_a32(uint32_t fetchdat) } cycles -= ((mod == 3) ? 2 : 3); - return 0; + return abrt; } static int opMOV_seg_w_a16(uint32_t fetchdat) @@ -134,7 +134,7 @@ static int opMOV_seg_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - new_seg=geteaw(); if (abrt) return 0; + new_seg=geteaw(); if (abrt) return 1; switch (rmdat & 0x38) { @@ -146,12 +146,15 @@ static int opMOV_seg_w_a16(uint32_t fetchdat) break; case 0x10: /*SS*/ loadseg(new_seg, &_ss); - if (abrt) return 0; + if (abrt) return 1; oldpc = pc; op32 = use32; ssegs = 0; ea_seg = &_ds; - return 1; + fetchdat = fastreadl(cs + pc); + pc++; + if (abrt) return 1; + return x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8); case 0x20: /*FS*/ loadseg(new_seg, &_fs); break; @@ -161,7 +164,7 @@ static int opMOV_seg_w_a16(uint32_t fetchdat) } cycles -= ((mod == 3) ? 2 : 5); - return 0; + return abrt; } static int opMOV_seg_w_a32(uint32_t fetchdat) { @@ -169,7 +172,7 @@ static int opMOV_seg_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - new_seg=geteaw(); if (abrt) return 0; + new_seg=geteaw(); if (abrt) return 1; switch (rmdat & 0x38) { @@ -181,12 +184,15 @@ static int opMOV_seg_w_a32(uint32_t fetchdat) break; case 0x10: /*SS*/ loadseg(new_seg, &_ss); - if (abrt) return 0; + if (abrt) return 1; oldpc = pc; op32 = use32; ssegs = 0; ea_seg = &_ds; - return 1; + fetchdat = fastreadl(cs + pc); + pc++; + if (abrt) return 1; + return x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8); case 0x20: /*FS*/ loadseg(new_seg, &_fs); break; @@ -196,7 +202,7 @@ static int opMOV_seg_w_a32(uint32_t fetchdat) } cycles -= ((mod == 3) ? 2 : 5); - return 0; + return abrt; } @@ -207,8 +213,8 @@ static int opLDS_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; - loadseg(seg, &_ds); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 1; + loadseg(seg, &_ds); if (abrt) return 1; regs[reg].w = addr; cycles -= 7; @@ -221,8 +227,8 @@ static int opLDS_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; - loadseg(seg, &_ds); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 1; + loadseg(seg, &_ds); if (abrt) return 1; regs[reg].w = addr; cycles -= 7; @@ -236,8 +242,8 @@ static int opLDS_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; - loadseg(seg, &_ds); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 1; + loadseg(seg, &_ds); if (abrt) return 1; regs[reg].l = addr; cycles -= 7; @@ -251,8 +257,8 @@ static int opLDS_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; - loadseg(seg, &_ds); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 1; + loadseg(seg, &_ds); if (abrt) return 1; regs[reg].l = addr; cycles -= 7; @@ -266,8 +272,8 @@ static int opLSS_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; - loadseg(seg, &_ss); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 1; + loadseg(seg, &_ss); if (abrt) return 1; regs[reg].w = addr; cycles -= 7; @@ -280,8 +286,8 @@ static int opLSS_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; - loadseg(seg, &_ss); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 1; + loadseg(seg, &_ss); if (abrt) return 1; regs[reg].w = addr; cycles -= 7; @@ -295,8 +301,8 @@ static int opLSS_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; - loadseg(seg, &_ss); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 1; + loadseg(seg, &_ss); if (abrt) return 1; regs[reg].l = addr; cycles -= 7; @@ -310,8 +316,8 @@ static int opLSS_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); - seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; - loadseg(seg, &_ss); if (abrt) return 0; + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 1; + loadseg(seg, &_ss); if (abrt) return 1; regs[reg].l = addr; cycles -= 7; @@ -326,8 +332,8 @@ static int opLSS_l_a32(uint32_t fetchdat) fetch_ea_16(fetchdat); \ ILLEGAL_ON(mod == 3); \ addr = readmemw(easeg, eaaddr); \ - seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \ - loadseg(seg, &sel); if (abrt) return 0; \ + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 1; \ + loadseg(seg, &sel); if (abrt) return 1; \ regs[reg].w = addr; \ \ cycles -= 7; \ @@ -341,8 +347,8 @@ static int opLSS_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); \ ILLEGAL_ON(mod == 3); \ addr = readmemw(easeg, eaaddr); \ - seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \ - loadseg(seg, &sel); if (abrt) return 0; \ + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 1; \ + loadseg(seg, &sel); if (abrt) return 1; \ regs[reg].w = addr; \ \ cycles -= 7; \ @@ -357,8 +363,8 @@ static int opLSS_l_a32(uint32_t fetchdat) fetch_ea_16(fetchdat); \ ILLEGAL_ON(mod == 3); \ addr = readmeml(easeg, eaaddr); \ - seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \ - loadseg(seg, &sel); if (abrt) return 0; \ + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 1; \ + loadseg(seg, &sel); if (abrt) return 1; \ regs[reg].l = addr; \ \ cycles -= 7; \ @@ -373,8 +379,8 @@ static int opLSS_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); \ ILLEGAL_ON(mod == 3); \ addr = readmeml(easeg, eaaddr); \ - seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \ - loadseg(seg, &sel); if (abrt) return 0; \ + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 1; \ + loadseg(seg, &sel); if (abrt) return 1; \ regs[reg].l = addr; \ \ cycles -= 7; \ diff --git a/src/x86_ops_movx.h b/src/x86_ops_movx.h index 77226c2..c6fb2aa 100644 --- a/src/x86_ops_movx.h +++ b/src/x86_ops_movx.h @@ -3,7 +3,7 @@ static int opMOVZX_w_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].w = (uint16_t)temp; cycles -= 3; @@ -14,7 +14,7 @@ static int opMOVZX_w_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].w = (uint16_t)temp; cycles -= 3; @@ -25,7 +25,7 @@ static int opMOVZX_l_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; cycles -= 3; @@ -36,7 +36,7 @@ static int opMOVZX_l_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; cycles -= 3; @@ -47,7 +47,7 @@ static int opMOVZX_w_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].w = temp; cycles -= 3; @@ -58,7 +58,7 @@ static int opMOVZX_w_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].w = temp; cycles -= 3; @@ -69,7 +69,7 @@ static int opMOVZX_l_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; cycles -= 3; @@ -80,7 +80,7 @@ static int opMOVZX_l_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; cycles -= 3; @@ -92,7 +92,7 @@ static int opMOVSX_w_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].w = (uint16_t)temp; if (temp & 0x80) regs[reg].w |= 0xff00; @@ -105,7 +105,7 @@ static int opMOVSX_w_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].w = (uint16_t)temp; if (temp & 0x80) regs[reg].w |= 0xff00; @@ -118,7 +118,7 @@ static int opMOVSX_l_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; if (temp & 0x80) regs[reg].l |= 0xffffff00; @@ -131,7 +131,7 @@ static int opMOVSX_l_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; if (temp & 0x80) regs[reg].l |= 0xffffff00; @@ -144,7 +144,7 @@ static int opMOVSX_l_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; if (temp & 0x8000) regs[reg].l |= 0xffff0000; @@ -157,7 +157,7 @@ static int opMOVSX_l_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; regs[reg].l = (uint32_t)temp; if (temp & 0x8000) regs[reg].l |= 0xffff0000; diff --git a/src/x86_ops_msr.h b/src/x86_ops_msr.h index 743af64..425c563 100644 --- a/src/x86_ops_msr.h +++ b/src/x86_ops_msr.h @@ -4,12 +4,12 @@ static int opRDTSC(uint32_t fetchdat) { pc = oldpc; x86illegal(); - return 0; + return 1; } if ((cr4 & CR4_TSD) && CPL) { x86gpf("RDTSC when TSD set and CPL != 0", 0); - return 0; + return 1; } EAX = tsc & 0xffffffff; EDX = tsc >> 32; diff --git a/src/x86_ops_mul.h b/src/x86_ops_mul.h index 1326cb8..67707e7 100644 --- a/src/x86_ops_mul.h +++ b/src/x86_ops_mul.h @@ -5,8 +5,8 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - tempw = geteaw(); if (abrt) return 0; - tempw2 = getword(); if (abrt) return 0; + tempw = geteaw(); if (abrt) return 1; + tempw2 = getword(); if (abrt) return 1; templ = ((int)tempw) * ((int)tempw2); flags_rebuild(); @@ -24,8 +24,8 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - tempw = geteaw(); if (abrt) return 0; - tempw2 = getword(); if (abrt) return 0; + tempw = geteaw(); if (abrt) return 1; + tempw2 = getword(); if (abrt) return 1; templ = ((int)tempw) * ((int)tempw2); flags_rebuild(); @@ -44,8 +44,8 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - templ = geteal(); if (abrt) return 0; - templ2 = getlong(); if (abrt) return 0; + templ = geteal(); if (abrt) return 1; + templ2 = getlong(); if (abrt) return 1; temp64 = ((int64_t)templ) * ((int64_t)templ2); flags_rebuild(); @@ -63,8 +63,8 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - templ = geteal(); if (abrt) return 0; - templ2 = getlong(); if (abrt) return 0; + templ = geteal(); if (abrt) return 1; + templ2 = getlong(); if (abrt) return 1; temp64 = ((int64_t)templ) * ((int64_t)templ2); flags_rebuild(); @@ -83,8 +83,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - tempw = geteaw(); if (abrt) return 0; - tempw2 = getbyte(); if (abrt) return 0; + tempw = geteaw(); if (abrt) return 1; + tempw2 = getbyte(); if (abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; templ = ((int)tempw) * ((int)tempw2); @@ -103,8 +103,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - tempw = geteaw(); if (abrt) return 0; - tempw2 = getbyte(); if (abrt) return 0; + tempw = geteaw(); if (abrt) return 1; + tempw2 = getbyte(); if (abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; templ = ((int)tempw) * ((int)tempw2); @@ -123,8 +123,8 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) int32_t templ, templ2; fetch_ea_16(fetchdat); - templ = geteal(); if (abrt) return 0; - templ2 = getbyte(); if (abrt) return 0; + templ = geteal(); if (abrt) return 1; + templ2 = getbyte(); if (abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; temp64 = ((int64_t)templ)*((int64_t)templ2); @@ -142,8 +142,8 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) int32_t templ, templ2; fetch_ea_32(fetchdat); - templ = geteal(); if (abrt) return 0; - templ2 = getbyte(); if (abrt) return 0; + templ = geteal(); if (abrt) return 1; + templ2 = getbyte(); if (abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; temp64 = ((int64_t)templ)*((int64_t)templ2); @@ -164,7 +164,7 @@ static int opIMUL_w_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw(); - if (abrt) return 0; + if (abrt) return 1; regs[reg].w = templ & 0xFFFF; flags_rebuild(); if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; @@ -179,7 +179,7 @@ static int opIMUL_w_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw(); - if (abrt) return 0; + if (abrt) return 1; regs[reg].w = templ & 0xFFFF; flags_rebuild(); if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; @@ -195,7 +195,7 @@ static int opIMUL_l_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal(); - if (abrt) return 0; + if (abrt) return 1; regs[reg].l = temp64 & 0xFFFFFFFF; flags_rebuild(); if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; @@ -210,7 +210,7 @@ static int opIMUL_l_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal(); - if (abrt) return 0; + if (abrt) return 1; regs[reg].l = temp64 & 0xFFFFFFFF; flags_rebuild(); if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index cd2a934..6da1b5f 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -4,14 +4,14 @@ static int opARPL_a16(uint32_t fetchdat) NOTRM fetch_ea_16(fetchdat); - - temp_seg = geteaw(); if (abrt) return 0; + pclog("ARPL_a16\n"); + temp_seg = geteaw(); if (abrt) return 1; flags_rebuild(); if ((temp_seg & 3) < (regs[reg].w & 3)) { temp_seg = (temp_seg & 0xfffc) | (regs[reg].w & 3); - seteaw(temp_seg); if (abrt) return 0; + seteaw(temp_seg); if (abrt) return 1; flags |= Z_FLAG; } else @@ -26,14 +26,14 @@ static int opARPL_a32(uint32_t fetchdat) NOTRM fetch_ea_32(fetchdat); - - temp_seg = geteaw(); if (abrt) return 0; + pclog("ARPL_a32\n"); + temp_seg = geteaw(); if (abrt) return 1; flags_rebuild(); if ((temp_seg & 3) < (regs[reg].w & 3)) { temp_seg = (temp_seg & 0xfffc) | (regs[reg].w & 3); - seteaw(temp_seg); if (abrt) return 0; + seteaw(temp_seg); if (abrt) return 1; flags |= Z_FLAG; } else @@ -52,7 +52,7 @@ static int opARPL_a32(uint32_t fetchdat) NOTRM \ fetch_ea(fetchdat); \ \ - sel = geteaw(); if (abrt) return 0; \ + sel = geteaw(); if (abrt) return 1; \ \ flags_rebuild(); \ if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ @@ -61,7 +61,7 @@ static int opARPL_a32(uint32_t fetchdat) { \ cpl_override = 1; \ desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (abrt) return 0; \ + cpl_override = 0; if (abrt) return 1; \ } \ flags &= ~Z_FLAG; \ if ((desc & 0x1f00) == 0x000) valid = 0; \ @@ -84,7 +84,7 @@ static int opARPL_a32(uint32_t fetchdat) cpl_override = 0; \ } \ cycles -= 11; \ - return 0; \ + return abrt; \ } opLAR(w_a16, fetch_ea_16, 0) @@ -101,7 +101,7 @@ opLAR(l_a32, fetch_ea_32, 1) NOTRM \ fetch_ea(fetchdat); \ \ - sel = geteaw(); if (abrt) return 0; \ + sel = geteaw(); if (abrt) return 1; \ flags_rebuild(); \ flags &= ~Z_FLAG; \ if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ @@ -110,7 +110,7 @@ opLAR(l_a32, fetch_ea_32, 1) { \ cpl_override = 1; \ desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (abrt) return 0; \ + cpl_override = 0; if (abrt) return 1; \ } \ if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \ if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \ @@ -139,7 +139,7 @@ opLAR(l_a32, fetch_ea_32, 1) cpl_override = 0; \ } \ cycles -= 10; \ - return 0; \ + return abrt; \ } opLSL(w_a16, fetch_ea_16, 0) @@ -148,7 +148,7 @@ opLSL(l_a16, fetch_ea_16, 1) opLSL(l_a32, fetch_ea_32, 1) -static inline int op0F00_common(uint32_t fetchdat) +static int op0F00_common(uint32_t fetchdat) { int dpl, valid, granularity; uint32_t addr, base, limit; @@ -171,15 +171,15 @@ static inline int op0F00_common(uint32_t fetchdat) { pclog("Invalid LLDT!\n"); x86gpf(NULL,0); - return 0; + return 1; } - sel = geteaw(); if (abrt) return 0; + sel = geteaw(); if (abrt) return 1; addr = (sel & ~7) + gdt.base; limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); access = readmemb(0, addr + 5); granularity = readmemb(0, addr + 6) & 0x80; - if (abrt) return 0; + if (abrt) return 1; ldt.limit = limit; ldt.access = access; if (granularity) @@ -198,13 +198,13 @@ static inline int op0F00_common(uint32_t fetchdat) x86gpf(NULL,0); break; } - sel = geteaw(); if (abrt) return 0; + sel = geteaw(); if (abrt) return 1; addr = (sel & ~7) + gdt.base; limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); access = readmemb(0, addr + 5); granularity = readmemb(0, addr + 6) & 0x80; - if (abrt) return 0; + if (abrt) return 1; tr.seg = sel; tr.limit = limit; tr.access = access; @@ -217,14 +217,14 @@ static inline int op0F00_common(uint32_t fetchdat) cycles -= 20; break; case 0x20: /*VERR*/ - sel = geteaw(); if (abrt) return 0; + sel = geteaw(); if (abrt) return 1; flags_rebuild(); flags &= ~Z_FLAG; if (!(sel & 0xfffc)) return 0; /*Null selector*/ cpl_override = 1; valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (abrt) return 0; + cpl_override = 0; if (abrt) return 1; if (!(desc & 0x1000)) valid = 0; if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ { @@ -236,14 +236,14 @@ static inline int op0F00_common(uint32_t fetchdat) cycles -= 20; break; case 0x28: /*VERW*/ - sel = geteaw(); if (abrt) return 0; + sel = geteaw(); if (abrt) return 1; flags_rebuild(); flags &= ~Z_FLAG; if (!(sel & 0xfffc)) return 0; /*Null selector*/ cpl_override = 1; valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (abrt) return 0; + cpl_override = 0; if (abrt) return 1; if (!(desc & 0x1000)) valid = 0; dpl = (desc >> 13) & 3; /*Check permissions*/ if (dpl < CPL || dpl < (sel & 3)) valid = 0; @@ -259,29 +259,27 @@ static inline int op0F00_common(uint32_t fetchdat) x86illegal(); break; } - return 0; + return abrt; } -static inline op0F00_a16(uint32_t fetchdat) +static int op0F00_a16(uint32_t fetchdat) { NOTRM fetch_ea_16(fetchdat); - op0F00_common(fetchdat); - return 0; + return op0F00_common(fetchdat); } -static inline op0F00_a32(uint32_t fetchdat) +static int op0F00_a32(uint32_t fetchdat) { NOTRM fetch_ea_32(fetchdat); - op0F00_common(fetchdat); - return 0; + return op0F00_common(fetchdat); } -static inline op0F01_common(uint32_t fetchdat, int is32, int is286) +static int op0F01_common(uint32_t fetchdat, int is32, int is286) { uint32_t base; uint16_t limit, tempw; @@ -313,7 +311,7 @@ static inline op0F01_common(uint32_t fetchdat, int is32, int is286) } // pclog("LGDT %08X:%08X\n", easeg, eaaddr); limit = geteaw(); - base = readmeml(0, easeg + eaaddr + 2); if (abrt) return 0; + base = readmeml(0, easeg + eaaddr + 2); if (abrt) return 1; // pclog(" %08X %04X\n", base, limit); gdt.limit = limit; gdt.base = base; @@ -329,7 +327,7 @@ static inline op0F01_common(uint32_t fetchdat, int is32, int is286) } // pclog("LIDT %08X:%08X\n", easeg, eaaddr); limit = geteaw(); - base = readmeml(0, easeg + eaaddr + 2); if (abrt) return 0; + base = readmeml(0, easeg + eaaddr + 2); if (abrt) return 1; // pclog(" %08X %04X\n", base, limit); idt.limit = limit; idt.base = base; @@ -349,7 +347,7 @@ static inline op0F01_common(uint32_t fetchdat, int is32, int is286) x86gpf(NULL, 0); break; } - tempw = geteaw(); if (abrt) return 0; + tempw = geteaw(); if (abrt) return 1; if (msw & 1) tempw |= 1; msw = tempw; break; @@ -374,42 +372,37 @@ static inline op0F01_common(uint32_t fetchdat, int is32, int is286) x86illegal(); break; } - return 0; + return abrt; } -static inline op0F01_w_a16(uint32_t fetchdat) +static int op0F01_w_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - op0F01_common(fetchdat, 0, 0); - return 0; + return op0F01_common(fetchdat, 0, 0); } -static inline op0F01_w_a32(uint32_t fetchdat) +static int op0F01_w_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - op0F01_common(fetchdat, 0, 0); - return 0; + return op0F01_common(fetchdat, 0, 0); } -static inline op0F01_l_a16(uint32_t fetchdat) +static int op0F01_l_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - op0F01_common(fetchdat, 1, 0); - return 0; + return op0F01_common(fetchdat, 1, 0); } -static inline op0F01_l_a32(uint32_t fetchdat) +static int op0F01_l_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - op0F01_common(fetchdat, 1, 0); - return 0; + return op0F01_common(fetchdat, 1, 0); } -static inline op0F01_286(uint32_t fetchdat) +static int op0F01_286(uint32_t fetchdat) { fetch_ea_16(fetchdat); - op0F01_common(fetchdat, 0, 1); - return 0; + return op0F01_common(fetchdat, 0, 1); } diff --git a/src/x86_ops_prefix.h b/src/x86_ops_prefix.h index e75a9d1..5fb0e51 100644 --- a/src/x86_ops_prefix.h +++ b/src/x86_ops_prefix.h @@ -1,56 +1,80 @@ -static int op_CS(uint32_t fetchdat) -{ - ea_seg = &_cs; - ssegs = 1; - cycles -= 4; - return 1; -} -static int op_DS(uint32_t fetchdat) -{ - ea_seg = &_ds; - ssegs = 1; - cycles -= 4; - return 1; -} -static int op_ES(uint32_t fetchdat) -{ - ea_seg = &_es; - ssegs = 1; - cycles -= 4; - return 1; -} -static int op_FS(uint32_t fetchdat) -{ - ea_seg = &_fs; - ssegs = 1; - cycles -= 4; - return 1; -} -static int op_GS(uint32_t fetchdat) -{ - ea_seg = &_gs; - ssegs = 1; - cycles -= 4; - return 1; -} -static int op_SS(uint32_t fetchdat) -{ - ea_seg = &_ss; - ssegs = 1; - cycles -= 4; - return 1; +#define op_seg(name, seg) \ +static int op ## name ## _w_a16(uint32_t fetchdat) \ +{ \ + fetchdat = fastreadl(cs + pc); \ + if (abrt) return 1; \ + pc++; \ + \ + ea_seg = &seg; \ + ssegs = 1; \ + cycles -= 4; \ + \ + return x86_opcodes[fetchdat & 0xff](fetchdat >> 8); \ +} \ + \ +static int op ## name ## _l_a16(uint32_t fetchdat) \ +{ \ + fetchdat = fastreadl(cs + pc); \ + if (abrt) return 1; \ + pc++; \ + \ + ea_seg = &seg; \ + ssegs = 1; \ + cycles -= 4; \ + \ + return x86_opcodes[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ +} \ + \ +static int op ## name ## _w_a32(uint32_t fetchdat) \ +{ \ + fetchdat = fastreadl(cs + pc); \ + if (abrt) return 1; \ + pc++; \ + \ + ea_seg = &seg; \ + ssegs = 1; \ + cycles -= 4; \ + \ + return x86_opcodes[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ +} \ + \ +static int op ## name ## _l_a32(uint32_t fetchdat) \ +{ \ + fetchdat = fastreadl(cs + pc); \ + if (abrt) return 1; \ + pc++; \ + \ + ea_seg = &seg; \ + ssegs = 1; \ + cycles -= 4; \ + \ + return x86_opcodes[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ } +op_seg(CS, _cs) +op_seg(DS, _ds) +op_seg(ES, _es) +op_seg(FS, _fs) +op_seg(GS, _gs) +op_seg(SS, _ss) static int op_66(uint32_t fetchdat) /*Data size select*/ { + fetchdat = fastreadl(cs + pc); + if (abrt) return 1; + pc++; + op32 = ((use32 & 0x100) ^ 0x100) | (op32 & 0x200); cycles -= 2; - return 1; + return x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8); } static int op_67(uint32_t fetchdat) /*Address size select*/ { + fetchdat = fastreadl(cs + pc); + if (abrt) return 1; + pc++; + op32 = ((use32 & 0x200) ^ 0x200) | (op32 & 0x100); cycles -= 2; - return 1; + return x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8); } diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index e941ebb..7d3713a 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -1,11 +1,9 @@ static int opREPNE(uint32_t fetchdat) { - rep386(0); - return 0; + return rep386(0); } static int opREPE(uint32_t fetchdat) { - rep386(1); - return 0; + return rep386(1); } diff --git a/src/x86_ops_ret.h b/src/x86_ops_ret.h index b549feb..46f5b8a 100644 --- a/src/x86_ops_ret.h +++ b/src/x86_ops_ret.h @@ -2,7 +2,7 @@ if ((msw&1) && !(eflags&VM_FLAG)) \ { \ pmoderetf(0, stack_offset); \ - return 0; \ + return 1; \ } \ oxpc = pc; \ if (stack32) \ @@ -15,7 +15,7 @@ pc = readmemw(ss, SP); \ loadcs(readmemw(ss, SP + 2)); \ } \ - if (abrt) return 0; \ + if (abrt) return 1; \ if (stack32) ESP += 4 + stack_offset; \ else SP += 4 + stack_offset; \ cycles -= is486 ? 13 : 18; @@ -24,7 +24,7 @@ if ((msw&1) && !(eflags&VM_FLAG)) \ { \ pmoderetf(1, stack_offset); \ - return 0; \ + return 1; \ } \ oxpc = pc; \ if (stack32) \ @@ -37,18 +37,20 @@ pc = readmeml(ss, SP); \ loadcs(readmeml(ss, SP + 4) & 0xffff); \ } \ - if (abrt) return 0; \ + if (abrt) return 1; \ if (stack32) ESP += 8 + stack_offset; \ else SP += 8 + stack_offset; \ cycles -= is486 ? 13 : 18; static int opRETF_a16(uint32_t fetchdat) { + CPU_BLOCK_END(); RETF_a16(0); return 0; } static int opRETF_a32(uint32_t fetchdat) { + CPU_BLOCK_END(); RETF_a32(0); return 0; } @@ -56,12 +58,14 @@ static int opRETF_a32(uint32_t fetchdat) static int opRETF_a16_imm(uint32_t fetchdat) { uint16_t offset = getwordf(); + CPU_BLOCK_END(); RETF_a16(offset); return 0; } static int opRETF_a32_imm(uint32_t fetchdat) { uint16_t offset = getwordf(); + CPU_BLOCK_END(); RETF_a32(offset); return 0; } @@ -71,7 +75,7 @@ static int opIRET_286(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); - return 0; + return 1; } if (msw&1) { @@ -102,7 +106,8 @@ static int opIRET_286(uint32_t fetchdat) flags_extract(); cycles -= is486 ? 15 : 22; nmi_enable = 1; - return 0; + CPU_BLOCK_END(); + return abrt; } static int opIRET(uint32_t fetchdat) @@ -110,7 +115,7 @@ static int opIRET(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); - return 0; + return 1; } if (msw&1) { @@ -141,7 +146,8 @@ static int opIRET(uint32_t fetchdat) flags_extract(); cycles -= is486 ? 15 : 22; nmi_enable = 1; - return 0; + CPU_BLOCK_END(); + return abrt; } static int opIRETD(uint32_t fetchdat) @@ -149,7 +155,7 @@ static int opIRETD(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); - return 0; + return 1; } if (msw & 1) { @@ -182,6 +188,7 @@ static int opIRETD(uint32_t fetchdat) flags_extract(); cycles -= is486 ? 15 : 22; nmi_enable = 1; - return 0; + CPU_BLOCK_END(); + return abrt; } diff --git a/src/x86_ops_set.h b/src/x86_ops_set.h index 45dfb14..aaadf4b 100644 --- a/src/x86_ops_set.h +++ b/src/x86_ops_set.h @@ -4,7 +4,7 @@ fetch_ea_16(fetchdat); \ seteab((cond_ ## condition) ? 1 : 0); \ cycles -= 4; \ - return 0; \ + return abrt; \ } \ \ static int opSET ## condition ## _a32(uint32_t fetchdat) \ @@ -12,7 +12,7 @@ fetch_ea_32(fetchdat); \ seteab((cond_ ## condition) ? 1 : 0); \ cycles -= 4; \ - return 0; \ + return abrt; \ } opSET(O) diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index d4a7c4a..71c5e7c 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -12,7 +12,7 @@ temp = (temp << 1) | temp2; \ c--; \ } \ - seteab(temp); if (abrt) return 0; \ + seteab(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ @@ -26,7 +26,7 @@ if (temp2) temp |= 0x80; \ c--; \ } \ - seteab(temp); if (abrt) return 0; \ + seteab(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ @@ -42,7 +42,7 @@ c--; \ if (is486) cycles--; \ } \ - seteab(temp); if (abrt) return 0; \ + seteab(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ @@ -58,20 +58,20 @@ c--; \ if (is486) cycles--; \ } \ - seteab(temp); if (abrt) return 0; \ + seteab(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ cycles -= ((mod == 3) ? 9 : 10); \ break; \ case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (abrt) return 0; \ + seteab(temp << c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ break; \ case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (abrt) return 0; \ + seteab(temp >> c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ @@ -84,7 +84,7 @@ if (temp & 0x40) temp |= 0x80; \ c--; \ } \ - seteab(temp); if (abrt) return 0; \ + seteab(temp); if (abrt) return 1; \ set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ if (tempc) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ @@ -106,7 +106,7 @@ temp = (temp << 1) | temp2; \ c--; \ } \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ @@ -120,7 +120,7 @@ if (temp2) temp |= 0x8000; \ c--; \ } \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ @@ -136,7 +136,7 @@ c--; \ if (is486) cycles--; \ } \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ @@ -152,20 +152,20 @@ c--; \ if (is486) cycles--; \ } \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ cycles -= ((mod == 3) ? 9 : 10); \ break; \ case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (abrt) return 0; \ + seteaw(temp << c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ break; \ case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (abrt) return 0; \ + seteaw(temp >> c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ @@ -178,7 +178,7 @@ if (temp & 0x4000) temp |= 0x8000; \ c--; \ } \ - seteaw(temp); if (abrt) return 0; \ + seteaw(temp); if (abrt) return 1; \ set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ if (tempc) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ @@ -200,7 +200,7 @@ temp = (temp << 1) | temp2; \ c--; \ } \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ @@ -214,7 +214,7 @@ if (temp2) temp |= 0x80000000; \ c--; \ } \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ @@ -230,7 +230,7 @@ c--; \ if (is486) cycles--; \ } \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ @@ -246,20 +246,20 @@ c--; \ if (is486) cycles--; \ } \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ flags &= ~(C_FLAG | V_FLAG); \ if (temp2) flags |= C_FLAG; \ if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ cycles -= ((mod == 3) ? 9 : 10); \ break; \ case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (abrt) return 0; \ + seteal(temp << c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ break; \ case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (abrt) return 0; \ + seteal(temp >> c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ @@ -272,7 +272,7 @@ if (temp & 0x40000000) temp |= 0x80000000; \ c--; \ } \ - seteal(temp); if (abrt) return 0; \ + seteal(temp); if (abrt) return 1; \ set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ if (tempc) flags |= C_FLAG; \ cycles -= ((mod == 3) ? 3 : 7); \ @@ -288,7 +288,7 @@ static int opC0_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); c = readmemb(cs, pc) & 31; pc++; - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; OP_SHIFT_b(c); return 0; } @@ -300,7 +300,7 @@ static int opC0_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); c = readmemb(cs, pc) & 31; pc++; - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; OP_SHIFT_b(c); return 0; } @@ -312,7 +312,7 @@ static int opC1_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); c = readmemb(cs, pc) & 31; pc++; - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; OP_SHIFT_w(c); return 0; } @@ -324,7 +324,7 @@ static int opC1_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); c = readmemb(cs, pc) & 31; pc++; - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; OP_SHIFT_w(c); return 0; } @@ -336,7 +336,7 @@ static int opC1_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); c = readmemb(cs, pc) & 31; pc++; - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; OP_SHIFT_l(c); return 0; } @@ -348,7 +348,7 @@ static int opC1_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); c = readmemb(cs, pc) & 31; pc++; - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; OP_SHIFT_l(c); return 0; } @@ -360,7 +360,7 @@ static int opD0_a16(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; OP_SHIFT_b(c); return 0; } @@ -371,7 +371,7 @@ static int opD0_a32(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; OP_SHIFT_b(c); return 0; } @@ -382,7 +382,7 @@ static int opD1_w_a16(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; OP_SHIFT_w(c); return 0; } @@ -393,7 +393,7 @@ static int opD1_w_a32(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; OP_SHIFT_w(c); return 0; } @@ -404,7 +404,7 @@ static int opD1_l_a16(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; OP_SHIFT_l(c); return 0; } @@ -415,7 +415,7 @@ static int opD1_l_a32(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; OP_SHIFT_l(c); return 0; } @@ -428,7 +428,7 @@ static int opD2_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); c = CL & 31; - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; OP_SHIFT_b(c); return 0; } @@ -440,7 +440,7 @@ static int opD2_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); c = CL & 31; - temp = geteab(); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; OP_SHIFT_b(c); return 0; } @@ -452,7 +452,7 @@ static int opD3_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); c = CL & 31; - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; OP_SHIFT_w(c); return 0; } @@ -464,7 +464,7 @@ static int opD3_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); c = CL & 31; - temp = geteaw(); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; OP_SHIFT_w(c); return 0; } @@ -476,7 +476,7 @@ static int opD3_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); c = CL & 31; - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; OP_SHIFT_l(c); return 0; } @@ -488,7 +488,7 @@ static int opD3_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); c = CL & 31; - temp = geteal(); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; OP_SHIFT_l(c); return 0; } @@ -497,12 +497,12 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHLD_w() \ if (count) \ { \ - uint16_t tempw = geteaw(); if (abrt) return 0; \ + uint16_t tempw = geteaw(); if (abrt) return 1; \ int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ uint32_t templ = (tempw << 16) | regs[reg].w; \ if (count <= 16) tempw = templ >> (16 - count); \ else tempw = (templ << count) >> 16; \ - seteaw(tempw); if (abrt) return 0; \ + seteaw(tempw); if (abrt) return 1; \ setznp16(tempw); \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ @@ -511,10 +511,10 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHLD_l() \ if (count) \ { \ - uint32_t templ = geteal(); if (abrt) return 0; \ + uint32_t templ = geteal(); if (abrt) return 1; \ int tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ templ = (templ << count) | (regs[reg].l >> (32 - count)); \ - seteal(templ); if (abrt) return 0; \ + seteal(templ); if (abrt) return 1; \ setznp32(templ); \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ @@ -524,11 +524,11 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHRD_w() \ if (count) \ { \ - uint16_t tempw = geteaw(); if (abrt) return 0; \ + uint16_t tempw = geteaw(); if (abrt) return 1; \ int tempc = (tempw >> (count - 1)) & 1; \ uint32_t templ = tempw | (regs[reg].w << 16); \ tempw = templ >> count; \ - seteaw(tempw); if (abrt) return 0; \ + seteaw(tempw); if (abrt) return 1; \ setznp16(tempw); \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ @@ -537,10 +537,10 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHRD_l() \ if (count) \ { \ - uint32_t templ = geteal(); if (abrt) return 0; \ + uint32_t templ = geteal(); if (abrt) return 1; \ int tempc = (templ >> (count - 1)) & 1; \ templ = (templ >> count) | (regs[reg].l << (32 - count)); \ - seteal(templ); if (abrt) return 0; \ + seteal(templ); if (abrt) return 1; \ setznp32(templ); \ flags_rebuild(); \ if (tempc) flags |= C_FLAG; \ diff --git a/src/x86_ops_stack.h b/src/x86_ops_stack.h index 2586a8b..5986a3c 100644 --- a/src/x86_ops_stack.h +++ b/src/x86_ops_stack.h @@ -3,7 +3,7 @@ { \ PUSH_W(reg); \ cycles -= (is486) ? 1 : 2; \ - return 0; \ + return abrt; \ } #define PUSH_L_OP(reg) \ @@ -11,7 +11,7 @@ { \ PUSH_L(reg); \ cycles -= (is486) ? 1 : 2; \ - return 0; \ + return abrt; \ } #define POP_W_OP(reg) \ @@ -19,7 +19,7 @@ { \ reg = POP_W(); \ cycles -= (is486) ? 1 : 4; \ - return 0; \ + return abrt; \ } #define POP_L_OP(reg) \ @@ -27,7 +27,7 @@ { \ reg = POP_L(); \ cycles -= (is486) ? 1 : 4; \ - return 0; \ + return abrt; \ } PUSH_W_OP(AX) @@ -94,7 +94,7 @@ static int opPUSHA_w(uint32_t fetchdat) if (!abrt) SP -= 16; } cycles -= (is486) ? 11 : 18; - return 0; + return abrt; } static int opPUSHA_l(uint32_t fetchdat) { @@ -123,31 +123,31 @@ static int opPUSHA_l(uint32_t fetchdat) if (!abrt) SP -= 32; } cycles -= (is486) ? 11 : 18; - return 0; + return abrt; } static int opPOPA_w(uint32_t fetchdat) { if (stack32) { - DI = readmemw(ss, ESP); if (abrt) return 0; - SI = readmemw(ss, ESP + 2); if (abrt) return 0; - BP = readmemw(ss, ESP + 4); if (abrt) return 0; - BX = readmemw(ss, ESP + 8); if (abrt) return 0; - DX = readmemw(ss, ESP + 10); if (abrt) return 0; - CX = readmemw(ss, ESP + 12); if (abrt) return 0; - AX = readmemw(ss, ESP + 14); if (abrt) return 0; + DI = readmemw(ss, ESP); if (abrt) return 1; + SI = readmemw(ss, ESP + 2); if (abrt) return 1; + BP = readmemw(ss, ESP + 4); if (abrt) return 1; + BX = readmemw(ss, ESP + 8); if (abrt) return 1; + DX = readmemw(ss, ESP + 10); if (abrt) return 1; + CX = readmemw(ss, ESP + 12); if (abrt) return 1; + AX = readmemw(ss, ESP + 14); if (abrt) return 1; ESP += 16; } else { - DI = readmemw(ss, ((SP) & 0xFFFF)); if (abrt) return 0; - SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (abrt) return 0; - BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (abrt) return 0; - BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (abrt) return 0; - DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (abrt) return 0; - CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (abrt) return 0; - AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (abrt) return 0; + DI = readmemw(ss, ((SP) & 0xFFFF)); if (abrt) return 1; + SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (abrt) return 1; + BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (abrt) return 1; + BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (abrt) return 1; + DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (abrt) return 1; + CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (abrt) return 1; + AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (abrt) return 1; SP += 16; } cycles -= (is486) ? 9 : 24; @@ -157,24 +157,24 @@ static int opPOPA_l(uint32_t fetchdat) { if (stack32) { - EDI = readmeml(ss, ESP); if (abrt) return 0; - ESI = readmeml(ss, ESP + 4); if (abrt) return 0; - EBP = readmeml(ss, ESP + 8); if (abrt) return 0; - EBX = readmeml(ss, ESP + 16); if (abrt) return 0; - EDX = readmeml(ss, ESP + 20); if (abrt) return 0; - ECX = readmeml(ss, ESP + 24); if (abrt) return 0; - EAX = readmeml(ss, ESP + 28); if (abrt) return 0; + EDI = readmeml(ss, ESP); if (abrt) return 1; + ESI = readmeml(ss, ESP + 4); if (abrt) return 1; + EBP = readmeml(ss, ESP + 8); if (abrt) return 1; + EBX = readmeml(ss, ESP + 16); if (abrt) return 1; + EDX = readmeml(ss, ESP + 20); if (abrt) return 1; + ECX = readmeml(ss, ESP + 24); if (abrt) return 1; + EAX = readmeml(ss, ESP + 28); if (abrt) return 1; ESP += 32; } else { - EDI = readmeml(ss, ((SP) & 0xFFFF)); if (abrt) return 0; - ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (abrt) return 0; - EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (abrt) return 0; - EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (abrt) return 0; - EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (abrt) return 0; - ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (abrt) return 0; - EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (abrt) return 0; + EDI = readmeml(ss, ((SP) & 0xFFFF)); if (abrt) return 1; + ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (abrt) return 1; + EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (abrt) return 1; + EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (abrt) return 1; + EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (abrt) return 1; + ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (abrt) return 1; + EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (abrt) return 1; SP += 32; } cycles -= (is486) ? 9 : 24; @@ -186,14 +186,14 @@ static int opPUSH_imm_w(uint32_t fetchdat) uint16_t val = getwordf(); PUSH_W(val); cycles -= 2; - return 0; + return abrt; } static int opPUSH_imm_l(uint32_t fetchdat) { - uint32_t val = getlong(); + uint32_t val = getlong(); if (abrt) return 1; PUSH_L(val); cycles -= 2; - return 0; + return abrt; } static int opPUSH_imm_bw(uint32_t fetchdat) @@ -204,7 +204,7 @@ static int opPUSH_imm_bw(uint32_t fetchdat) PUSH_W(tempw); cycles -= 2; - return 0; + return abrt; } static int opPUSH_imm_bl(uint32_t fetchdat) { @@ -214,14 +214,14 @@ static int opPUSH_imm_bl(uint32_t fetchdat) PUSH_L(templ); cycles -= 2; - return 0; + return abrt; } static int opPOPW_a16(uint32_t fetchdat) { uint16_t temp; - temp = POP_W(); if (abrt) return 0; + temp = POP_W(); if (abrt) return 1; fetch_ea_16(fetchdat); seteaw(temp); @@ -233,13 +233,13 @@ static int opPOPW_a16(uint32_t fetchdat) if (is486) cycles -= ((mod == 3) ? 1 : 6); else cycles -= ((mod == 3) ? 4 : 5); - return 0; + return abrt; } static int opPOPW_a32(uint32_t fetchdat) { uint16_t temp; - temp = POP_W(); if (abrt) return 0; + temp = POP_W(); if (abrt) return 1; fetch_ea_32(fetchdat); seteaw(temp); @@ -251,14 +251,14 @@ static int opPOPW_a32(uint32_t fetchdat) if (is486) cycles -= ((mod == 3) ? 1 : 6); else cycles -= ((mod == 3) ? 4 : 5); - return 0; + return abrt; } static int opPOPL_a16(uint32_t fetchdat) { uint32_t temp; - temp = POP_L(); if (abrt) return 0; + temp = POP_L(); if (abrt) return 1; fetch_ea_16(fetchdat); seteal(temp); @@ -270,13 +270,13 @@ static int opPOPL_a16(uint32_t fetchdat) if (is486) cycles -= ((mod == 3) ? 1 : 6); else cycles -= ((mod == 3) ? 4 : 5); - return 0; + return abrt; } static int opPOPL_a32(uint32_t fetchdat) { uint32_t temp; - temp = POP_L(); if (abrt) return 0; + temp = POP_L(); if (abrt) return 1; fetch_ea_32(fetchdat); seteal(temp); @@ -288,7 +288,7 @@ static int opPOPL_a32(uint32_t fetchdat) if (is486) cycles -= ((mod == 3) ? 1 : 6); else cycles -= ((mod == 3) ? 4 : 5); - return 0; + return abrt; } @@ -298,7 +298,7 @@ static int opENTER_w(uint32_t fetchdat) int count = (fetchdat >> 16) & 0xff; pc++; uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; - PUSH_W(BP); if (abrt) return 0; + PUSH_W(BP); if (abrt) return 1; frame_ptr = ESP; if (count > 0) @@ -309,13 +309,13 @@ static int opENTER_w(uint32_t fetchdat) BP -= 2; tempw = readmemw(ss, BP); - if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } + if (abrt) { ESP = tempESP; EBP = tempEBP; return 1; } PUSH_W(tempw); - if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } + if (abrt) { ESP = tempESP; EBP = tempEBP; return 1; } cycles -= (is486) ? 3 : 4; } PUSH_W(frame_ptr); - if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } + if (abrt) { ESP = tempESP; EBP = tempEBP; return 1; } cycles -= (is486) ? 3 : 5; } BP = frame_ptr; @@ -331,7 +331,7 @@ static int opENTER_l(uint32_t fetchdat) int count = (fetchdat >> 16) & 0xff; pc++; uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; - PUSH_L(EBP); if (abrt) return 0; + PUSH_L(EBP); if (abrt) return 1; frame_ptr = ESP; if (count > 0) @@ -342,13 +342,13 @@ static int opENTER_l(uint32_t fetchdat) EBP -= 4; templ = readmeml(ss, EBP); - if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } + if (abrt) { ESP = tempESP; EBP = tempEBP; return 1; } PUSH_L(templ); - if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } + if (abrt) { ESP = tempESP; EBP = tempEBP; return 1; } cycles -= (is486) ? 3 : 4; } PUSH_L(frame_ptr); - if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } + if (abrt) { ESP = tempESP; EBP = tempEBP; return 1; } cycles -= (is486) ? 3 : 5; } EBP = frame_ptr; @@ -367,7 +367,7 @@ static int opLEAVE_w(uint32_t fetchdat) SP = BP; temp = POP_W(); - if (abrt) { ESP = tempESP; return 0; } + if (abrt) { ESP = tempESP; return 1; } BP = temp; cycles -= 4; @@ -380,7 +380,7 @@ static int opLEAVE_l(uint32_t fetchdat) ESP = EBP; temp = POP_L(); - if (abrt) { ESP = tempESP; return 0; } + if (abrt) { ESP = tempESP; return 1; } EBP = temp; cycles -= 4; @@ -393,13 +393,13 @@ static int opLEAVE_l(uint32_t fetchdat) { \ PUSH_W(seg); \ cycles -= 2; \ - return 0; \ + return abrt; \ } \ static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \ { \ PUSH_L(seg); \ cycles -= 2; \ - return 0; \ + return abrt; \ } #define POP_SEG_OPS(seg, realseg) \ @@ -407,19 +407,19 @@ static int opLEAVE_l(uint32_t fetchdat) { \ uint16_t temp_seg; \ uint32_t temp_esp = ESP; \ - temp_seg = POP_W(); if (abrt) return 0; \ + temp_seg = POP_W(); if (abrt) return 1; \ loadseg(temp_seg, realseg); if (abrt) ESP = temp_esp; \ cycles -= is486 ? 3 : 7; \ - return 0; \ + return abrt; \ } \ static int opPOP_ ## seg ## _l(uint32_t fetchdat) \ { \ uint32_t temp_seg; \ uint32_t temp_esp = ESP; \ - temp_seg = POP_L(); if (abrt) return 0; \ + temp_seg = POP_L(); if (abrt) return 1; \ loadseg(temp_seg & 0xffff, realseg); if (abrt) ESP = temp_esp; \ cycles -= is486 ? 3 : 7; \ - return 0; \ + return abrt; \ } diff --git a/src/x86_ops_string.h b/src/x86_ops_string.h index aacf893..544047c 100644 --- a/src/x86_ops_string.h +++ b/src/x86_ops_string.h @@ -1,7 +1,7 @@ static int opMOVSB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0; - writememb(es, DI, temp); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 1; + writememb(es, DI, temp); if (abrt) return 1; if (flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } cycles -= 7; @@ -9,8 +9,8 @@ static int opMOVSB_a16(uint32_t fetchdat) } static int opMOVSB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0; - writememb(es, EDI, temp); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 1; + writememb(es, EDI, temp); if (abrt) return 1; if (flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } cycles -= 7; @@ -19,8 +19,8 @@ static int opMOVSB_a32(uint32_t fetchdat) static int opMOVSW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0; - writememw(es, DI, temp); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 1; + writememw(es, DI, temp); if (abrt) return 1; if (flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } cycles -= 7; @@ -28,8 +28,8 @@ static int opMOVSW_a16(uint32_t fetchdat) } static int opMOVSW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0; - writememw(es, EDI, temp); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 1; + writememw(es, EDI, temp); if (abrt) return 1; if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } cycles -= 7; @@ -38,8 +38,8 @@ static int opMOVSW_a32(uint32_t fetchdat) static int opMOVSL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0; - writememl(es, DI, temp); if (abrt) return 0; + uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 1; + writememl(es, DI, temp); if (abrt) return 1; if (flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } cycles -= 7; @@ -47,8 +47,8 @@ static int opMOVSL_a16(uint32_t fetchdat) } static int opMOVSL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0; - writememl(es, EDI, temp); if (abrt) return 0; + uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 1; + writememl(es, EDI, temp); if (abrt) return 1; if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } cycles -= 7; @@ -59,7 +59,7 @@ static int opMOVSL_a32(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat) { uint8_t src = readmemb(ea_seg->base, SI); - uint8_t dst = readmemb(es, DI); if (abrt) return 0; + uint8_t dst = readmemb(es, DI); if (abrt) return 1; setsub8(src, dst); if (flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } @@ -69,7 +69,7 @@ static int opCMPSB_a16(uint32_t fetchdat) static int opCMPSB_a32(uint32_t fetchdat) { uint8_t src = readmemb(ea_seg->base, ESI); - uint8_t dst = readmemb(es, EDI); if (abrt) return 0; + uint8_t dst = readmemb(es, EDI); if (abrt) return 1; setsub8(src, dst); if (flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } @@ -80,7 +80,7 @@ static int opCMPSB_a32(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat) { uint16_t src = readmemw(ea_seg->base, SI); - uint16_t dst = readmemw(es, DI); if (abrt) return 0; + uint16_t dst = readmemw(es, DI); if (abrt) return 1; setsub16(src, dst); if (flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } @@ -90,7 +90,7 @@ static int opCMPSW_a16(uint32_t fetchdat) static int opCMPSW_a32(uint32_t fetchdat) { uint16_t src = readmemw(ea_seg->base, ESI); - uint16_t dst = readmemw(es, EDI); if (abrt) return 0; + uint16_t dst = readmemw(es, EDI); if (abrt) return 1; setsub16(src, dst); if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } @@ -101,7 +101,7 @@ static int opCMPSW_a32(uint32_t fetchdat) static int opCMPSL_a16(uint32_t fetchdat) { uint32_t src = readmeml(ea_seg->base, SI); - uint32_t dst = readmeml(es, DI); if (abrt) return 0; + uint32_t dst = readmeml(es, DI); if (abrt) return 1; setsub32(src, dst); if (flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } @@ -111,7 +111,7 @@ static int opCMPSL_a16(uint32_t fetchdat) static int opCMPSL_a32(uint32_t fetchdat) { uint32_t src = readmeml(ea_seg->base, ESI); - uint32_t dst = readmeml(es, EDI); if (abrt) return 0; + uint32_t dst = readmeml(es, EDI); if (abrt) return 1; setsub32(src, dst); if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } @@ -121,7 +121,7 @@ static int opCMPSL_a32(uint32_t fetchdat) static int opSTOSB_a16(uint32_t fetchdat) { - writememb(es, DI, AL); if (abrt) return 0; + writememb(es, DI, AL); if (abrt) return 1; if (flags & D_FLAG) DI--; else DI++; cycles -= 4; @@ -129,7 +129,7 @@ static int opSTOSB_a16(uint32_t fetchdat) } static int opSTOSB_a32(uint32_t fetchdat) { - writememb(es, EDI, AL); if (abrt) return 0; + writememb(es, EDI, AL); if (abrt) return 1; if (flags & D_FLAG) EDI--; else EDI++; cycles -= 4; @@ -138,7 +138,7 @@ static int opSTOSB_a32(uint32_t fetchdat) static int opSTOSW_a16(uint32_t fetchdat) { - writememw(es, DI, AX); if (abrt) return 0; + writememw(es, DI, AX); if (abrt) return 1; if (flags & D_FLAG) DI -= 2; else DI += 2; cycles -= 4; @@ -146,7 +146,7 @@ static int opSTOSW_a16(uint32_t fetchdat) } static int opSTOSW_a32(uint32_t fetchdat) { - writememw(es, EDI, AX); if (abrt) return 0; + writememw(es, EDI, AX); if (abrt) return 1; if (flags & D_FLAG) EDI -= 2; else EDI += 2; cycles -= 4; @@ -155,7 +155,7 @@ static int opSTOSW_a32(uint32_t fetchdat) static int opSTOSL_a16(uint32_t fetchdat) { - writememl(es, DI, EAX); if (abrt) return 0; + writememl(es, DI, EAX); if (abrt) return 1; if (flags & D_FLAG) DI -= 4; else DI += 4; cycles -= 4; @@ -163,7 +163,7 @@ static int opSTOSL_a16(uint32_t fetchdat) } static int opSTOSL_a32(uint32_t fetchdat) { - writememl(es, EDI, EAX); if (abrt) return 0; + writememl(es, EDI, EAX); if (abrt) return 1; if (flags & D_FLAG) EDI -= 4; else EDI += 4; cycles -= 4; @@ -173,7 +173,7 @@ static int opSTOSL_a32(uint32_t fetchdat) static int opLODSB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 1; AL = temp; if (flags & D_FLAG) SI--; else SI++; @@ -182,7 +182,7 @@ static int opLODSB_a16(uint32_t fetchdat) } static int opLODSB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 1; AL = temp; if (flags & D_FLAG) ESI--; else ESI++; @@ -192,7 +192,7 @@ static int opLODSB_a32(uint32_t fetchdat) static int opLODSW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 1; AX = temp; if (flags & D_FLAG) SI -= 2; else SI += 2; @@ -201,7 +201,7 @@ static int opLODSW_a16(uint32_t fetchdat) } static int opLODSW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 1; AX = temp; if (flags & D_FLAG) ESI -= 2; else ESI += 2; @@ -211,7 +211,7 @@ static int opLODSW_a32(uint32_t fetchdat) static int opLODSL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0; + uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 1; EAX = temp; if (flags & D_FLAG) SI -= 4; else SI += 4; @@ -220,7 +220,7 @@ static int opLODSL_a16(uint32_t fetchdat) } static int opLODSL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0; + uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 1; EAX = temp; if (flags & D_FLAG) ESI -= 4; else ESI += 4; @@ -231,7 +231,7 @@ static int opLODSL_a32(uint32_t fetchdat) static int opSCASB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(es, DI); if (abrt) return 0; + uint8_t temp = readmemb(es, DI); if (abrt) return 1; setsub8(AL, temp); if (flags & D_FLAG) DI--; else DI++; @@ -240,7 +240,7 @@ static int opSCASB_a16(uint32_t fetchdat) } static int opSCASB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(es, EDI); if (abrt) return 0; + uint8_t temp = readmemb(es, EDI); if (abrt) return 1; setsub8(AL, temp); if (flags & D_FLAG) EDI--; else EDI++; @@ -250,7 +250,7 @@ static int opSCASB_a32(uint32_t fetchdat) static int opSCASW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(es, DI); if (abrt) return 0; + uint16_t temp = readmemw(es, DI); if (abrt) return 1; setsub16(AX, temp); if (flags & D_FLAG) DI -= 2; else DI += 2; @@ -259,7 +259,7 @@ static int opSCASW_a16(uint32_t fetchdat) } static int opSCASW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(es, EDI); if (abrt) return 0; + uint16_t temp = readmemw(es, EDI); if (abrt) return 1; setsub16(AX, temp); if (flags & D_FLAG) EDI -= 2; else EDI += 2; @@ -269,7 +269,7 @@ static int opSCASW_a32(uint32_t fetchdat) static int opSCASL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(es, DI); if (abrt) return 0; + uint32_t temp = readmeml(es, DI); if (abrt) return 1; setsub32(EAX, temp); if (flags & D_FLAG) DI -= 4; else DI += 4; @@ -278,7 +278,7 @@ static int opSCASL_a16(uint32_t fetchdat) } static int opSCASL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(es, EDI); if (abrt) return 0; + uint32_t temp = readmeml(es, EDI); if (abrt) return 1; setsub32(EAX, temp); if (flags & D_FLAG) EDI -= 4; else EDI += 4; @@ -291,7 +291,7 @@ static int opINSB_a16(uint32_t fetchdat) uint8_t temp; check_io_perm(DX); temp = inb(DX); - writememb(es, DI, temp); if (abrt) return 0; + writememb(es, DI, temp); if (abrt) return 1; if (flags & D_FLAG) DI--; else DI++; cycles -= 15; @@ -302,7 +302,7 @@ static int opINSB_a32(uint32_t fetchdat) uint8_t temp; check_io_perm(DX); temp = inb(DX); - writememb(es, EDI, temp); if (abrt) return 0; + writememb(es, EDI, temp); if (abrt) return 1; if (flags & D_FLAG) EDI--; else EDI++; cycles -= 15; @@ -315,7 +315,7 @@ static int opINSW_a16(uint32_t fetchdat) check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); - writememw(es, DI, temp); if (abrt) return 0; + writememw(es, DI, temp); if (abrt) return 1; if (flags & D_FLAG) DI -= 2; else DI += 2; cycles -= 15; @@ -327,7 +327,7 @@ static int opINSW_a32(uint32_t fetchdat) check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); - writememw(es, EDI, temp); if (abrt) return 0; + writememw(es, EDI, temp); if (abrt) return 1; if (flags & D_FLAG) EDI -= 2; else EDI += 2; cycles -= 15; @@ -342,7 +342,7 @@ static int opINSL_a16(uint32_t fetchdat) check_io_perm(DX + 2); check_io_perm(DX + 3); temp = inl(DX); - writememl(es, DI, temp); if (abrt) return 0; + writememl(es, DI, temp); if (abrt) return 1; if (flags & D_FLAG) DI -= 4; else DI += 4; cycles -= 15; @@ -356,7 +356,7 @@ static int opINSL_a32(uint32_t fetchdat) check_io_perm(DX + 2); check_io_perm(DX + 3); temp = inl(DX); - writememl(es, EDI, temp); if (abrt) return 0; + writememl(es, EDI, temp); if (abrt) return 1; if (flags & D_FLAG) EDI -= 4; else EDI += 4; cycles -= 15; @@ -365,7 +365,7 @@ static int opINSL_a32(uint32_t fetchdat) static int opOUTSB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 1; check_io_perm(DX); if (flags & D_FLAG) SI--; else SI++; @@ -375,7 +375,7 @@ static int opOUTSB_a16(uint32_t fetchdat) } static int opOUTSB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0; + uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 1; check_io_perm(DX); if (flags & D_FLAG) ESI--; else ESI++; @@ -386,7 +386,7 @@ static int opOUTSB_a32(uint32_t fetchdat) static int opOUTSW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); if (flags & D_FLAG) SI -= 2; @@ -397,7 +397,7 @@ static int opOUTSW_a16(uint32_t fetchdat) } static int opOUTSW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0; + uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); if (flags & D_FLAG) ESI -= 2; @@ -409,7 +409,7 @@ static int opOUTSW_a32(uint32_t fetchdat) static int opOUTSL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0; + uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -422,7 +422,7 @@ static int opOUTSL_a16(uint32_t fetchdat) } static int opOUTSL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0; + uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); diff --git a/src/x86_ops_xchg.h b/src/x86_ops_xchg.h index 49174fb..4dd626b 100644 --- a/src/x86_ops_xchg.h +++ b/src/x86_ops_xchg.h @@ -2,8 +2,8 @@ static int opXCHG_b_a16(uint32_t fetchdat) { uint8_t temp; fetch_ea_16(fetchdat); - temp = geteab(); if (abrt) return 0; - seteab(getr8(reg)); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; + seteab(getr8(reg)); if (abrt) return 1; setr8(reg, temp); cycles -= ((mod == 3) ? 3 : 5); return 0; @@ -12,8 +12,8 @@ static int opXCHG_b_a32(uint32_t fetchdat) { uint8_t temp; fetch_ea_32(fetchdat); - temp = geteab(); if (abrt) return 0; - seteab(getr8(reg)); if (abrt) return 0; + temp = geteab(); if (abrt) return 1; + seteab(getr8(reg)); if (abrt) return 1; setr8(reg, temp); cycles -= ((mod == 3) ? 3 : 5); return 0; @@ -23,8 +23,8 @@ static int opXCHG_w_a16(uint32_t fetchdat) { uint16_t temp; fetch_ea_16(fetchdat); - temp = geteaw(); if (abrt) return 0; - seteaw(regs[reg].w); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(regs[reg].w); if (abrt) return 1; regs[reg].w = temp; cycles -= ((mod == 3) ? 3 : 5); return 0; @@ -33,8 +33,8 @@ static int opXCHG_w_a32(uint32_t fetchdat) { uint16_t temp; fetch_ea_32(fetchdat); - temp = geteaw(); if (abrt) return 0; - seteaw(regs[reg].w); if (abrt) return 0; + temp = geteaw(); if (abrt) return 1; + seteaw(regs[reg].w); if (abrt) return 1; regs[reg].w = temp; cycles -= ((mod == 3) ? 3 : 5); return 0; @@ -44,8 +44,8 @@ static int opXCHG_l_a16(uint32_t fetchdat) { uint32_t temp; fetch_ea_16(fetchdat); - temp = geteal(); if (abrt) return 0; - seteal(regs[reg].l); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(regs[reg].l); if (abrt) return 1; regs[reg].l = temp; cycles -= ((mod == 3) ? 3 : 5); return 0; @@ -54,8 +54,8 @@ static int opXCHG_l_a32(uint32_t fetchdat) { uint32_t temp; fetch_ea_32(fetchdat); - temp = geteal(); if (abrt) return 0; - seteal(regs[reg].l); if (abrt) return 0; + temp = geteal(); if (abrt) return 1; + seteal(regs[reg].l); if (abrt) return 1; regs[reg].l = temp; cycles -= ((mod == 3) ? 3 : 5); return 0; diff --git a/src/x87.c b/src/x87.c index 87391d9..e10dfd7 100644 --- a/src/x87.c +++ b/src/x87.c @@ -260,7 +260,7 @@ void x87_stmmx(MMX_REG r) writememw(easeg, eaaddr + 8, 0xffff); } -void x87_d8() +void x87_d8(uint32_t fetchdat) { union { @@ -269,59 +269,59 @@ void x87_d8() } ts; if (mod==3) { - switch (rmdat32&0xFF) + switch (fetchdat&0xFF) { case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADD*/ case 0xC4: case 0xC5: case 0xC6: case 0xC7: if (fplog) pclog("FADD\n"); - ST(0)=ST(0)+ST(rmdat32&7); + ST(0)=ST(0)+ST(fetchdat&7); cycles-=8; return; case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMUL*/ case 0xCC: case 0xCD: case 0xCE: case 0xCF: if (fplog) pclog("FMUL\n"); - ST(0)=ST(0)*ST(rmdat32&7); + ST(0)=ST(0)*ST(fetchdat&7); cycles-=16; return; case 0xD0: case 0xD1: case 0xD2: case 0xD3: /*FCOM*/ case 0xD4: case 0xD5: case 0xD6: case 0xD7: if (fplog) pclog("FCOM\n"); npxs&=~(C0|C2|C3); - if (ST(0)==ST(rmdat32&7)) npxs|=C3; - else if (ST(0)> ((TOP & 7) << 1)) & 3; - tag &= ~(3 << (((TOP + rmdat32) & 7) << 1)); - tag |= (temp << (((TOP + rmdat32) & 7) << 1)); + tag &= ~(3 << (((TOP + fetchdat) & 7) << 1)); + tag |= (temp << (((TOP + fetchdat) & 7) << 1)); x87_pop(); cycles-=3; return; @@ -588,7 +589,7 @@ void x87_d9() { case 0: /*FLD single-precision*/ if (fplog) pclog("FLDs %08X:%08X\n", easeg, eaaddr); -// if ((rmdat32&0xFFFF)==0xD445) { pclog("FLDS\n"); output=3; dumpregs(); exit(-1); } +// if ((fetchdat&0xFFFF)==0xD445) { pclog("FLDS\n"); output=3; dumpregs(); exit(-1); } ts.i=geteal(); if (abrt) { pclog("FLD sp abort\n"); return; } if (fplog) pclog(" %f\n", ts.s); x87_push((double)ts.s); @@ -687,15 +688,15 @@ void x87_d9() return; } } -// fatal("Bad x87 D9 opcode %i %02X\n",reg,rmdat32&0xFF); +// fatal("Bad x87 D9 opcode %i %02X\n",reg,fetchdat&0xFF); x86illegal(); } -void x87_da() +void x87_da(uint32_t fetchdat) { int32_t templ; if (mod==3) { - switch (rmdat32&0xFF) + switch (fetchdat&0xFF) { case 0xE9: /*FUCOMPP*/ if (fplog) pclog("FUCOMPP\n", easeg, eaaddr); @@ -760,10 +761,10 @@ void x87_da() return; } } -// fatal("Bad x87 DA opcode %i %02X\n",reg,rmdat32&0xFF); +// fatal("Bad x87 DA opcode %i %02X\n",reg,fetchdat&0xFF); x86illegal(); } -void x87_db() +void x87_db(uint32_t fetchdat) { double t; int32_t templ; @@ -773,7 +774,7 @@ void x87_db() switch (reg) { case 4: - switch (rmdat32&0xFF) + switch (fetchdat&0xFF) { case 0xE1: return; @@ -839,10 +840,10 @@ void x87_db() return; } } -// fatal("Bad x87 DB opcode %i %02X\n",reg,rmdat32&0xFF); +// fatal("Bad x87 DB opcode %i %02X\n",reg,fetchdat&0xFF); x86illegal(); } -void x87_dc() +void x87_dc(uint32_t fetchdat) { union { @@ -851,42 +852,42 @@ void x87_dc() } t; if (mod==3) { - switch (rmdat32&0xFF) + switch (fetchdat&0xFF) { case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADD*/ case 0xC4: case 0xC5: case 0xC6: case 0xC7: - if (fplog) pclog("FADD %f %f\n", ST(rmdat32 & 7), ST(0)); - ST(rmdat32&7)=ST(rmdat32&7)+ST(0); + if (fplog) pclog("FADD %f %f\n", ST(fetchdat & 7), ST(0)); + ST(fetchdat&7)=ST(fetchdat&7)+ST(0); cycles-=8; return; case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMUL*/ case 0xCC: case 0xCD: case 0xCE: case 0xCF: - if (fplog) pclog("FMUL %f %f\n", ST(rmdat32 & 7), ST(0)); - ST(rmdat32&7)=ST(rmdat32&7)*ST(0); + if (fplog) pclog("FMUL %f %f\n", ST(fetchdat & 7), ST(0)); + ST(fetchdat&7)=ST(fetchdat&7)*ST(0); cycles-=16; return; case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUBR*/ case 0xE4: case 0xE5: case 0xE6: case 0xE7: - if (fplog) pclog("FSUBR %f %f\n", ST(rmdat32 & 7), ST(0)); - ST(rmdat32&7)=ST(0)-ST(rmdat32&7); + if (fplog) pclog("FSUBR %f %f\n", ST(fetchdat & 7), ST(0)); + ST(fetchdat&7)=ST(0)-ST(fetchdat&7); cycles-=8; return; case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUB*/ case 0xEC: case 0xED: case 0xEE: case 0xEF: - if (fplog) pclog("FSUB %f %f\n", ST(rmdat32 & 7), ST(0)); - ST(rmdat32&7)=ST(rmdat32&7)-ST(0); + if (fplog) pclog("FSUB %f %f\n", ST(fetchdat & 7), ST(0)); + ST(fetchdat&7)=ST(fetchdat&7)-ST(0); cycles-=8; return; case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIVR*/ case 0xF4: case 0xF5: case 0xF6: case 0xF7: - if (fplog) pclog("FDIVR %f %f\n", ST(rmdat32 & 7), ST(0)); - x87_div(ST(rmdat32&7), ST(0), ST(rmdat32&7)); + if (fplog) pclog("FDIVR %f %f\n", ST(fetchdat & 7), ST(0)); + x87_div(ST(fetchdat&7), ST(0), ST(fetchdat&7)); cycles-=73; return; case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIV*/ case 0xFC: case 0xFD: case 0xFE: case 0xFF: - if (fplog) pclog("FDIV %f %f\n", ST(rmdat32 & 7), ST(0)); - x87_div(ST(rmdat32&7), ST(rmdat32&7), ST(0)); + if (fplog) pclog("FDIV %f %f\n", ST(fetchdat & 7), ST(0)); + x87_div(ST(fetchdat&7), ST(fetchdat&7), ST(0)); cycles-=73; return; } @@ -945,10 +946,10 @@ void x87_dc() return; } } -// fatal("Bad x87 DC opcode %i %02X\n",reg,rmdat32&0xFF); +// fatal("Bad x87 DC opcode %i %02X\n",reg,fetchdat&0xFF); x86illegal(); } -void x87_dd() +void x87_dd(uint32_t fetchdat) { union { @@ -962,38 +963,38 @@ void x87_dd() { case 0: /*FFREE*/ if (fplog) pclog("FFREE\n"); - tag |= (3 << (((TOP + rmdat32) & 7) << 1)); + tag |= (3 << (((TOP + fetchdat) & 7) << 1)); cycles-=3; return; case 2: /*FST*/ if (fplog) pclog("FST\n"); - ST(rmdat32 & 7) = ST(0); + ST(fetchdat & 7) = ST(0); temp = (tag >> ((TOP & 7) << 1)) & 3; - tag &= ~(3 << (((TOP + rmdat32) & 7) << 1)); - tag |= (temp << (((TOP + rmdat32) & 7) << 1)); + tag &= ~(3 << (((TOP + fetchdat) & 7) << 1)); + tag |= (temp << (((TOP + fetchdat) & 7) << 1)); cycles-=3; return; case 3: /*FSTP*/ if (fplog) pclog("FSTP\n"); - ST(rmdat32 & 7) = ST(0); + ST(fetchdat & 7) = ST(0); temp = (tag >> ((TOP & 7) << 1)) & 3; - tag &= ~(3 << (((TOP + rmdat32) & 7) << 1)); - tag |= (temp << (((TOP + rmdat32) & 7) << 1)); + tag &= ~(3 << (((TOP + fetchdat) & 7) << 1)); + tag |= (temp << (((TOP + fetchdat) & 7) << 1)); x87_pop(); cycles-=3; return; case 4: /*FUCOM*/ if (fplog) pclog("FUCOM\n"); npxs&=~(C0|C2|C3); - if (ST(0)==ST(rmdat32&7)) npxs|=C3; - else if (ST(0)