Added the IBM 5161 ISA expansion for PC and XT;

Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port;
Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX);
Finished the 586MC1;
Added 8087 emulation;
Moved Cyrix 6x86'es to the Dev branch;
Sanitized/cleaned up memregs.c/h and intel.c/h;
Split the chipsets from machines and sanitized Port 92 emulation;
Added support for the 15bpp mode to the Compaq ATI 28800;
Moved the MR 386DX and 486 machines to the Dev branch;
Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00;
Ported the new timer code from PCem;
Cleaned up the CPU table of unused stuff and better optimized its structure;
Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch;
Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem;
Added the AHA-1540A and the BusTek BT-542B;
Moved the Sumo SCSI-AT to the Dev branch;
Minor IDE, FDC, and floppy drive code clean-ups;
Made NCR 5380/53C400-based cards' BIOS address configurable;
Got rid of the legacy romset variable;
Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit;
Added the Amstead PPC512 per PCem patch by John Elliott;
Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages);
Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing;
Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem;
Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit;
Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement;
Amstrad MegaPC does now works correctly with non-internal graphics card;
The SLiRP code no longer casts a packed struct type to a non-packed struct type;
The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present;
The S3 Virge on BeOS is no longer broken (was broken by build #1591);
OS/2 2.0 build 6.167 now sees key presses again;
Xi8088 now work on CGA again;
86F images converted from either the old or new variants of the HxC MFM format now work correctly;
Hardware interrupts with a vector of 0xFF are now handled correctly;
OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct;
Fixed VNC keyboard input bugs;
Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g  / 81 MIDI play no longer hangs with the build's own VTD driver;
Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly;
Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4;
Compaq Portable now works with all graphics cards;
Fixed various MDSI Genius bugs;
Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly;
Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355;
OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400.
Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391.
Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389.
Fixed a minor IDE timing bug, fixes #388.
Fixed Toshiba T1000 RAM issues, fixes #379.
Fixed EGA/(S)VGA overscan border handling, fixes #378;
Got rid of the now long useless IDE channel 2 auto-removal, fixes #370;
Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366;
Ported the Unicode CD image file name fix from VARCem, fixes #365;
Fixed high density floppy disks on the Xi8088, fixes #359;
Fixed some bugs in the Hercules emulation, fixes #346, fixes #358;
Fixed the SCSI hard disk mode sense pages, fixes #356;
Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349;
Fixed bugs in the serial mouse emulation, fixes #344;
Compiled 86Box binaries now include all the required .DLL's, fixes #341;
Made some combo boxes in the Settings dialog slightly wider, fixes #276.
This commit is contained in:
OBattler
2019-09-20 14:02:30 +02:00
parent b06296bbf6
commit 552a87ea3d
524 changed files with 129555 additions and 21862 deletions

View File

@@ -11,13 +11,13 @@
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "../timer.h"
#include "x86.h"
#include "x87.h"
#include "../nmi.h"
#include "../mem.h"
#include "../pic.h"
#include "../pit.h"
#include "../timer.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "386_common.h"
@@ -29,12 +29,11 @@ extern int codegen_flags_changed;
int cpl_override = 0, fpucount = 0;
int tempc, oldcpl, optype, inttype, oddeven = 0;
int use32, stack32;
int stack32, timetolive;
uint16_t flags, eflags;
uint16_t rds, ea_rseg;
uint16_t oldcs;
uint32_t use32;
uint32_t oldds, oldss, olddslimit, oldsslimit,
olddslimitw, oldsslimitw;
uint32_t *eal_r, *eal_w;
@@ -44,11 +43,9 @@ uint32_t rmdat32;
uint32_t backupregs[16];
x86seg gdt,ldt,idt,tr;
x86seg _cs,_ds,_es,_ss,_fs,_gs;
x86seg _oldds;
#define rmdat rmdat32
#define fetchdat rmdat32
uint32_t rmdat;
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; }
#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0
@@ -68,7 +65,7 @@ uint32_t testr[9];
extern int dontprint;
#undef NOTRM
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
{ \
x86_int(6); \
return 0; \
@@ -82,7 +79,7 @@ extern int dontprint;
#include "x86_ops.h"
#undef NOTRM
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
{ \
x86_int(6); \
break; \
@@ -111,49 +108,46 @@ x386_log(const char *fmt, ...)
void exec386(int cycs)
{
uint8_t temp;
int vector, tempi, cycdiff, oldcyc;
int ins_cycles;
uint32_t addr;
int tempi;
int cycdiff;
int oldcyc;
cycles+=cycs;
/* output=3; */
while (cycles>0)
{
int cycle_period = (timer_count >> TIMER_SHIFT) + 1;
int cycle_period = (timer_target - (uint32_t)tsc) + 1;
x86_was_reset = 0;
cycdiff=0;
oldcyc=cycles;
timer_start_period(cycles << TIMER_SHIFT);
while (cycdiff < cycle_period)
{
ins_cycles = cycles;
oldcs=CS;
cpu_state.oldpc = cpu_state.pc;
oldcpl=CPL;
oldcpl=CPL;
cpu_state.op32 = use32;
x86_was_reset = 0;
dontprint=0;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl(cs + cpu_state.pc);
if (!cpu_state.abrt)
{
trap = flags & T_FLAG;
{
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
fetchdat >>= 8;
trap = cpu_state.flags & T_FLAG;
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset)
break;
if(x86_was_reset) break;
if(x86_was_reset)
break;
}
if (!use32) cpu_state.pc &= 0xffff;
@@ -180,6 +174,10 @@ dontprint=0;
}
}
}
ins_cycles -= cycles;
tsc += ins_cycles;
cycdiff=oldcyc-cycles;
if (trap)
@@ -193,13 +191,13 @@ dontprint=0;
}
else
{
writememw(ss,(SP-2)&0xFFFF,flags);
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
SP-=6;
addr = (1 << 2) + idt.base;
flags&=~I_FLAG;
flags&=~T_FLAG;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
@@ -216,26 +214,26 @@ dontprint=0;
nmi = 0;
}
}
else if ((flags&I_FLAG) && pic_intpending)
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
{
temp=picinterrupt();
if (temp!=0xFF)
vector = picinterrupt();
if (vector != -1)
{
flags_rebuild();
if (msw&1)
{
pmodeint(temp,0);
pmodeint(vector,0);
}
else
{
writememw(ss,(SP-2)&0xFFFF,flags);
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
SP-=6;
addr = (temp << 2) + idt.base;
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=cpu_state.pc;
addr = (vector << 2) + idt.base;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
oxpc = cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
@@ -252,8 +250,7 @@ dontprint=0;
}
}
tsc += cycdiff;
timer_end_period(cycles << TIMER_SHIFT);
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
timer_process();
}
}

View File

@@ -1,5 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
extern void cpu_386_flags_extract();
extern void cpu_386_flags_rebuild();

View File

@@ -8,16 +8,14 @@
*
* Common 386 CPU code.
*
* Version: @(#)386_common.h 1.0.0 2017/05/30
* Version: @(#)386_common.h 1.0.1 2019/02/19
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
extern uint16_t ea_rseg;
#undef readmemb
#undef writememb
@@ -32,7 +30,7 @@ extern uint16_t ea_rseg;
#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \
#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \
{ \
int tempi = checkio(port); \
if (cpu_state.abrt) return 1; \
@@ -43,46 +41,88 @@ extern uint16_t ea_rseg;
} \
}
#define checkio_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \
{ \
tempi = checkio(port); \
if (cpu_state.abrt) break; \
if (tempi) \
{ \
x86gpf("checkio_perm(): no permission",0); \
break; \
} \
}
#define SEG_CHECK_READ(seg) \
do \
{ \
if ((seg)->base == 0xffffffff) \
{ \
x86gpf("Segment can't read", 0);\
return 1; \
} \
} while (0)
#define SEG_CHECK_WRITE(seg) \
do \
{ \
if ((seg)->base == 0xffffffff) \
{ \
x86gpf("Segment can't write", 0);\
return 1; \
} \
} while (0)
#define CHECK_READ(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
{ \
x86gpf("Limit check (READ)", 0); \
return 1; \
} \
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &_ss) \
if ((chseg) == &cpu_state.seg_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
return 1; \
}
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 0); \
(void) mmutranslatereal((chseg)->base + high, 0); \
if (cpu_state.abrt) \
return 1; \
}
#define CHECK_READ_REP(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
{ \
x86gpf("Limit check (READ)", 0); \
break; \
} \
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &cpu_state.seg_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
break; \
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 0); \
(void) mmutranslatereal((chseg)->base + high, 0); \
if (cpu_state.abrt) \
break; \
}
#define CHECK_WRITE(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((chseg)->access & 8))) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \
{ \
x86gpf("Limit check (WRITE)", 0); \
return 1; \
} \
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &_ss) \
if ((chseg) == &cpu_state.seg_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
return 1; \
}
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 1); \
(void) mmutranslatereal((chseg)->base + high, 1); \
if (cpu_state.abrt) \
return 1; \
}
#define CHECK_WRITE_REP(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
@@ -90,17 +130,23 @@ extern uint16_t ea_rseg;
x86gpf("Limit check (WRITE REP)", 0); \
break; \
} \
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &_ss) \
if ((chseg) == &cpu_state.seg_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
break; \
}
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 1); \
(void) mmutranslatereal((chseg)->base + high, 1); \
if (cpu_state.abrt) \
break; \
}
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
{ \
x86_int(6); \
return 1; \
@@ -165,6 +211,17 @@ static __inline uint32_t fastreadl(uint32_t a)
return val;
}
static __inline void *get_ram_ptr(uint32_t a)
{
if ((a >> 12) == pccache)
return &pccache2[a];
else
{
uint8_t *t = getpccache(a);
return &t[a];
}
}
static __inline uint8_t getbyte()
{
cpu_state.pc++;
@@ -204,7 +261,6 @@ static __inline uint16_t geteaw()
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].w;
/* cycles-=3; */
if (eal_r)
return *(uint16_t *)eal_r;
return readmemw(easeg, cpu_state.eaaddr);
@@ -214,7 +270,6 @@ static __inline uint32_t geteal()
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].l;
/* cycles-=3; */
if (eal_r)
return *eal_r;
return readmeml(easeg, cpu_state.eaaddr);
@@ -246,10 +301,11 @@ static __inline void seteaq(uint64_t v)
writememql(easeg, cpu_state.eaaddr, v);
}
#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
#define seteaw(v) if (cpu_mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v
#define seteal(v) if (cpu_mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v
#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else { writememb386l(easeg,cpu_state.eaaddr,v); } } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else { writememwl(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].w=v
#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else { writememll(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].l=v
#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v);
#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v);
#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v);
@@ -258,9 +314,3 @@ static __inline void seteaq(uint64_t v)
#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2
#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++
#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2
#define rmdat rmdat32
#define fetchdat rmdat32
void x86_int(int num);

View File

@@ -40,7 +40,7 @@ int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latch
#ifdef ENABLE_386_DYNAREC_LOG
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;#endif
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
void
@@ -63,7 +63,6 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (cpu_rm == 4)
{
uint8_t sib = rmdat >> 8;
@@ -89,8 +88,7 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
else if ((sib & 6) == 4 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
cpu_state.ea_seg = &cpu_state.seg_ss;
}
if (((sib >> 3) & 7) != 4)
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
@@ -103,8 +101,7 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
if (cpu_rm == 5 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
cpu_state.ea_seg = &cpu_state.seg_ss;
}
if (cpu_mod == 1)
{
@@ -136,7 +133,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (!cpu_mod && cpu_rm == 6)
{
cpu_state.eaaddr = getword();
@@ -159,8 +155,7 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
cpu_state.ea_seg = &cpu_state.seg_ss;
}
cpu_state.eaaddr &= 0xFFFF;
}
@@ -211,22 +206,22 @@ void x86_int(int num)
{
if (stack32)
{
writememw(ss,ESP-2,flags);
writememw(ss,ESP-2,cpu_state.flags);
writememw(ss,ESP-4,CS);
writememw(ss,ESP-6,cpu_state.pc);
ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
SP-=6;
}
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
@@ -256,22 +251,22 @@ void x86_int_sw(int num)
{
if (stack32)
{
writememw(ss,ESP-2,flags);
writememw(ss,ESP-2,cpu_state.flags);
writememw(ss,ESP-4,CS);
writememw(ss,ESP-6,cpu_state.pc);
ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
SP-=6;
}
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
cycles -= timing_int_rm;
@@ -295,7 +290,7 @@ int x86_int_sw_rm(int num)
if (cpu_state.abrt) return 1;
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
if (cpu_state.abrt) {
#ifdef ENABLE_386_DYNAREC_LOG
x386_dynarec_log("abrt5\n");
@@ -312,11 +307,11 @@ int x86_int_sw_rm(int num)
}
SP-=6;
eflags &= ~VIF_FLAG;
flags &= ~T_FLAG;
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags &= ~T_FLAG;
cpu_state.pc = new_pc;
loadcs(new_cs);
oxpc=cpu_state.pc;
oxpc=cpu_state.pc;
cycles -= timing_int_rm;
trap = 0;
@@ -400,6 +395,8 @@ static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int
}
prefetch_prefixes = 0;
if (prefetch_bytes > 16)
prefetch_bytes = 16;
}
static void prefetch_flush()
@@ -509,14 +506,14 @@ int dontprint=0;
#include "386_ops.h"
#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG))
#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(cpu_state.flags & T_FLAG))
#ifdef USE_DYNAREC
static int cycles_main = 0;
void exec386_dynarec(int cycs)
{
uint8_t temp;
int vector;
uint32_t addr;
int tempi;
int cycdiff;
@@ -533,7 +530,6 @@ void exec386_dynarec(int cycs)
cycles += cyc_period;
cycles_start = cycles;
timer_start_period(cycles << TIMER_SHIFT);
while (cycles>0)
{
oldcs = CS;
@@ -552,18 +548,18 @@ void exec386_dynarec(int cycs)
{
oldcs=CS;
cpu_state.oldpc = cpu_state.pc;
oldcpl=CPL;
oldcpl = CPL;
cpu_state.op32 = use32;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl(cs + cpu_state.pc);
if (!cpu_state.abrt)
{
trap = flags & T_FLAG;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
trap = cpu_state.flags & T_FLAG;
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
@@ -602,7 +598,7 @@ void exec386_dynarec(int cycs)
int hash = HASH(phys_addr);
codeblock_t *block = codeblock_hash[hash];
int valid_block = 0;
trap = 0;
trap = 0;
if (block && !cpu_state.abrt)
{
@@ -699,18 +695,18 @@ inrecomp=0;
{
oldcs=CS;
cpu_state.oldpc = cpu_state.pc;
oldcpl=CPL;
oldcpl = CPL;
cpu_state.op32 = use32;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl(cs + cpu_state.pc);
if (!cpu_state.abrt)
{
trap = flags & T_FLAG;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
{
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
trap = cpu_state.flags & T_FLAG;
cpu_state.pc++;
@@ -769,20 +765,20 @@ inrecomp=0;
{
oldcs=CS;
cpu_state.oldpc = cpu_state.pc;
oldcpl=CPL;
oldcpl = CPL;
cpu_state.op32 = use32;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
codegen_endpc = (cs + cpu_state.pc) + 8;
fetchdat = fastreadl(cs + cpu_state.pc);
if (!cpu_state.abrt)
{
trap = flags & T_FLAG;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
{
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
trap = cpu_state.flags & T_FLAG;
cpu_state.pc++;
@@ -857,7 +853,6 @@ inrecomp=0;
if (trap)
{
flags_rebuild();
if (msw&1)
{
@@ -865,13 +860,13 @@ inrecomp=0;
}
else
{
writememw(ss,(SP-2)&0xFFFF,flags);
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
SP-=6;
addr = (1 << 2) + idt.base;
flags&=~I_FLAG;
flags&=~T_FLAG;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
@@ -888,35 +883,37 @@ inrecomp=0;
nmi = 0;
}
}
else if ((flags&I_FLAG) && pic_intpending)
else if ((cpu_state.flags&I_FLAG) && pic_intpending)
{
temp=picinterrupt();
if (temp!=0xFF)
vector=picinterrupt();
if (vector!=-1)
{
CPU_BLOCK_END();
flags_rebuild();
if (msw&1)
{
pmodeint(temp,0);
pmodeint(vector,0);
}
else
{
writememw(ss,(SP-2)&0xFFFF,flags);
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
SP-=6;
addr=temp<<2;
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=cpu_state.pc;
addr=vector<<2;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
}
}
}
timer_end_period(cycles << TIMER_SHIFT);
cycles_main -= (cycles_start - cycles);
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
timer_process();
cycles_main -= (cycles_start - cycles);
}
}
#endif

View File

@@ -24,14 +24,10 @@
#include "386_common.h"
extern uint16_t *mod1add[2][8];
extern uint32_t *mod1seg[8];
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
@@ -47,7 +43,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;

View File

@@ -910,6 +910,7 @@ const OpFn OP_TABLE(k6_0f)[1024] =
};
#endif
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
const OpFn OP_TABLE(c6x86mx_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
@@ -1000,6 +1001,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] =
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
/*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,
};
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686

File diff suppressed because it is too large Load Diff

View File

@@ -5,12 +5,12 @@ static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
CLEAR_BITS((uintptr_t)&flags, D_FLAG);
CLEAR_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
return op_pc;
}
static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
SET_BITS((uintptr_t)&flags, D_FLAG);
SET_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
return op_pc;
}
@@ -18,14 +18,14 @@ static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
{
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
return 0;
CLEAR_BITS((uintptr_t)&flags, I_FLAG);
CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
return op_pc;
}
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
return 0;
SET_BITS((uintptr_t)&flags, I_FLAG);
SET_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
return op_pc;
}
@@ -152,7 +152,7 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(op_pc + 1);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-2);
host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp);
@@ -168,7 +168,7 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
host_reg = LOAD_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-2);
return op_pc + 1;
}
@@ -245,7 +245,7 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(op_pc + 1);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-4);
host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp);
@@ -261,7 +261,7 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
host_reg = LOAD_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-4);
return op_pc + 1;
}

View File

@@ -588,16 +588,16 @@ static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
switch (fetchdat & 0x38)
{
case 0x00: /*ES*/
LOAD_SEG(host_reg, &_es);
LOAD_SEG(host_reg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
LOAD_SEG(host_reg, &_ds);
LOAD_SEG(host_reg, &cpu_state.seg_ds);
break;
case 0x20: /*FS*/
LOAD_SEG(host_reg, &_fs);
LOAD_SEG(host_reg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
LOAD_SEG(host_reg, &_gs);
LOAD_SEG(host_reg, &cpu_state.seg_gs);
break;
}
@@ -644,13 +644,13 @@ static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \
} \
\
if (&rseg == &_ss) \
if (&rseg == &cpu_state.seg_ss) \
CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \
return op_pc + 1; \
}
ropLseg(DS, _ds)
ropLseg(ES, _es)
ropLseg(FS, _fs)
ropLseg(GS, _gs)
ropLseg(SS, _ss)
ropLseg(DS, cpu_state.seg_ds)
ropLseg(ES, cpu_state.seg_es)
ropLseg(FS, cpu_state.seg_fs)
ropLseg(GS, cpu_state.seg_gs)
ropLseg(SS, cpu_state.seg_ss)

View File

@@ -5,7 +5,7 @@ static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ui
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_W(opcode & 7);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-2);
return op_pc;
@@ -17,7 +17,7 @@ static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ui
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_L(opcode & 7);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-4);
return op_pc;
@@ -31,7 +31,7 @@ static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-2);
return op_pc+2;
@@ -44,7 +44,7 @@ static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-4);
return op_pc+4;
@@ -61,7 +61,7 @@ static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_3
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-2);
return op_pc+1;
@@ -77,7 +77,7 @@ static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_3
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-4);
return op_pc+1;
@@ -87,7 +87,7 @@ static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
SP_MODIFY(2);
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
@@ -97,7 +97,7 @@ static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
SP_MODIFY(4);
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
@@ -108,7 +108,7 @@ static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(2);
@@ -118,7 +118,7 @@ static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(4);
@@ -131,7 +131,7 @@ static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(2+offset);
@@ -143,7 +143,7 @@ static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(4+offset);
@@ -158,7 +158,7 @@ static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(op_pc+2);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-2);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
@@ -172,7 +172,7 @@ static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(op_pc+4);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
SP_MODIFY(-4);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
@@ -185,7 +185,7 @@ static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_EBP_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
ADD_HOST_REG_IMM_W(host_reg, 2);
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
@@ -199,7 +199,7 @@ static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_EBP_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
ADD_HOST_REG_IMM(host_reg, 4);
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
@@ -216,7 +216,7 @@ static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-2); \
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
MEM_STORE_ADDR_EA_W(&_ss, host_reg); \
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
SP_MODIFY(-2); \
\
return op_pc; \
@@ -228,7 +228,7 @@ static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-4); \
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
MEM_STORE_ADDR_EA_L(&_ss, host_reg); \
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
SP_MODIFY(-4); \
\
return op_pc; \
@@ -246,7 +246,7 @@ static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_
{ \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&_ss); \
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(2); \
\
@@ -256,14 +256,14 @@ static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_
{ \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&_ss); \
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(4); \
\
return op_pc; \
}
ROP_POP_SEG(DS, _ds)
ROP_POP_SEG(ES, _es)
ROP_POP_SEG(FS, _fs)
ROP_POP_SEG(GS, _gs)
ROP_POP_SEG(DS, cpu_state.seg_ds)
ROP_POP_SEG(ES, cpu_state.seg_es)
ROP_POP_SEG(FS, cpu_state.seg_fs)
ROP_POP_SEG(GS, cpu_state.seg_gs)

View File

@@ -647,7 +647,7 @@ static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u
}
if (mod1seg[rm] == &ss && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
}
return op_ea_seg;
}
@@ -796,7 +796,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u
addlong(stack_offset);
}
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
}
else
{
@@ -814,7 +814,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u
if (mod)
{
if (rm == 5 && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
if (mod == 1)
{
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
@@ -857,14 +857,14 @@ static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_sseg
static inline void CHECK_SEG_READ(x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (eflags & VM_FLAG))
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
return;
/*CS and SS must always be valid*/
if (seg == &_cs || seg == &_ss)
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
return;
if (seg->checked)
return;
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
return;
if (IS_32_ADDR(&seg->base))
@@ -893,14 +893,14 @@ static inline void CHECK_SEG_READ(x86seg *seg)
static inline void CHECK_SEG_WRITE(x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (eflags & VM_FLAG))
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
return;
/*CS and SS must always be valid*/
if (seg == &_cs || seg == &_ss)
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
return;
if (seg->checked)
return;
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
return;
if (IS_32_ADDR(&seg->base))
@@ -928,7 +928,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
}
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
return;
if (IS_32_ADDR(&seg->base))
@@ -967,7 +967,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1040,7 +1040,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1126,7 +1126,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
}
static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1204,7 +1204,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1325,7 +1325,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
addbyte(8);
host_reg = 8;
}
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1409,7 +1409,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1500,7 +1500,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -1589,7 +1589,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -5270,7 +5270,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
CHECK_SEG_WRITE(seg);
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -5321,7 +5321,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
addbyte(0xc1); /*SHR EDI, 12*/
addbyte(0xef);
addbyte(12);
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
@@ -5352,7 +5352,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
jump2 = &codeblock[block_current].data[block_pos];
addbyte(0);
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
*jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
/*slowpath:*/
addbyte(0x67); /*LEA EDI, [EAX+ESI]*/
@@ -5385,7 +5385,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
CHECK_SEG_WRITE(seg);
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -5433,7 +5433,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
addbyte(0x79); /*JNS +*/
jump1 = &codeblock[block_current].data[block_pos];
addbyte(0);
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
@@ -5442,7 +5442,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
addbyte(0x8d); /*LEA ESI, 1[EDI]*/
addbyte(0x77);
addbyte(0x01);
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x74); /*JE slowpath*/
jump4 = &codeblock[block_current].data[block_pos];
@@ -5498,7 +5498,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
/*slowpath:*/
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
jump_pos = block_pos;
load_param_1_reg_32(REG_EBX);
@@ -5534,7 +5534,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
CHECK_SEG_WRITE(seg);
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -5582,7 +5582,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
addbyte(0x79); /*JNS +*/
jump1 = &codeblock[block_current].data[block_pos];
addbyte(0);
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
@@ -5591,7 +5591,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
addbyte(0x8d); /*LEA ESI, 3[EDI]*/
addbyte(0x77);
addbyte(0x03);
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x74); /*JE slowpath*/
jump4 = &codeblock[block_current].data[block_pos];
@@ -5647,7 +5647,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
/*slowpath:*/
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
jump_pos = block_pos;
load_param_1_reg_32(REG_EBX);
@@ -5678,7 +5678,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -5750,7 +5750,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
}
static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -5828,7 +5828,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
}
static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
@@ -5928,7 +5928,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
addbyte(8);
host_reg = 8;
}
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EBX, EBX*/
addbyte(0xdb);
@@ -6005,7 +6005,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EBX, EBX*/
addbyte(0xdb);
@@ -6089,7 +6089,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EBX, EBX*/
addbyte(0xdb);

View File

@@ -611,14 +611,14 @@ static inline void SAR_L_IMM(int reg, int count)
static inline void CHECK_SEG_READ(x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (eflags & VM_FLAG))
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
return;
/*CS and SS must always be valid*/
if (seg == &_cs || seg == &_ss)
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
return;
if (seg->checked)
return;
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
return;
addbyte(0x83); /*CMP seg->base, -1*/
@@ -634,14 +634,14 @@ static inline void CHECK_SEG_READ(x86seg *seg)
static inline void CHECK_SEG_WRITE(x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (eflags & VM_FLAG))
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
return;
/*CS and SS must always be valid*/
if (seg == &_cs || seg == &_ss)
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
return;
if (seg->checked)
return;
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
return;
addbyte(0x83); /*CMP seg->base, -1*/
@@ -656,7 +656,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
}
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
return;
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
@@ -684,7 +684,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -702,7 +702,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
}
static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -722,7 +722,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -740,7 +740,7 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -761,7 +761,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
}
static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -781,7 +781,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -800,7 +800,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
}
static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -821,7 +821,7 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
@@ -859,7 +859,7 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr)
static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -880,7 +880,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -901,7 +901,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -922,7 +922,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -943,7 +943,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -964,7 +964,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
}
static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
{
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -995,7 +995,7 @@ static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
addbyte(0x89); /*MOV ECX, host_reg2*/
addbyte(0xc0 | REG_ECX | (host_reg2 << 3));
}
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -1087,7 +1087,7 @@ static inline x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_s
addlong(0xffff);
if (mod1seg[rm] == &ss && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
}
return op_ea_seg;
}
@@ -1154,7 +1154,7 @@ static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_s
}
}
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
if (((sib >> 3) & 7) != 4)
{
switch (sib >> 6)
@@ -1199,7 +1199,7 @@ static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_s
if (mod)
{
if (rm == 5 && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
if (mod == 1)
{
addbyte(0x83); /*ADD EAX, imm8*/
@@ -3919,7 +3919,7 @@ static inline void LOAD_EA()
static inline void MEM_CHECK_WRITE(x86seg *seg)
{
CHECK_SEG_WRITE(seg);
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -3937,7 +3937,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
static inline void MEM_CHECK_WRITE_W(x86seg *seg)
{
CHECK_SEG_WRITE(seg);
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
@@ -3955,7 +3955,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
static inline void MEM_CHECK_WRITE_L(x86seg *seg)
{
CHECK_SEG_WRITE(seg);
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);

View File

@@ -817,7 +817,7 @@ static inline int COUNT(uint64_t timings, uint64_t deps, int op_32)
case CYCLES_RMW:
return 3;
case CYCLES_BRANCH:
return cpu_hasMMX ? 1 : 2;
return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2;
}
fatal("Illegal COUNT %016llx\n", timings);
@@ -950,13 +950,13 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat)
last_prefix = prefix;
return;
}
if (cpu_hasMMX && prefix == 0x0f)
if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f)
{
/*On Pentium MMX 0fh prefix is 'free'*/
last_prefix = prefix;
return;
}
if (cpu_hasMMX && (prefix == 0x66 || prefix == 0x67))
if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67))
{
/*On Pentium MMX 66h and 67h prefixes take 2 clocks*/
decode_delay_offset += 2;
@@ -1223,7 +1223,7 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
else
has_displacement = 0;
if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
{
int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK;
int t2 = timings[opcode] & CYCLES_MASK;
@@ -1276,7 +1276,7 @@ nopair:
else
has_displacement = 0;
if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
{
/*Instruction might pair with next*/
u_pipe_full = 1;

View File

@@ -376,7 +376,7 @@ void codegen_block_start_recompile(codeblock_t *block)
codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] =
codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0;
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1;
codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] =
codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0;
@@ -692,7 +692,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat,
addbyte((uint8_t)cpu_state_offset(eaaddr));
if (mod1seg[cpu_rm] == &ss && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
}
return op_ea_seg;
}
@@ -840,7 +840,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
addlong(stack_offset);
}
if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
addbyte(0x89); /*MOV eaaddr, EAX*/
addbyte(0x45);
@@ -864,7 +864,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
if (cpu_mod)
{
if (cpu_rm == 5 && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
if (cpu_mod == 1)
{
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
@@ -913,7 +913,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
int test_modrm = 1;
int c;
op_ea_seg = &_ds;
op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 0;
op_old_pc = old_pc;
@@ -935,27 +935,27 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
break;
case 0x26: /*ES:*/
op_ea_seg = &_es;
op_ea_seg = &cpu_state.seg_es;
op_ssegs = 1;
break;
case 0x2e: /*CS:*/
op_ea_seg = &_cs;
op_ea_seg = &cpu_state.seg_cs;
op_ssegs = 1;
break;
case 0x36: /*SS:*/
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
op_ssegs = 1;
break;
case 0x3e: /*DS:*/
op_ea_seg = &_ds;
op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 1;
break;
case 0x64: /*FS:*/
op_ea_seg = &_fs;
op_ea_seg = &cpu_state.seg_fs;
op_ssegs = 1;
break;
case 0x65: /*GS:*/
op_ea_seg = &_gs;
op_ea_seg = &cpu_state.seg_gs;
op_ssegs = 1;
break;

View File

@@ -1495,7 +1495,7 @@ void codegen_block_start_recompile(codeblock_t *block)
codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] =
codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0;
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1;
block->TOP = cpu_state.TOP;
block->was_recompiled = 1;
@@ -1735,7 +1735,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat,
addlong((uint32_t)&cpu_state.eaaddr);
if (mod1seg[cpu_rm] == &ss && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
}
return op_ea_seg;
}
@@ -1791,7 +1791,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
addlong(stack_offset);
}
if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
if (((sib >> 3) & 7) != 4)
{
switch (sib >> 6)
@@ -1840,7 +1840,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
if (cpu_mod)
{
if (cpu_rm == 5 && !op_ssegs)
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
if (cpu_mod == 1)
{
addbyte(0x05);
@@ -1875,7 +1875,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
int test_modrm = 1;
int c;
op_ea_seg = &_ds;
op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 0;
op_old_pc = old_pc;
@@ -1898,27 +1898,27 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
break;
case 0x26: /*ES:*/
op_ea_seg = &_es;
op_ea_seg = &cpu_state.seg_es;
op_ssegs = 1;
break;
case 0x2e: /*CS:*/
op_ea_seg = &_cs;
op_ea_seg = &cpu_state.seg_cs;
op_ssegs = 1;
break;
case 0x36: /*SS:*/
op_ea_seg = &_ss;
op_ea_seg = &cpu_state.seg_ss;
op_ssegs = 1;
break;
case 0x3e: /*DS:*/
op_ea_seg = &_ds;
op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 1;
break;
case 0x64: /*FS:*/
op_ea_seg = &_fs;
op_ea_seg = &cpu_state.seg_fs;
op_ssegs = 1;
break;
case 0x65: /*GS:*/
op_ea_seg = &_gs;
op_ea_seg = &cpu_state.seg_gs;
op_ssegs = 1;
break;
@@ -2131,7 +2131,7 @@ generate_call:
if (op_ea_seg != last_ea_seg)
{
last_ea_seg = op_ea_seg;
addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/
addbyte(0xC7); /*MOVL $&cpu_state.seg_ds,(ea_seg)*/
addbyte(0x45);
addbyte((uint8_t)cpu_state_offset(ea_seg));
addlong((uint32_t)op_ea_seg);

View File

@@ -49,12 +49,20 @@
#include "../io.h"
#include "x86_ops.h"
#include "../mem.h"
#include "../nmi.h"
#include "../pic.h"
#include "../pci.h"
#ifdef USE_DYNAREC
# include "codegen.h"
#endif
#if 1
static void cpu_write(uint16_t addr, uint8_t val, void *priv);
static uint8_t cpu_read(uint16_t addr, void *priv);
#endif
enum {
CPUID_FPU = (1 << 0),
CPUID_VME = (1 << 1),
@@ -120,7 +128,6 @@ int cpu_multi;
int cpu_16bitbus;
int cpu_busspeed;
int cpu_cyrix_alignment;
int cpuspeed;
int CPUID;
uint64_t cpu_CR4_mask;
int isa_cycles;
@@ -130,7 +137,9 @@ int cpu_prefetch_cycles, cpu_prefetch_width,
cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed;
int cpu_pci_speed, cpu_alt_reset;
uint32_t cpu_features;
int is286,
is386,
@@ -139,12 +148,7 @@ int is286,
israpidcad,
is_pentium;
int hasfpu,
cpu_hasrdtsc,
cpu_hasMMX,
cpu_hasMSR,
cpu_hasCR4,
cpu_hasVME;
int hasfpu;
uint64_t tsc = 0;
@@ -205,6 +209,11 @@ int timing_misaligned;
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
int cpu_has_feature(int feature)
{
return cpu_features & feature;
}
void
cpu_dynamic_switch(int new_cpu)
@@ -236,36 +245,40 @@ cpu_set(void)
cpu_manufacturer = 0;
cpu = 0;
}
cpu_effective = cpu;
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
cpu_alt_reset = 0;
CPUID = cpu_s->cpuid_model;
cpuspeed = cpu_s->speed;
is8086 = (cpu_s->cpu_type > CPU_8088);
is286 = (cpu_s->cpu_type >= CPU_286);
is386 = (cpu_s->cpu_type >= CPU_386SX);
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD);
is_pentium= (cpu_s->cpu_type >= CPU_WINCHIP);
is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP);
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1);
#else
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86);
#endif
cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC);
if (cpu_s->multi)
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
if (cpu_s->multi) {
if (cpu_s->pci_speed)
cpu_busspeed = cpu_s->pci_speed;
else
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
}
cpu_multi = cpu_s->multi;
cpu_hasrdtsc = 0;
cpu_hasMMX = 0;
cpu_hasMSR = 0;
cpu_hasCR4 = 0;
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0;
if ((cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || (cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX))
{
if (enable_external_fpu)
{
hasfpu = 1;
}
if ((cpu_s->cpu_type == CPU_8088) || (cpu_s->cpu_type == CPU_8086) ||
(cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) ||
(cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX)) {
hasfpu = !!enable_external_fpu;
}
cpu_update_waitstates();
@@ -289,10 +302,15 @@ cpu_set(void)
}
if (cpu_iscyrix)
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
else
io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
io_removehandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
if (hasfpu)
io_sethandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
else
io_removehandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
#else
@@ -636,8 +654,7 @@ cpu_set(void)
break;
case CPU_iDX4:
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME;
case CPU_i486SX:
case CPU_i486DX:
@@ -807,10 +824,8 @@ cpu_set(void)
timing_mml = 3;
timing_bt = 3-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
/*unknown*/
timing_int_rm = 26;
@@ -873,12 +888,8 @@ cpu_set(void)
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_pentium);
@@ -920,18 +931,15 @@ cpu_set(void)
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_pentium);
#endif
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
case CPU_Cx6x86:
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
@@ -967,11 +975,8 @@ cpu_set(void)
timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
cpu_hasMSR = 0;
cpu_hasCR4 = 0;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
#endif
@@ -1013,11 +1018,8 @@ cpu_set(void)
timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
cpu_hasMSR = 0;
cpu_hasCR4 = 0;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
#endif
@@ -1042,11 +1044,8 @@ cpu_set(void)
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
@@ -1101,17 +1100,15 @@ cpu_set(void)
timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
#endif
ccr4 = 0x80;
break;
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
@@ -1131,11 +1128,8 @@ cpu_set(void)
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
break;
@@ -1155,12 +1149,8 @@ cpu_set(void)
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_pentium);
@@ -1197,12 +1187,8 @@ cpu_set(void)
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
@@ -1238,12 +1224,8 @@ cpu_set(void)
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
@@ -1279,12 +1261,8 @@ cpu_set(void)
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_hasVME = 1;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
@@ -1410,7 +1388,7 @@ cpu_CPUID(void)
EAX = 0x540;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
if (msr.fcr & (1 << 1))
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 9))
EDX |= CPUID_MMX;
@@ -1590,6 +1568,7 @@ cpu_CPUID(void)
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
case CPU_Cx6x86:
if (!EAX)
{
@@ -1665,6 +1644,7 @@ cpu_CPUID(void)
else
EAX = EBX = ECX = EDX = 0;
break;
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
@@ -1820,6 +1800,7 @@ void cpu_RDMSR()
break;
}
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -1832,6 +1813,7 @@ void cpu_RDMSR()
break;
}
break;
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
@@ -1953,6 +1935,7 @@ void cpu_RDMSR()
break;
default:
i686_invalid_rdmsr:
pclog("Invalid MSR read %08X\n", ECX);
x86gpf(NULL, 0);
break;
}
@@ -1983,11 +1966,18 @@ void cpu_WRMSR()
break;
case 0x107:
msr.fcr = EAX;
cpu_hasMMX = EAX & (1 << 9);
if (EAX & (1 << 29))
CPUID = 0;
if (EAX & (1 << 9))
cpu_features |= CPU_FEATURE_MMX;
else
CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model;
cpu_features &= ~CPU_FEATURE_MMX;
if (EAX & (1 << 1))
cpu_features |= CPU_FEATURE_CX8;
else
cpu_features &= ~CPU_FEATURE_CX8;
if (EAX & (1 << 29))
CPUID = 0;
else
CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
break;
case 0x108:
msr.fcr2 = EAX | ((uint64_t)EDX << 32);
@@ -2032,6 +2022,7 @@ void cpu_WRMSR()
break;
}
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -2043,6 +2034,7 @@ void cpu_WRMSR()
break;
}
break;
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
@@ -2132,6 +2124,7 @@ void cpu_WRMSR()
break;
default:
i686_invalid_wrmsr:
pclog("Invalid MSR write %08X: %08X%08X\n", ECX, EDX, EAX);
x86gpf(NULL, 0);
break;
}
@@ -2143,8 +2136,18 @@ i686_invalid_wrmsr:
static int cyrix_addr;
void cyrix_write(uint16_t addr, uint8_t val, void *priv)
static void cpu_write(uint16_t addr, uint8_t val, void *priv)
{
if (addr == 0xf0) {
/* Writes to F0 clear FPU error and deassert the interrupt. */
if (is286)
picintc(1 << 13);
else
nmi = 0;
return;
} else if (addr >= 0xf1)
return; /* FPU stuff */
if (!(addr & 1))
cyrix_addr = val;
else switch (cyrix_addr)
@@ -2165,6 +2168,7 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
if ((ccr3 & 0xf0) == 0x10)
{
ccr4 = val;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86)
{
if (val & 0x80)
@@ -2172,6 +2176,7 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
else
CPUID = 0;
}
#endif
}
break;
case 0xe9: /*CCR5*/
@@ -2185,8 +2190,11 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
}
}
uint8_t cyrix_read(uint16_t addr, void *priv)
static uint8_t cpu_read(uint16_t addr, void *priv)
{
if (addr >= 0xf0)
return 0xff; /* FPU stuff */
if (addr & 1)
{
switch (cyrix_addr)

View File

@@ -18,6 +18,10 @@
* Copyright 2016-2018 leilei.
* Copyright 2016,2018 Miran Grca.
*/
#ifdef USE_NEW_DYNAREC
#include "../cpu_new/cpu.h"
#else
#ifndef EMU_CPU_H
# define EMU_CPU_H
@@ -77,17 +81,16 @@
typedef struct {
const char *name;
int cpu_type;
int speed;
int rspeed;
int multi;
int pci_speed;
uint32_t edx_reset;
uint32_t cpuid_model;
uint16_t cyrix_id;
int cpu_flags;
int mem_read_cycles, mem_write_cycles;
int cache_read_cycles, cache_write_cycles;
int atclk_div;
uint8_t cpu_flags;
int8_t mem_read_cycles, mem_write_cycles;
int8_t cache_read_cycles, cache_write_cycles;
int8_t atclk_div;
} CPU;
extern CPU cpus_8088[];
@@ -143,9 +146,9 @@ extern CPU cpus_Pentium2D[];
#define CR4_PVI (1 << 1)
#define CR4_PSE (1 << 4)
#define CPL ((_cs.access>>5)&3)
#define CPL ((cpu_state.seg_cs.access>>5)&3)
#define IOPL ((flags>>12)&3)
#define IOPL ((cpu_state.flags>>12)&3)
#define IOPLp ((!(msw&1)) || (CPL<=IOPL))
@@ -240,9 +243,18 @@ struct _cpustate_ {
uint16_t old_npxc,
new_npxc;
uint32_t last_ea;
x86seg seg_cs,
seg_ds,
seg_es,
seg_ss,
seg_fs,
seg_gs;
uint16_t flags, eflags;
} cpu_state;
/*The flags below must match in both cpu_cur_status and block->status for a block
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
to be valid*/
#define CPU_STATUS_USE32 (1 << 0)
#define CPU_STATUS_STACK32 (1 << 1)
@@ -250,7 +262,7 @@ struct _cpustate_ {
#define CPU_STATUS_V86 (1 << 3)
#define CPU_STATUS_FLAGS 0xffff
/*If the flags below are set in cpu_cur_status, they must be set in block->status.
/*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status.
Otherwise they are ignored*/
#define CPU_STATUS_NOTFLATDS (1 << 16)
#define CPU_STATUS_NOTFLATSS (1 << 17)
@@ -319,18 +331,20 @@ extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
extern int is8086, is286, is386, is486;
extern int is_rapidcad;
extern int hasfpu;
extern int cpu_hasrdtsc;
extern int cpu_hasMSR;
extern int cpu_hasMMX;
extern int cpu_hasCR4;
extern int cpu_hasVME;
#define CPU_FEATURE_RDTSC (1 << 0)
#define CPU_FEATURE_MSR (1 << 1)
#define CPU_FEATURE_MMX (1 << 2)
#define CPU_FEATURE_CR4 (1 << 3)
#define CPU_FEATURE_VME (1 << 4)
#define CPU_FEATURE_CX8 (1 << 5)
#define CPU_FEATURE_3DNOW (1 << 6)
extern uint32_t cpu_features;
extern uint32_t cpu_cur_status;
extern uint64_t cpu_CR4_mask;
extern uint64_t tsc;
extern msr_t msr;
extern int cpuspeed;
extern int cycles_lost;
extern uint8_t opcode;
extern int insc;
extern int fpucount;
@@ -339,16 +353,14 @@ extern int clockrate;
extern int cgate16;
extern int cpl_override;
extern int CPUID;
extern int xt_cpu_multi;
extern uint64_t xt_cpu_multi;
extern int isa_cycles;
extern uint16_t flags,eflags;
extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
extern int ins,output;
extern int cycdiff;
extern uint32_t pccache;
extern uint8_t *pccache2;
extern float isa_timing, bus_timing;
extern double bus_timing;
extern uint64_t pmc[2];
extern uint16_t temp_seg_data[4];
extern uint16_t cs_msr;
@@ -372,24 +384,22 @@ extern uint32_t dr[8];
CS,DS,ES,SS is the 16-bit data
cs,ds,es,ss are defines to the bases*/
extern x86seg gdt,ldt,idt,tr;
extern x86seg _cs,_ds,_es,_ss,_fs,_gs;
extern x86seg _oldds;
#define CS _cs.seg
#define DS _ds.seg
#define ES _es.seg
#define SS _ss.seg
#define FS _fs.seg
#define GS _gs.seg
#define cs _cs.base
#define ds _ds.base
#define es _es.base
#define ss _ss.base
#define seg_fs _fs.base
#define gs _gs.base
#define CS cpu_state.seg_cs.seg
#define DS cpu_state.seg_ds.seg
#define ES cpu_state.seg_es.seg
#define SS cpu_state.seg_ss.seg
#define FS cpu_state.seg_fs.seg
#define GS cpu_state.seg_gs.seg
#define cs cpu_state.seg_cs.base
#define ds cpu_state.seg_ds.base
#define es cpu_state.seg_es.base
#define ss cpu_state.seg_ss.base
#define fs_seg cpu_state.seg_fs.base
#define gs cpu_state.seg_gs.base
#define ISA_CYCLES_SHIFT 6
#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT)
#define ISA_CYCLES(x) (x * isa_cycles)
extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
@@ -424,8 +434,8 @@ extern CPU cpus_acer[]; // FIXME: should be in machine file!
/* Functions. */
extern void cyrix_write(uint16_t addr, uint8_t val, void *priv);
extern uint8_t cyrix_read(uint16_t addr, void *priv);
extern int cpu_has_feature(int feature);
extern void loadseg(uint16_t seg, x86seg *s);
extern void loadcs(uint16_t seg);
@@ -448,7 +458,7 @@ extern void exec386(int cycs);
extern void exec386_dynarec(int cycs);
extern int idivl(int32_t val);
extern void loadcscall(uint16_t seg);
extern void loadcsjmp(uint16_t seg, uint32_t oxpc);
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
extern void pmodeint(int num, int soft);
extern void pmoderetf(int is32, uint16_t off);
extern void pmodeiret(int is32);
@@ -457,6 +467,7 @@ extern void resetx86(void);
extern void refreshread(void);
extern void resetreadlookup(void);
extern void softresetx86(void);
extern void x86_int(int num);
extern void x86_int_sw(int num);
extern int x86_int_sw_rm(int num);
extern void x86gpf(char *s, uint16_t error);
@@ -470,8 +481,9 @@ extern void x87_dumpregs(void);
extern void x87_reset(void);
#endif
extern int cpu_effective;
extern int cpu_effective, cpu_alt_reset;
extern void cpu_dynamic_switch(int new_cpu);
#endif /*EMU_CPU_H*/
#endif

View File

@@ -52,371 +52,370 @@
CPU cpus_8088[] = {
/*8088 standard*/
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/10", CPU_8088, 1, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/12", CPU_8088, 1, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/16", CPU_8088, 1, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_pcjr[] = {
/*8088 PCjr*/
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_europc[] = {
/*8088 EuroPC*/
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8088/9.54", CPU_8088, 1, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_8086[] = {
/*8086 standard*/
{"8086/7.16", CPU_8086, 1, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8086/9.54", CPU_8086, 1, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
{"8086/10", CPU_8086, 10000000, 2, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8086/12", CPU_8086, 12000000, 3, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"8086/16", CPU_8086, 16000000, 4, 0, 0, 0, 0, 0, 0,0,0,0, 2},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_pc1512[] = {
/*8086 Amstrad*/
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_286[] = {
/*286*/
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/12", CPU_286, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_ibmat[] = {
/*286*/
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
{"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
{"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_ibmxt286[] = {
/*286*/
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_ps1_m2011[] = {
/*286*/
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9}
};
CPU cpus_ps2_m30_286[] = {
/*286*/
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
{"286/12", CPU_286, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
{"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_i386SX[] = {
/*i386SX*/
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
{"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"i386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
{"i386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"i386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"i386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
{"i386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_i386DX[] = {
/*i386DX*/
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
{"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
{"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3, 3},
{"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3, 4},
{"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"i386DX/16", CPU_386DX, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
{"i386DX/20", CPU_386DX, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
{"i386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
{"i386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
{"i386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
{"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, 0, 4,4,3,3, 3},
{"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, 0, 6,6,3,3, 4},
{"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
#if 0
CPU cpus_acer[] = {
/*i386SX*/
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
};
#endif
CPU cpus_Am386SX[] = {
/*Am386*/
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
{"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Am386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
{"Am386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"Am386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
{"Am386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
{"Am386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_Am386DX[] = {
/*Am386*/
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Am386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
{"Am386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
{"Am386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_486SLC[] = {
/*Cx486SLC*/
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
{"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
{"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
{"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
{"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
{"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
};
CPU cpus_486DLC[] = {
/*Cx486DLC*/
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 4},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 6},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 6},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3},
{"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4},
{"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5},
{"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4},
{"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
{"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
{"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
};
CPU cpus_i486[] = {
/*i486*/
{"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2},
{"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
{"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 8},
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6},
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
{"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/
{"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
{"i486SX/20", CPU_i486SX, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
{"i486SX/25", CPU_i486SX, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
{"i486SX/33", CPU_i486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
{"i486SX2/50", CPU_i486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
{"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
{"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
{"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
{"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
{"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
{"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
{"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
{"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/
{"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
{"Pentium OverDrive/63", CPU_PENTIUM, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
{"Pentium OverDrive/83", CPU_PENTIUM, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
};
CPU cpus_Am486[] = {
/*Am486/5x86*/
{"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
{"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
{"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
{"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
{"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
{"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
{"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
{"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
{"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 10},
{"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9},
{"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
{"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
{"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 15},
{"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
{"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
{"Am486SX/40", CPU_Am486SX, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
{"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
{"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
{"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
{"Am486DX/40", CPU_Am486DX, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
{"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
{"Am486DX2/66", CPU_Am486DX, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
{"Am486DX2/80", CPU_Am486DX, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
{"Am486DX4/75", CPU_Am486DX, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
{"Am486DX4/90", CPU_Am486DX, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
{"Am486DX4/100", CPU_Am486DX, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
{"Am486DX4/120", CPU_Am486DX, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
{"Am5x86/P75", CPU_Am486DX, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
{"Am5x86/P75+", CPU_Am486DX, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
CPU cpus_Cx486[] = {
/*Cx486/5x86*/
{"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
{"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
{"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
{"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
{"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
{"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
{"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
{"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 10},
{"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9},
{"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
{"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
{"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 15},
{"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Cx486S/25", CPU_Cx486S, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
{"Cx486S/33", CPU_Cx486S, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
{"Cx486S/40", CPU_Cx486S, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
{"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
{"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
{"Cx486DX2/50", CPU_Cx486DX, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
{"Cx486DX2/66", CPU_Cx486DX, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
{"Cx486DX2/80", CPU_Cx486DX, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 10},
{"Cx486DX4/75", CPU_Cx486DX, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
{"Cx486DX4/100", CPU_Cx486DX, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
{"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
{"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
{"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
#ifdef DEV_BRANCH
#ifdef USE_CYRIX_6X86
CPU cpus_6x86[] = {
/*Cyrix 6x86*/
{"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 10},
{"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
{"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 14},
{"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 18},
{"6x86-P90", CPU_Cx6x86, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
{"6x86-PR120+", CPU_Cx6x86, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
{"6x86-PR133+", CPU_Cx6x86, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
{"6x86-PR150+", CPU_Cx6x86, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
{"6x86-PR166+", CPU_Cx6x86, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
{"6x86-PR200+", CPU_Cx6x86, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
/*Cyrix 6x86L*/
{"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 14},
{"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 18},
{"6x86L-PR133+", CPU_Cx6x86L, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
{"6x86L-PR150+", CPU_Cx6x86L, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
{"6x86L-PR166+", CPU_Cx6x86L, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
{"6x86L-PR200+", CPU_Cx6x86L, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
/*Cyrix 6x86MX*/
{"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 45/2},
{"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, 25},
{"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, 28},
{"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 30},
{"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 30},
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 33},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"6x86MX-PR166", CPU_Cx6x86MX, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
{"6x86MX-PR200", CPU_Cx6x86MX, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"6x86MX-PR233", CPU_Cx6x86MX, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
{"6x86MX-PR266", CPU_Cx6x86MX, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
{"6x86MX-PR300", CPU_Cx6x86MX, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 7, 7, 28},
{"6x86MX-PR333", CPU_Cx6x86MX, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20, 9, 9, 30},
{"6x86MX-PR366", CPU_Cx6x86MX, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 30},
{"6x86MX-PR400", CPU_Cx6x86MX, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 33},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
#endif
#endif
CPU cpus_WinChip[] = {
/*IDT WinChip*/
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 9},
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, 21/2},
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, 12},
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 14},
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 16},
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, 35/2},
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, 40},
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 21},
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24},
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 27},
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"WinChip 75", CPU_WINCHIP, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
{"WinChip 90", CPU_WINCHIP, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
{"WinChip 100", CPU_WINCHIP, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
{"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 14},
{"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 16},
{"WinChip 150", CPU_WINCHIP, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15, 7, 7, 35/2},
{"WinChip 166", CPU_WINCHIP, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15, 7, 7, 40},
{"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 21},
{"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 24},
{"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 27},
{"WinChip 240", CPU_WINCHIP, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
CPU cpus_Pentium5V[] = {
/*Intel Pentium (5V, socket 4)*/
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
{"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
{"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
};
CPU cpus_Pentium5V50[] = {
/*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/
{"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6},
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
{"Pentium OverDrive 100",CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 12},
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6},
{"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
{"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
{"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12},
{"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
};
CPU cpus_PentiumS5[] = {
/*Intel Pentium (Socket 5)*/
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16},
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40},
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Pentium 75", CPU_PENTIUM, 75000000, 2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
{"Pentium 90", CPU_PENTIUM, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
{"Pentium 100/66", CPU_PENTIUM, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16},
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40},
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
};
CPU cpus_Pentium[] = {
/*Intel Pentium*/
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Pentium 75", CPU_PENTIUM, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"Pentium 90", CPU_PENTIUM, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
{"Pentium 100/66", CPU_PENTIUM, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
{"Pentium 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
{"Pentium 150", CPU_PENTIUM, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
{"Pentium 166", CPU_PENTIUM, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
CPU cpus_K5[] = {
/*AMD K5 (Socket 5)*/
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
};
CPU cpus_K56[] = {
/*AMD K5 and K6 (Socket 7)*/
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"K6 (Model 6) 166", CPU_K6, 19, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"K6 (Model 6) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"K6 (Model 6) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"K6 (Model 7) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"K6 (Model 7) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"K6 (Model 7) 266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
{"K6 (Model 7) 300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"K6 (Model 6) 166", CPU_K6, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"K6 (Model 6) 233", CPU_K6, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"K6 (Model 7) 233", CPU_K6, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
{"K6 (Model 7) 300", CPU_K6, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
#endif
#endif
@@ -425,27 +424,28 @@ CPU cpus_K56[] = {
#ifdef USE_I686
CPU cpus_PentiumPro[] = {
/*Intel Pentium Pro and II Overdrive*/
{"Pentium Pro 50", CPU_PENTIUMPRO, 5, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6},
{"Pentium Pro 60" , CPU_PENTIUMPRO, 6, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
{"Pentium Pro 66" , CPU_PENTIUMPRO, 6, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
{"Pentium Pro 75", CPU_PENTIUMPRO, 9, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"Pentium Pro 150", CPU_PENTIUMPRO, 17, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
{"Pentium Pro 166", CPU_PENTIUMPRO, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
{"Pentium Pro 180", CPU_PENTIUMPRO, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
{"Pentium Pro 200", CPU_PENTIUMPRO, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 5, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6},
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 6, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 6, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 9, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 22, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, 25},
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 24, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,1, 28},
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 25, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29},
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 26, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 27, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33},
{"Pentium II Overdrive 300/66",CPU_PENTIUM2D, 28, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
{"Pentium II Overdrive 300/60",CPU_PENTIUM2D, 28, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 29, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
{"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
{"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
{"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
{"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
{"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
{"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
{"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29},
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33},
{"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
{"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
{"Pentium II 75", CPU_PENTIUM2D, 75000000, 2, 25000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
#endif
#endif

View File

@@ -1,28 +1,33 @@
#ifdef USE_NEW_DYNAREC
#include "../cpu_new/x86.h"
#else
extern uint8_t opcode, opcode2;
extern uint8_t flags_p;
extern uint8_t znptable8[256];
extern uint16_t zero, oldcs;
extern uint16_t lastcs, lastpc;
extern uint16_t rds, ea_rseg;
extern uint16_t znptable16[65536];
extern uint16_t *mod1add[2][8];
extern uint16_t znptable16[65536];
extern int x86_was_reset, codegen_flat_ds;
extern int codegen_flat_ss, nmi_enable;
extern int x86_was_reset, trap;
extern int codegen_flat_ss, codegen_flat_ds;
extern int timetolive, keyboardtimer, trap;
extern int tempc, optype, use32, stack32;
extern int optype, stack32;
extern int oldcpl, cgate32, cpl_override, fpucount;
extern int gpf, nmi_enable;
extern int nmi_enable;
extern int oddeven, inttype;
extern uint32_t rmdat32, easeg;
extern uint32_t use32;
extern uint32_t rmdat, easeg;
extern uint32_t oxpc, flags_zn;
extern uint32_t abrt_error;
extern uint32_t backupregs[16];
extern uint32_t *mod1seg[8];
extern uint32_t *eal_r, *eal_w;
#define fetchdat rmdat
#define setznp168 setznp16
@@ -50,10 +55,6 @@ extern uint32_t *eal_r, *eal_w;
#define IRET 3
#define OPTYPE_INT 4
#define FLAG_N (flags_zn>>31)
#define FLAG_Z (flags_zn)
#define FLAG_P (znptable8[flags_p]&P_FLAG)
enum
{
@@ -71,3 +72,4 @@ extern void x86_doabrt(int x86_abrt);
extern void x86illegal();
extern void x86seg_reset();
extern void x86gpf(char *s, uint16_t error);
#endif

View File

@@ -1,6 +1,8 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
extern int tempc;
enum
{
FLAGS_UNKNOWN,
@@ -69,7 +71,7 @@ static __inline int ZF_SET()
return !cpu_state.flags_res;
case FLAGS_UNKNOWN:
return flags & Z_FLAG;
return cpu_state.flags & Z_FLAG;
default:
return 0;
@@ -111,7 +113,7 @@ static __inline int NF_SET()
return cpu_state.flags_res & 0x80000000;
case FLAGS_UNKNOWN:
return flags & N_FLAG;
return cpu_state.flags & N_FLAG;
default:
return 0;
@@ -149,7 +151,7 @@ static __inline int PF_SET()
return znptable8[cpu_state.flags_res & 0xff] & P_FLAG;
case FLAGS_UNKNOWN:
return flags & P_FLAG;
return cpu_state.flags & P_FLAG;
default:
return 0;
@@ -171,20 +173,20 @@ static __inline int VF_SET()
case FLAGS_ADD8:
case FLAGS_INC8:
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
case FLAGS_ADD16:
case FLAGS_ADD16:
case FLAGS_INC16:
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
case FLAGS_ADD32:
case FLAGS_ADD32:
case FLAGS_INC32:
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
case FLAGS_SUB8:
case FLAGS_DEC8:
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
case FLAGS_SUB16:
case FLAGS_SUB16:
case FLAGS_DEC16:
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
case FLAGS_SUB32:
case FLAGS_SUB32:
case FLAGS_DEC32:
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
@@ -203,7 +205,7 @@ static __inline int VF_SET()
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000));
case FLAGS_UNKNOWN:
return flags & V_FLAG;
return cpu_state.flags & V_FLAG;
default:
return 0;
@@ -243,9 +245,9 @@ static __inline int AF_SET()
case FLAGS_DEC16:
case FLAGS_DEC32:
return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10;
case FLAGS_UNKNOWN:
return flags & A_FLAG;
return cpu_state.flags & A_FLAG;
default:
return 0;
@@ -267,7 +269,7 @@ static __inline int CF_SET()
case FLAGS_SUB16:
case FLAGS_SUB32:
return (cpu_state.flags_op1 < cpu_state.flags_op2);
case FLAGS_SHL8:
return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80;
case FLAGS_SHL16:
@@ -299,7 +301,7 @@ static __inline int CF_SET()
case FLAGS_INC16:
case FLAGS_INC32:
case FLAGS_UNKNOWN:
return flags & C_FLAG;
return cpu_state.flags & C_FLAG;
default:
return 0;
@@ -317,7 +319,7 @@ static __inline void flags_rebuild()
if (ZF_SET()) tempf |= Z_FLAG;
if (NF_SET()) tempf |= N_FLAG;
if (VF_SET()) tempf |= V_FLAG;
flags = (flags & ~0x8d5) | tempf;
cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf;
cpu_state.flags_op = FLAGS_UNKNOWN;
}
}
@@ -332,9 +334,9 @@ static __inline void flags_rebuild_c()
if (cpu_state.flags_op != FLAGS_UNKNOWN)
{
if (CF_SET())
flags |= C_FLAG;
cpu_state.flags |= C_FLAG;
else
flags &= ~C_FLAG;
cpu_state.flags &= ~C_FLAG;
}
}
@@ -457,65 +459,68 @@ static __inline void setadc8(uint8_t a, uint8_t b)
{
uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
cpu_state.flags_op = FLAGS_UNKNOWN;
flags&=~0x8D5;
flags|=znptable8[c&0xFF];
if (c&0x100) flags|=C_FLAG;
if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
cpu_state.flags&=~0x8D5;
cpu_state.flags|=znptable8[c&0xFF];
if (c&0x100) cpu_state.flags|=C_FLAG;
if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG;
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
}
static __inline void setadc16(uint16_t a, uint16_t b)
{
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
cpu_state.flags_op = FLAGS_UNKNOWN;
flags&=~0x8D5;
flags|=znptable16[c&0xFFFF];
if (c&0x10000) flags|=C_FLAG;
if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
cpu_state.flags&=~0x8D5;
cpu_state.flags|=znptable16[c&0xFFFF];
if (c&0x10000) cpu_state.flags|=C_FLAG;
if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG;
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
}
static __inline void setadc32(uint32_t a, uint32_t b)
{
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
cpu_state.flags_op = FLAGS_UNKNOWN;
cpu_state.flags&=~0x8D5;
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
if ((c<a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) cpu_state.flags|=V_FLAG;
if (((a&0xF)+(b&0xF)+tempc)&0x10) cpu_state.flags|=A_FLAG;
}
static __inline void setsbc8(uint8_t a, uint8_t b)
{
uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
cpu_state.flags_op = FLAGS_UNKNOWN;
flags&=~0x8D5;
flags|=znptable8[c&0xFF];
if (c&0x100) flags|=C_FLAG;
if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
cpu_state.flags&=~0x8D5;
cpu_state.flags|=znptable8[c&0xFF];
if (c&0x100) cpu_state.flags|=C_FLAG;
if ((a^b)&(a^c)&0x80) cpu_state.flags|=V_FLAG;
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
}
static __inline void setsbc16(uint16_t a, uint16_t b)
{
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
cpu_state.flags_op = FLAGS_UNKNOWN;
flags&=~0x8D5;
flags|=(znptable16[c&0xFFFF]&~4);
flags|=(znptable8[c&0xFF]&4);
if (c&0x10000) flags|=C_FLAG;
if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
cpu_state.flags&=~0x8D5;
cpu_state.flags|=(znptable16[c&0xFFFF]&~4);
cpu_state.flags|=(znptable8[c&0xFF]&4);
if (c&0x10000) cpu_state.flags|=C_FLAG;
if ((a^b)&(a^c)&0x8000) cpu_state.flags|=V_FLAG;
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
}
static __inline void setadc32(uint32_t a, uint32_t b)
{
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
cpu_state.flags_op = FLAGS_UNKNOWN;
flags&=~0x8D5;
flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
flags|=(znptable8[c&0xFF]&P_FLAG);
if ((c<a) || (c==a && tempc)) flags|=C_FLAG;
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG;
if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG;
}
static __inline void setsbc32(uint32_t a, uint32_t b)
{
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
cpu_state.flags_op = FLAGS_UNKNOWN;
flags&=~0x8D5;
flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
flags|=(znptable8[c&0xFF]&P_FLAG);
if ((c>a) || (c==a && tempc)) flags|=C_FLAG;
if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG;
if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG;
cpu_state.flags&=~0x8D5;
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
if ((c>a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG;
if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG;
}
extern void cpu_386_flags_extract();
extern void cpu_386_flags_rebuild();

View File

@@ -83,7 +83,9 @@ extern const OpFn dynarec_ops_winchip_0f[1024];
extern const OpFn dynarec_ops_pentium_0f[1024];
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
extern const OpFn dynarec_ops_c6x86mx_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
extern const OpFn dynarec_ops_k6_0f[1024];
@@ -175,7 +177,9 @@ extern const OpFn ops_winchip_0f[1024];
extern const OpFn ops_pentium_0f[1024];
extern const OpFn ops_pentiummmx_0f[1024];
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
extern const OpFn ops_c6x86mx_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
extern const OpFn ops_k6_0f[1024];

View File

@@ -40,36 +40,36 @@ static int opSYSCALL(uint32_t fetchdat)
if (!AMD_SYSCALL_SB) return internal_illegal("SYSCALL: AMD SYSCALL SB MSR is zero");
/* Set VM, IF, RF to 0. */
/* eflags &= ~0x00030200;
flags &= ~0x0200; */
/* cpu_state.eflags &= ~0x00030200;
cpu_state.flags &= ~0x0200; */
/* Let's do this by the AMD spec. */
ECX = cpu_state.pc;
eflags &= ~0x0002;
flags &= ~0x0200;
cpu_state.eflags &= ~0x0002;
cpu_state.flags &= ~0x0200;
/* CS */
_cs.seg = AMD_SYSCALL_SB & ~7;
cpu_state.seg_cs.seg = AMD_SYSCALL_SB & ~7;
if (AMD_SYSCALL_SB & 4)
{
if (_cs.seg >= ldt.limit)
if (cpu_state.seg_cs.seg >= ldt.limit)
{
x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSCALL_SB,ldt.limit);
x86gpf(NULL, AMD_SYSCALL_SB & ~3);
return 1;
}
_cs.seg +=ldt.base;
cpu_state.seg_cs.seg +=ldt.base;
}
else
{
if (_cs.seg >= gdt.limit)
if (cpu_state.seg_cs.seg >= gdt.limit)
{
x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSCALL_SB,gdt.limit);
x86gpf(NULL, AMD_SYSCALL_SB & ~3);
return 1;
}
_cs.seg += gdt.base;
cpu_state.seg_cs.seg += gdt.base;
}
cpl_override = 1;
@@ -83,27 +83,27 @@ static int opSYSCALL(uint32_t fetchdat)
use32 = 0x300;
CS = (AMD_SYSCALL_SB & ~3) | 0;
do_seg_load(&_cs, syscall_cs_seg_data);
do_seg_load(&cpu_state.seg_cs, syscall_cs_seg_data);
use32 = 0x300;
CS = (CS & 0xFFFC) | 0;
_cs.limit = 0xFFFFFFFF;
_cs.limit_high = 0xFFFFFFFF;
cpu_state.seg_cs.limit = 0xFFFFFFFF;
cpu_state.seg_cs.limit_high = 0xFFFFFFFF;
/* SS */
syscall_ss_seg_data[0] = 0xFFFF;
syscall_ss_seg_data[1] = 0;
syscall_ss_seg_data[2] = 0x9300;
syscall_ss_seg_data[3] = 0xC0;
do_seg_load(&_ss, syscall_ss_seg_data);
_ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC;
do_seg_load(&cpu_state.seg_ss, syscall_ss_seg_data);
cpu_state.seg_ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC;
stack32 = 1;
_ss.limit = 0xFFFFFFFF;
_ss.limit_high = 0xFFFFFFFF;
cpu_state.seg_ss.limit = 0xFFFFFFFF;
cpu_state.seg_ss.limit_high = 0xFFFFFFFF;
_ss.checked = 0;
cpu_state.seg_ss.checked = 0;
cpu_state.pc = AMD_SYSCALL_EIP;
@@ -125,29 +125,29 @@ static int opSYSRET(uint32_t fetchdat)
cpu_state.pc = ECX;
eflags |= (1 << 1);
cpu_state.eflags |= (1 << 1);
/* CS */
_cs.seg = AMD_SYSRET_SB & ~7;
cpu_state.seg_cs.seg = AMD_SYSRET_SB & ~7;
if (AMD_SYSRET_SB & 4)
{
if (_cs.seg >= ldt.limit)
if (cpu_state.seg_cs.seg >= ldt.limit)
{
x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSRET_SB,ldt.limit);
x86gpf(NULL, AMD_SYSRET_SB & ~3);
return 1;
}
_cs.seg +=ldt.base;
cpu_state.seg_cs.seg +=ldt.base;
}
else
{
if (_cs.seg >= gdt.limit)
if (cpu_state.seg_cs.seg >= gdt.limit)
{
x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSRET_SB,gdt.limit);
x86gpf(NULL, AMD_SYSRET_SB & ~3);
return 1;
}
_cs.seg += gdt.base;
cpu_state.seg_cs.seg += gdt.base;
}
cpl_override = 1;
@@ -161,28 +161,28 @@ static int opSYSRET(uint32_t fetchdat)
use32 = 0x300;
CS = (AMD_SYSRET_SB & ~3) | 3;
do_seg_load(&_cs, sysret_cs_seg_data);
do_seg_load(&cpu_state.seg_cs, sysret_cs_seg_data);
flushmmucache_cr3();
use32 = 0x300;
CS = (CS & 0xFFFC) | 3;
_cs.limit = 0xFFFFFFFF;
_cs.limit_high = 0xFFFFFFFF;
cpu_state.seg_cs.limit = 0xFFFFFFFF;
cpu_state.seg_cs.limit_high = 0xFFFFFFFF;
/* SS */
sysret_ss_seg_data[0] = 0xFFFF;
sysret_ss_seg_data[1] = 0;
sysret_ss_seg_data[2] = 0xF300;
sysret_ss_seg_data[3] = 0xC0;
do_seg_load(&_ss, sysret_ss_seg_data);
_ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3;
do_seg_load(&cpu_state.seg_ss, sysret_ss_seg_data);
cpu_state.seg_ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3;
stack32 = 1;
_ss.limit = 0xFFFFFFFF;
_ss.limit_high = 0xFFFFFFFF;
cpu_state.seg_ss.limit = 0xFFFFFFFF;
cpu_state.seg_ss.limit_high = 0xFFFFFFFF;
_ss.checked = 0;
cpu_state.seg_ss.checked = 0;
CLOCK_CYCLES(20);

View File

@@ -16,6 +16,7 @@
} \
else \
{ \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
dst = geteab(); if (cpu_state.abrt) return 1; \
src = getr8(cpu_reg); \
seteab(operation); if (cpu_state.abrt) return 1; \
@@ -42,6 +43,7 @@
} \
else \
{ \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
dst = geteab(); if (cpu_state.abrt) return 1; \
src = getr8(cpu_reg); \
seteab(operation); if (cpu_state.abrt) return 1; \
@@ -69,6 +71,7 @@
} \
else \
{ \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
dst = geteaw(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].w; \
seteaw(operation); if (cpu_state.abrt) return 1; \
@@ -95,6 +98,7 @@
} \
else \
{ \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
dst = geteaw(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].w; \
seteaw(operation); if (cpu_state.abrt) return 1; \
@@ -122,6 +126,7 @@
} \
else \
{ \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
dst = geteal(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].l; \
seteal(operation); if (cpu_state.abrt) return 1; \
@@ -148,6 +153,7 @@
} \
else \
{ \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
dst = geteal(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].l; \
seteal(operation); if (cpu_state.abrt) return 1; \
@@ -163,6 +169,8 @@
uint8_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
dst = getr8(cpu_reg); \
src = geteab(); if (cpu_state.abrt) return 1; \
setflags ## 8 flagops; \
@@ -176,6 +184,8 @@
uint8_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
dst = getr8(cpu_reg); \
src = geteab(); if (cpu_state.abrt) return 1; \
setflags ## 8 flagops; \
@@ -190,6 +200,8 @@
uint16_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
dst = cpu_state.regs[cpu_reg].w; \
src = geteaw(); if (cpu_state.abrt) return 1; \
setflags ## 16 flagops; \
@@ -203,6 +215,8 @@
uint16_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
dst = cpu_state.regs[cpu_reg].w; \
src = geteaw(); if (cpu_state.abrt) return 1; \
setflags ## 16 flagops; \
@@ -217,6 +231,8 @@
uint32_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
dst = cpu_state.regs[cpu_reg].l; \
src = geteal(); if (cpu_state.abrt) return 1; \
setflags ## 32 flagops; \
@@ -230,6 +246,8 @@
uint32_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
dst = cpu_state.regs[cpu_reg].l; \
src = geteal(); if (cpu_state.abrt) return 1; \
setflags ## 32 flagops; \
@@ -287,6 +305,8 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat)
{
uint8_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteab(); if (cpu_state.abrt) return 1;
setsub8(dst, getr8(cpu_reg));
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -298,6 +318,8 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat)
{
uint8_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteab(); if (cpu_state.abrt) return 1;
setsub8(dst, getr8(cpu_reg));
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -310,6 +332,8 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat)
{
uint16_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteaw(); if (cpu_state.abrt) return 1;
setsub16(dst, cpu_state.regs[cpu_reg].w);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -321,6 +345,8 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat)
{
uint16_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteaw(); if (cpu_state.abrt) return 1;
setsub16(dst, cpu_state.regs[cpu_reg].w);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -333,6 +359,8 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat)
{
uint32_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteal(); if (cpu_state.abrt) return 1;
setsub32(dst, cpu_state.regs[cpu_reg].l);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -344,6 +372,8 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat)
{
uint32_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteal(); if (cpu_state.abrt) return 1;
setsub32(dst, cpu_state.regs[cpu_reg].l);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -355,7 +385,9 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat)
static int opCMP_b_rm_a16(uint32_t fetchdat)
{
uint8_t src;
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
src = geteab(); if (cpu_state.abrt) return 1;
setsub8(getr8(cpu_reg), src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
@@ -365,7 +397,9 @@ static int opCMP_b_rm_a16(uint32_t fetchdat)
static int opCMP_b_rm_a32(uint32_t fetchdat)
{
uint8_t src;
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
src = geteab(); if (cpu_state.abrt) return 1;
setsub8(getr8(cpu_reg), src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
@@ -376,7 +410,9 @@ static int opCMP_b_rm_a32(uint32_t fetchdat)
static int opCMP_w_rm_a16(uint32_t fetchdat)
{
uint16_t src;
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
src = geteaw(); if (cpu_state.abrt) return 1;
setsub16(cpu_state.regs[cpu_reg].w, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
@@ -386,7 +422,9 @@ static int opCMP_w_rm_a16(uint32_t fetchdat)
static int opCMP_w_rm_a32(uint32_t fetchdat)
{
uint16_t src;
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
src = geteaw(); if (cpu_state.abrt) return 1;
setsub16(cpu_state.regs[cpu_reg].w, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
@@ -395,9 +433,11 @@ static int opCMP_w_rm_a32(uint32_t fetchdat)
}
static int opCMP_l_rm_a16(uint32_t fetchdat)
{
uint32_t src;
fetch_ea_16(fetchdat);
{
uint32_t src;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
src = geteal(); if (cpu_state.abrt) return 1;
setsub32(cpu_state.regs[cpu_reg].l, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
@@ -407,7 +447,9 @@ static int opCMP_l_rm_a16(uint32_t fetchdat)
static int opCMP_l_rm_a32(uint32_t fetchdat)
{
uint32_t src;
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
src = geteal(); if (cpu_state.abrt) return 1;
setsub32(cpu_state.regs[cpu_reg].l, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
@@ -446,6 +488,8 @@ static int opTEST_b_a16(uint32_t fetchdat)
{
uint8_t temp, temp2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg);
setznp8(temp & temp2);
@@ -458,6 +502,8 @@ static int opTEST_b_a32(uint32_t fetchdat)
{
uint8_t temp, temp2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg);
setznp8(temp & temp2);
@@ -471,6 +517,8 @@ static int opTEST_w_a16(uint32_t fetchdat)
{
uint16_t temp, temp2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w;
setznp16(temp & temp2);
@@ -483,6 +531,8 @@ static int opTEST_w_a32(uint32_t fetchdat)
{
uint16_t temp, temp2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w;
setznp16(temp & temp2);
@@ -496,6 +546,8 @@ static int opTEST_l_a16(uint32_t fetchdat)
{
uint32_t temp, temp2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l;
setznp32(temp & temp2);
@@ -508,6 +560,8 @@ static int opTEST_l_a32(uint32_t fetchdat)
{
uint32_t temp, temp2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l;
setznp32(temp & temp2);
@@ -600,6 +654,8 @@ static int op80_a16(uint32_t fetchdat)
uint8_t src, dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1;
ARITH_MULTI(b, 8);
if ((rmdat & 0x38) == 0x38)
@@ -614,6 +670,8 @@ static int op80_a32(uint32_t fetchdat)
uint8_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1;
ARITH_MULTI(b, 8);
if ((rmdat & 0x38) == 0x38)
@@ -628,6 +686,8 @@ static int op81_w_a16(uint32_t fetchdat)
uint16_t src, dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getword(); if (cpu_state.abrt) return 1;
ARITH_MULTI(w, 16);
if ((rmdat & 0x38) == 0x38)
@@ -642,6 +702,8 @@ static int op81_w_a32(uint32_t fetchdat)
uint16_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getword(); if (cpu_state.abrt) return 1;
ARITH_MULTI(w, 16);
if ((rmdat & 0x38) == 0x38)
@@ -670,6 +732,8 @@ static int op81_l_a32(uint32_t fetchdat)
uint32_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getlong(); if (cpu_state.abrt) return 1;
ARITH_MULTI(l, 32);
if ((rmdat & 0x38) == 0x38)
@@ -685,6 +749,8 @@ static int op83_w_a16(uint32_t fetchdat)
uint16_t src, dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xff00;
ARITH_MULTI(w, 16);
@@ -700,6 +766,8 @@ static int op83_w_a32(uint32_t fetchdat)
uint16_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xff00;
ARITH_MULTI(w, 16);
@@ -716,6 +784,8 @@ static int op83_l_a16(uint32_t fetchdat)
uint32_t src, dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xffffff00;
ARITH_MULTI(l, 32);
@@ -731,6 +801,8 @@ static int op83_l_a32(uint32_t fetchdat)
uint32_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xffffff00;
ARITH_MULTI(l, 32);

752
src/cpu/x86_ops_arith_ex.h Normal file
View File

@@ -0,0 +1,752 @@
#define OP_ARITH(name, operation, setflags, flagops, gettempc) \
static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \
{ \
uint8_t dst; \
uint8_t src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
if (cpu_mod == 3) \
{ \
dst = getr8(cpu_rm); \
src = getr8(cpu_reg); \
setflags ## 8 flagops; \
setr8(cpu_rm, operation); \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \
} \
else \
{ \
dst = geteab(); if (cpu_state.abrt) return 1; \
src = getr8(cpu_reg); \
seteab(operation); if (cpu_state.abrt) return 1; \
setflags ## 8 flagops; \
CLOCK_CYCLES(timing_mr); \
PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \
} \
return 0; \
} \
static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \
{ \
uint8_t dst; \
uint8_t src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
if (cpu_mod == 3) \
{ \
dst = getr8(cpu_rm); \
src = getr8(cpu_reg); \
setflags ## 8 flagops; \
setr8(cpu_rm, operation); \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \
} \
else \
{ \
dst = geteab(); if (cpu_state.abrt) return 1; \
src = getr8(cpu_reg); \
seteab(operation); if (cpu_state.abrt) return 1; \
setflags ## 8 flagops; \
CLOCK_CYCLES(timing_mr); \
PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \
} \
return 0; \
} \
\
static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \
{ \
uint16_t dst; \
uint16_t src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
if (cpu_mod == 3) \
{ \
dst = cpu_state.regs[cpu_rm].w; \
src = cpu_state.regs[cpu_reg].w; \
setflags ## 16 flagops; \
cpu_state.regs[cpu_rm].w = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \
} \
else \
{ \
dst = geteaw(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].w; \
seteaw(operation); if (cpu_state.abrt) return 1; \
setflags ## 16 flagops; \
CLOCK_CYCLES(timing_mr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \
} \
return 0; \
} \
static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \
{ \
uint16_t dst; \
uint16_t src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
if (cpu_mod == 3) \
{ \
dst = cpu_state.regs[cpu_rm].w; \
src = cpu_state.regs[cpu_reg].w; \
setflags ## 16 flagops; \
cpu_state.regs[cpu_rm].w = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \
} \
else \
{ \
dst = geteaw(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].w; \
seteaw(operation); if (cpu_state.abrt) return 1; \
setflags ## 16 flagops; \
CLOCK_CYCLES(timing_mr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \
} \
return 0; \
} \
\
static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \
{ \
uint32_t dst; \
uint32_t src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
if (cpu_mod == 3) \
{ \
dst = cpu_state.regs[cpu_rm].l; \
src = cpu_state.regs[cpu_reg].l; \
setflags ## 32 flagops; \
cpu_state.regs[cpu_rm].l = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \
} \
else \
{ \
dst = geteal(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].l; \
seteal(operation); if (cpu_state.abrt) return 1; \
setflags ## 32 flagops; \
CLOCK_CYCLES(timing_mr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \
} \
return 0; \
} \
static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \
{ \
uint32_t dst; \
uint32_t src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
if (cpu_mod == 3) \
{ \
dst = cpu_state.regs[cpu_rm].l; \
src = cpu_state.regs[cpu_reg].l; \
setflags ## 32 flagops; \
cpu_state.regs[cpu_rm].l = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \
} \
else \
{ \
dst = geteal(); if (cpu_state.abrt) return 1; \
src = cpu_state.regs[cpu_reg].l; \
seteal(operation); if (cpu_state.abrt) return 1; \
setflags ## 32 flagops; \
CLOCK_CYCLES(timing_mr); \
PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \
} \
return 0; \
} \
\
static int op ## name ## _b_rm_a16(uint32_t fetchdat) \
{ \
uint8_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
dst = getr8(cpu_reg); \
src = geteab(); if (cpu_state.abrt) return 1; \
setflags ## 8 flagops; \
setr8(cpu_reg, operation); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \
return 0; \
} \
static int op ## name ## _b_rm_a32(uint32_t fetchdat) \
{ \
uint8_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
dst = getr8(cpu_reg); \
src = geteab(); if (cpu_state.abrt) return 1; \
setflags ## 8 flagops; \
setr8(cpu_reg, operation); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \
return 0; \
} \
\
static int op ## name ## _w_rm_a16(uint32_t fetchdat) \
{ \
uint16_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
dst = cpu_state.regs[cpu_reg].w; \
src = geteaw(); if (cpu_state.abrt) return 1; \
setflags ## 16 flagops; \
cpu_state.regs[cpu_reg].w = operation; \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \
return 0; \
} \
static int op ## name ## _w_rm_a32(uint32_t fetchdat) \
{ \
uint16_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
dst = cpu_state.regs[cpu_reg].w; \
src = geteaw(); if (cpu_state.abrt) return 1; \
setflags ## 16 flagops; \
cpu_state.regs[cpu_reg].w = operation; \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \
return 0; \
} \
\
static int op ## name ## _l_rm_a16(uint32_t fetchdat) \
{ \
uint32_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_16(fetchdat); \
dst = cpu_state.regs[cpu_reg].l; \
src = geteal(); if (cpu_state.abrt) return 1; \
setflags ## 32 flagops; \
cpu_state.regs[cpu_reg].l = operation; \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \
return 0; \
} \
static int op ## name ## _l_rm_a32(uint32_t fetchdat) \
{ \
uint32_t dst, src; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
fetch_ea_32(fetchdat); \
dst = cpu_state.regs[cpu_reg].l; \
src = geteal(); if (cpu_state.abrt) return 1; \
setflags ## 32 flagops; \
cpu_state.regs[cpu_reg].l = operation; \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \
return 0; \
} \
\
static int op ## name ## _AL_imm(uint32_t fetchdat) \
{ \
uint8_t dst = AL; \
uint8_t src = getbytef(); \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
setflags ## 8 flagops; \
AL = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \
return 0; \
} \
\
static int op ## name ## _AX_imm(uint32_t fetchdat) \
{ \
uint16_t dst = AX; \
uint16_t src = getwordf(); \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
setflags ## 16 flagops; \
AX = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \
return 0; \
} \
\
static int op ## name ## _EAX_imm(uint32_t fetchdat) \
{ \
uint32_t dst = EAX; \
uint32_t src = getlong(); if (cpu_state.abrt) return 1; \
if (gettempc) tempc = CF_SET() ? 1 : 0; \
setflags ## 32 flagops; \
EAX = operation; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \
return 0; \
}
OP_ARITH(ADD, dst + src, setadd, (dst, src), 0)
OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1)
OP_ARITH(SUB, dst - src, setsub, (dst, src), 0)
OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1)
OP_ARITH(OR, dst | src, setznp, (dst | src), 0)
OP_ARITH(AND, dst & src, setznp, (dst & src), 0)
OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0)
static int opCMP_b_rmw_a16(uint32_t fetchdat)
{
uint8_t dst;
fetch_ea_16(fetchdat);
dst = geteab(); if (cpu_state.abrt) return 1;
setsub8(dst, getr8(cpu_reg));
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0;
}
static int opCMP_b_rmw_a32(uint32_t fetchdat)
{
uint8_t dst;
fetch_ea_32(fetchdat);
dst = geteab(); if (cpu_state.abrt) return 1;
setsub8(dst, getr8(cpu_reg));
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0;
}
static int opCMP_w_rmw_a16(uint32_t fetchdat)
{
uint16_t dst;
fetch_ea_16(fetchdat);
dst = geteaw(); if (cpu_state.abrt) return 1;
setsub16(dst, cpu_state.regs[cpu_reg].w);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0;
}
static int opCMP_w_rmw_a32(uint32_t fetchdat)
{
uint16_t dst;
fetch_ea_32(fetchdat);
dst = geteaw(); if (cpu_state.abrt) return 1;
setsub16(dst, cpu_state.regs[cpu_reg].w);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0;
}
static int opCMP_l_rmw_a16(uint32_t fetchdat)
{
uint32_t dst;
fetch_ea_16(fetchdat);
dst = geteal(); if (cpu_state.abrt) return 1;
setsub32(dst, cpu_state.regs[cpu_reg].l);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0);
return 0;
}
static int opCMP_l_rmw_a32(uint32_t fetchdat)
{
uint32_t dst;
fetch_ea_32(fetchdat);
dst = geteal(); if (cpu_state.abrt) return 1;
setsub32(dst, cpu_state.regs[cpu_reg].l);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1);
return 0;
}
static int opCMP_b_rm_a16(uint32_t fetchdat)
{
uint8_t src;
fetch_ea_16(fetchdat);
src = geteab(); if (cpu_state.abrt) return 1;
setsub8(getr8(cpu_reg), src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0;
}
static int opCMP_b_rm_a32(uint32_t fetchdat)
{
uint8_t src;
fetch_ea_32(fetchdat);
src = geteab(); if (cpu_state.abrt) return 1;
setsub8(getr8(cpu_reg), src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0;
}
static int opCMP_w_rm_a16(uint32_t fetchdat)
{
uint16_t src;
fetch_ea_16(fetchdat);
src = geteaw(); if (cpu_state.abrt) return 1;
setsub16(cpu_state.regs[cpu_reg].w, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0;
}
static int opCMP_w_rm_a32(uint32_t fetchdat)
{
uint16_t src;
fetch_ea_32(fetchdat);
src = geteaw(); if (cpu_state.abrt) return 1;
setsub16(cpu_state.regs[cpu_reg].w, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0;
}
static int opCMP_l_rm_a16(uint32_t fetchdat)
{
uint32_t src;
fetch_ea_16(fetchdat);
src = geteal(); if (cpu_state.abrt) return 1;
setsub32(cpu_state.regs[cpu_reg].l, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0);
return 0;
}
static int opCMP_l_rm_a32(uint32_t fetchdat)
{
uint32_t src;
fetch_ea_32(fetchdat);
src = geteal(); if (cpu_state.abrt) return 1;
setsub32(cpu_state.regs[cpu_reg].l, src);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1);
return 0;
}
static int opCMP_AL_imm(uint32_t fetchdat)
{
uint8_t src = getbytef();
setsub8(AL, src);
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0);
return 0;
}
static int opCMP_AX_imm(uint32_t fetchdat)
{
uint16_t src = getwordf();
setsub16(AX, src);
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0);
return 0;
}
static int opCMP_EAX_imm(uint32_t fetchdat)
{
uint32_t src = getlong(); if (cpu_state.abrt) return 1;
setsub32(EAX, src);
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0);
return 0;
}
static int opTEST_b_a16(uint32_t fetchdat)
{
uint8_t temp, temp2;
fetch_ea_16(fetchdat);
temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg);
setznp8(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0;
}
static int opTEST_b_a32(uint32_t fetchdat)
{
uint8_t temp, temp2;
fetch_ea_32(fetchdat);
temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg);
setznp8(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0;
}
static int opTEST_w_a16(uint32_t fetchdat)
{
uint16_t temp, temp2;
fetch_ea_16(fetchdat);
temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w;
setznp16(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0;
}
static int opTEST_w_a32(uint32_t fetchdat)
{
uint16_t temp, temp2;
fetch_ea_32(fetchdat);
temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w;
setznp16(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0;
}
static int opTEST_l_a16(uint32_t fetchdat)
{
uint32_t temp, temp2;
fetch_ea_16(fetchdat);
temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l;
setznp32(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0);
return 0;
}
static int opTEST_l_a32(uint32_t fetchdat)
{
uint32_t temp, temp2;
fetch_ea_32(fetchdat);
temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l;
setznp32(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1);
return 0;
}
static int opTEST_AL(uint32_t fetchdat)
{
uint8_t temp = getbytef();
setznp8(AL & temp);
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0);
return 0;
}
static int opTEST_AX(uint32_t fetchdat)
{
uint16_t temp = getwordf();
setznp16(AX & temp);
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0);
return 0;
}
static int opTEST_EAX(uint32_t fetchdat)
{
uint32_t temp = getlong(); if (cpu_state.abrt) return 1;
setznp32(EAX & temp);
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0);
return 0;
}
#define ARITH_MULTI(ea_width, flag_width, is32) \
dst = read ## ea_width(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \
switch ((rmdat >> 3) & 7) \
{ \
case 0x00: /*ADD ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
write ## ea_width(easeg, cpu_state.eaaddr, dst + src); if (cpu_state.abrt) return 1; \
setadd ## flag_width(dst, src); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x01: /*OR ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
dst |= src; \
write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \
setznp ## flag_width(dst); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x02: /*ADC ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
tempc = CF_SET() ? 1 : 0; \
write ## ea_width(easeg, cpu_state.eaaddr, dst + src + tempc); if (cpu_state.abrt) return 1; \
setadc ## flag_width(dst, src); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x03: /*SBB ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
tempc = CF_SET() ? 1 : 0; \
write ## ea_width(easeg, cpu_state.eaaddr, dst - (src + tempc)); if (cpu_state.abrt) return 1; \
setsbc ## flag_width(dst, src); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x04: /*AND ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
dst &= src; \
write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \
setznp ## flag_width(dst); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x05: /*SUB ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
write ## ea_width(easeg, cpu_state.eaaddr, dst - src); if (cpu_state.abrt) return 1; \
setsub ## flag_width(dst, src); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x06: /*XOR ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
dst ^= src; \
write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \
setznp ## flag_width(dst); \
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
break; \
case 0x07: /*CMP ea, #*/ \
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 0, is32) \
setsub ## flag_width(dst, src); \
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \
break; \
}
static int op80_a16(uint32_t fetchdat)
{
uint8_t src, dst;
fetch_ea_16(fetchdat);
src = getbyte(); if (cpu_state.abrt) return 1;
ARITH_MULTI(8, 8, 0);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
return 0;
}
static int op80_a32(uint32_t fetchdat)
{
uint8_t src, dst;
fetch_ea_32(fetchdat);
src = getbyte(); if (cpu_state.abrt) return 1;
ARITH_MULTI(8, 8, 1);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
return 0;
}
static int op81_w_a16(uint32_t fetchdat)
{
uint16_t src, dst;
fetch_ea_16(fetchdat);
src = getword(); if (cpu_state.abrt) return 1;
ARITH_MULTI(16, 16, 0);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
return 0;
}
static int op81_w_a32(uint32_t fetchdat)
{
uint16_t src, dst;
fetch_ea_32(fetchdat);
src = getword(); if (cpu_state.abrt) return 1;
ARITH_MULTI(16, 16, 1);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
return 0;
}
static int op81_l_a16(uint32_t fetchdat)
{
uint32_t src, dst;
fetch_ea_16(fetchdat);
src = getlong(); if (cpu_state.abrt) return 1;
ARITH_MULTI(32, 32, 0);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
return 0;
}
static int op81_l_a32(uint32_t fetchdat)
{
uint32_t src, dst;
fetch_ea_32(fetchdat);
src = getlong(); if (cpu_state.abrt) return 1;
ARITH_MULTI(32, 32, 1);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
return 0;
}
static int op83_w_a16(uint32_t fetchdat)
{
uint16_t src, dst;
fetch_ea_16(fetchdat);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xff00;
ARITH_MULTI(16, 16, 0);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
return 0;
}
static int op83_w_a32(uint32_t fetchdat)
{
uint16_t src, dst;
fetch_ea_32(fetchdat);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xff00;
ARITH_MULTI(16, 16, 1);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
return 0;
}
static int op83_l_a16(uint32_t fetchdat)
{
uint32_t src, dst;
fetch_ea_16(fetchdat);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xffffff00;
ARITH_MULTI(32, 32, 0);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
return 0;
}
static int op83_l_a32(uint32_t fetchdat)
{
uint32_t src, dst;
fetch_ea_32(fetchdat);
src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xffffff00;
ARITH_MULTI(32, 32, 1);
if ((rmdat & 0x38) == 0x38)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
else
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
return 0;
}

View File

@@ -8,6 +8,7 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat)
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
if (AL == temp) seteab(getr8(cpu_reg));
else AL = temp;
@@ -26,6 +27,7 @@ static int opCMPXCHG_b_a32(uint32_t fetchdat)
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
if (AL == temp) seteab(getr8(cpu_reg));
else AL = temp;
@@ -45,6 +47,7 @@ static int opCMPXCHG_w_a16(uint32_t fetchdat)
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w);
else AX = temp;
@@ -63,6 +66,7 @@ static int opCMPXCHG_w_a32(uint32_t fetchdat)
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w);
else AX = temp;
@@ -82,6 +86,7 @@ static int opCMPXCHG_l_a16(uint32_t fetchdat)
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l);
else EAX = temp;
@@ -100,6 +105,7 @@ static int opCMPXCHG_l_a32(uint32_t fetchdat)
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l);
else EAX = temp;
@@ -119,6 +125,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat)
return 0;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
if (EAX == temp && EDX == temp_hi)
@@ -134,9 +141,9 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat)
if (cpu_state.abrt) return 0;
flags_rebuild();
if (temp == temp2 && temp_hi == temp2_hi)
flags |= Z_FLAG;
cpu_state.flags |= Z_FLAG;
else
flags &= ~Z_FLAG;
cpu_state.flags &= ~Z_FLAG;
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
}
@@ -150,6 +157,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat)
return 0;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
if (EAX == temp && EDX == temp_hi)
@@ -165,9 +173,9 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat)
if (cpu_state.abrt) return 0;
flags_rebuild();
if (temp == temp2 && temp_hi == temp2_hi)
flags |= Z_FLAG;
cpu_state.flags |= Z_FLAG;
else
flags &= ~Z_FLAG;
cpu_state.flags &= ~Z_FLAG;
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
}
@@ -182,6 +190,7 @@ static int opXADD_b_a16(uint32_t fetchdat)
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1;
setadd8(temp, getr8(cpu_reg));
@@ -199,6 +208,7 @@ static int opXADD_b_a32(uint32_t fetchdat)
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1;
setadd8(temp, getr8(cpu_reg));
@@ -217,6 +227,7 @@ static int opXADD_w_a16(uint32_t fetchdat)
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
setadd16(temp, cpu_state.regs[cpu_reg].w);
@@ -234,6 +245,7 @@ static int opXADD_w_a32(uint32_t fetchdat)
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
setadd16(temp, cpu_state.regs[cpu_reg].w);
@@ -252,6 +264,7 @@ static int opXADD_l_a16(uint32_t fetchdat)
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
setadd32(temp, cpu_state.regs[cpu_reg].l);
@@ -269,6 +282,7 @@ static int opXADD_l_a32(uint32_t fetchdat)
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
setadd32(temp, cpu_state.regs[cpu_reg].l);

View File

@@ -1,14 +1,14 @@
static int opAAA(uint32_t fetchdat)
{
flags_rebuild();
if ((flags & A_FLAG) || ((AL & 0xF) > 9))
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
{
AL += 6;
AH++;
flags |= (A_FLAG | C_FLAG);
cpu_state.flags |= (A_FLAG | C_FLAG);
}
else
flags &= ~(A_FLAG | C_FLAG);
cpu_state.flags &= ~(A_FLAG | C_FLAG);
AL &= 0xF;
CLOCK_CYCLES(is486 ? 3 : 4);
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0);
@@ -42,14 +42,14 @@ static int opAAM(uint32_t fetchdat)
static int opAAS(uint32_t fetchdat)
{
flags_rebuild();
if ((flags & A_FLAG) || ((AL & 0xF) > 9))
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
{
AL -= 6;
AH--;
flags |= (A_FLAG | C_FLAG);
cpu_state.flags |= (A_FLAG | C_FLAG);
}
else
flags &= ~(A_FLAG | C_FLAG);
cpu_state.flags &= ~(A_FLAG | C_FLAG);
AL &= 0xF;
CLOCK_CYCLES(is486 ? 3 : 4);
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0);
@@ -61,23 +61,23 @@ static int opDAA(uint32_t fetchdat)
uint16_t tempw;
flags_rebuild();
if ((flags & A_FLAG) || ((AL & 0xf) > 9))
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9))
{
int tempi = ((uint16_t)AL) + 6;
AL += 6;
flags |= A_FLAG;
if (tempi & 0x100) flags |= C_FLAG;
cpu_state.flags |= A_FLAG;
if (tempi & 0x100) cpu_state.flags |= C_FLAG;
}
if ((flags & C_FLAG) || (AL > 0x9f))
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f))
{
AL += 0x60;
flags |= C_FLAG;
cpu_state.flags |= C_FLAG;
}
tempw = flags & (C_FLAG | A_FLAG);
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
setznp8(AL);
flags_rebuild();
flags |= tempw;
cpu_state.flags |= tempw;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
@@ -89,23 +89,23 @@ static int opDAS(uint32_t fetchdat)
uint16_t tempw;
flags_rebuild();
if ((flags & A_FLAG) || ((AL & 0xf) > 9))
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9))
{
int tempi = ((uint16_t)AL) - 6;
AL -= 6;
flags |= A_FLAG;
if (tempi & 0x100) flags |= C_FLAG;
cpu_state.flags |= A_FLAG;
if (tempi & 0x100) cpu_state.flags |= C_FLAG;
}
if ((flags & C_FLAG) || (AL > 0x9f))
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f))
{
AL -= 0x60;
flags |= C_FLAG;
cpu_state.flags |= C_FLAG;
}
tempw = flags & (C_FLAG | A_FLAG);
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
setznp8(AL);
flags_rebuild();
flags |= tempw;
cpu_state.flags |= tempw;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);

View File

@@ -3,11 +3,12 @@ static int opBT_w_r_a16(uint32_t fetchdat)
uint16_t temp;
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0;
temp = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0);
@@ -18,11 +19,12 @@ static int opBT_w_r_a32(uint32_t fetchdat)
uint16_t temp;
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0;
temp = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1);
@@ -33,11 +35,12 @@ static int opBT_l_r_a16(uint32_t fetchdat)
uint32_t temp;
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0;
temp = geteal(); if (cpu_state.abrt) return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0);
@@ -48,11 +51,12 @@ static int opBT_l_r_a32(uint32_t fetchdat)
uint32_t temp;
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0;
temp = geteal(); if (cpu_state.abrt) return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1);
@@ -66,14 +70,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
uint16_t temp; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
temp = geteaw(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
else flags &= ~C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \
@@ -85,14 +91,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
uint16_t temp; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
temp = geteaw(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
else flags &= ~C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \
@@ -104,14 +112,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
uint32_t temp; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
temp = geteal(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
seteal(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
else flags &= ~C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \
@@ -123,14 +133,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
uint32_t temp; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
temp = geteal(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
seteal(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
else flags &= ~C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \
@@ -147,6 +159,8 @@ static int opBA_w_a16(uint32_t fetchdat)
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
count = getbyte(); if (cpu_state.abrt) return 1;
@@ -155,8 +169,8 @@ static int opBA_w_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x20: /*BT w,imm*/
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
return 0;
@@ -177,8 +191,8 @@ static int opBA_w_a16(uint32_t fetchdat)
break;
}
seteaw(temp); if (cpu_state.abrt) return 1;
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
return 0;
@@ -189,6 +203,8 @@ static int opBA_w_a32(uint32_t fetchdat)
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
count = getbyte(); if (cpu_state.abrt) return 1;
@@ -197,8 +213,8 @@ static int opBA_w_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x20: /*BT w,imm*/
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
return 0;
@@ -219,8 +235,8 @@ static int opBA_w_a32(uint32_t fetchdat)
break;
}
seteaw(temp); if (cpu_state.abrt) return 1;
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
return 0;
@@ -232,6 +248,8 @@ static int opBA_l_a16(uint32_t fetchdat)
uint32_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
count = getbyte(); if (cpu_state.abrt) return 1;
@@ -240,8 +258,8 @@ static int opBA_l_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x20: /*BT w,imm*/
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
return 0;
@@ -262,8 +280,8 @@ static int opBA_l_a16(uint32_t fetchdat)
break;
}
seteal(temp); if (cpu_state.abrt) return 1;
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
return 0;
@@ -274,6 +292,8 @@ static int opBA_l_a32(uint32_t fetchdat)
uint32_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
count = getbyte(); if (cpu_state.abrt) return 1;
@@ -282,8 +302,8 @@ static int opBA_l_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x20: /*BT w,imm*/
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
return 0;
@@ -304,8 +324,8 @@ static int opBA_l_a32(uint32_t fetchdat)
break;
}
seteal(temp); if (cpu_state.abrt) return 1;
if (tempc) flags |= C_FLAG;
else flags &= ~C_FLAG;
if (tempc) cpu_state.flags |= C_FLAG;
else cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
return 0;

View File

@@ -4,7 +4,7 @@
if (temp) \
{ \
int c; \
flags &= ~Z_FLAG; \
cpu_state.flags &= ~Z_FLAG; \
for (c = start; c != end; c += dir) \
{ \
CLOCK_CYCLES(time); \
@@ -17,7 +17,7 @@
} \
} \
else \
flags |= Z_FLAG;
cpu_state.flags |= Z_FLAG;
static int opBSF_w_a16(uint32_t fetchdat)
{
@@ -25,6 +25,8 @@ static int opBSF_w_a16(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
@@ -40,6 +42,8 @@ static int opBSF_w_a32(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
@@ -55,6 +59,8 @@ static int opBSF_l_a16(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
@@ -70,6 +76,8 @@ static int opBSF_l_a32(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
@@ -86,6 +94,8 @@ static int opBSR_w_a16(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
@@ -101,6 +111,8 @@ static int opBSR_w_a32(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
@@ -116,6 +128,8 @@ static int opBSR_l_a16(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
@@ -131,6 +145,8 @@ static int opBSR_l_a32(uint32_t fetchdat)
int instr_cycles = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);

View File

@@ -1,11 +1,11 @@
#define CALL_FAR_w(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
oxpc = cpu_state.pc; \
oxpc = cpu_state.pc; \
cpu_state.pc = new_pc; \
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
if (msw & 1) loadcscall(new_seg); \
else \
{ \
loadcs(new_seg); \
@@ -30,11 +30,11 @@
#define CALL_FAR_l(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
oxpc = cpu_state.pc; \
oxpc = cpu_state.pc; \
cpu_state.pc = new_pc; \
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
if (msw & 1) loadcscall(new_seg); \
else \
{ \
loadcs(new_seg); \
@@ -104,6 +104,8 @@ static int opFF_w_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*INC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp + 1); if (cpu_state.abrt) return 1;
setadd16nc(temp, 1);
@@ -111,6 +113,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
break;
case 0x08: /*DEC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp - 1); if (cpu_state.abrt) return 1;
setsub16nc(temp, 1);
@@ -118,6 +122,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(cpu_state.pc);
cpu_state.pc = new_pc;
@@ -128,6 +134,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1;
@@ -137,6 +145,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
@@ -146,6 +156,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
@@ -156,6 +168,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH w*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(temp);
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
@@ -181,6 +195,8 @@ static int opFF_w_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*INC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp + 1); if (cpu_state.abrt) return 1;
setadd16nc(temp, 1);
@@ -188,6 +204,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
break;
case 0x08: /*DEC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp - 1); if (cpu_state.abrt) return 1;
setsub16nc(temp, 1);
@@ -195,6 +213,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(cpu_state.pc);
cpu_state.pc = new_pc;
@@ -205,6 +225,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1;
@@ -214,6 +236,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
@@ -223,6 +247,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
@@ -233,6 +259,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH w*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(temp);
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
@@ -259,6 +287,8 @@ static int opFF_l_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*INC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp + 1); if (cpu_state.abrt) return 1;
setadd32nc(temp, 1);
@@ -266,6 +296,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
break;
case 0x08: /*DEC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp - 1); if (cpu_state.abrt) return 1;
setsub32nc(temp, 1);
@@ -273,6 +305,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(cpu_state.pc);
cpu_state.pc = new_pc;
@@ -283,6 +317,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1;
@@ -292,6 +328,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
@@ -301,6 +339,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
@@ -311,6 +351,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH l*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(temp);
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
@@ -336,6 +378,8 @@ static int opFF_l_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*INC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp + 1); if (cpu_state.abrt) return 1;
setadd32nc(temp, 1);
@@ -343,6 +387,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
break;
case 0x08: /*DEC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp - 1); if (cpu_state.abrt) return 1;
setsub32nc(temp, 1);
@@ -350,6 +396,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
@@ -360,6 +408,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1;
@@ -369,6 +419,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
@@ -378,6 +430,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
@@ -388,6 +442,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH l*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(temp);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1);

View File

@@ -1,7 +1,7 @@
static int opCMC(uint32_t fetchdat)
{
flags_rebuild();
flags ^= C_FLAG;
cpu_state.flags ^= C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 0;
@@ -11,14 +11,14 @@ static int opCMC(uint32_t fetchdat)
static int opCLC(uint32_t fetchdat)
{
flags_rebuild();
flags &= ~C_FLAG;
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 0;
}
static int opCLD(uint32_t fetchdat)
{
flags &= ~D_FLAG;
cpu_state.flags &= ~D_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 0;
@@ -27,10 +27,10 @@ static int opCLI(uint32_t fetchdat)
{
if (!IOPLp)
{
if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
((eflags & VM_FLAG) && (cr4 & CR4_VME)))
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME)))
{
eflags &= ~VIF_FLAG;
cpu_state.eflags &= ~VIF_FLAG;
}
else
{
@@ -39,7 +39,7 @@ static int opCLI(uint32_t fetchdat)
}
}
else
flags &= ~I_FLAG;
cpu_state.flags &= ~I_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
@@ -49,14 +49,14 @@ static int opCLI(uint32_t fetchdat)
static int opSTC(uint32_t fetchdat)
{
flags_rebuild();
flags |= C_FLAG;
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 0;
}
static int opSTD(uint32_t fetchdat)
{
flags |= D_FLAG;
cpu_state.flags |= D_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 0;
@@ -65,16 +65,16 @@ static int opSTI(uint32_t fetchdat)
{
if (!IOPLp)
{
if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
((eflags & VM_FLAG) && (cr4 & CR4_VME)))
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME)))
{
if (eflags & VIP_FLAG)
if (cpu_state.eflags & VIP_FLAG)
{
x86gpf(NULL,0);
return 1;
}
else
eflags |= VIF_FLAG;
cpu_state.eflags |= VIF_FLAG;
}
else
{
@@ -83,7 +83,7 @@ static int opSTI(uint32_t fetchdat)
}
}
else
flags |= I_FLAG;
cpu_state.flags |= I_FLAG;
CPU_BLOCK_END();
@@ -95,7 +95,7 @@ static int opSTI(uint32_t fetchdat)
static int opSAHF(uint32_t fetchdat)
{
flags_rebuild();
flags = (flags & 0xff00) | (AH & 0xd5) | 2;
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
@@ -108,7 +108,7 @@ static int opSAHF(uint32_t fetchdat)
static int opLAHF(uint32_t fetchdat)
{
flags_rebuild();
AH = flags & 0xff;
AH = cpu_state.flags & 0xff;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
return 0;
@@ -116,15 +116,15 @@ static int opLAHF(uint32_t fetchdat)
static int opPUSHF(uint32_t fetchdat)
{
if ((eflags & VM_FLAG) && (IOPL < 3))
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
{
if (cr4 & CR4_VME)
{
uint16_t temp;
flags_rebuild();
temp = (flags & ~I_FLAG) | 0x3000;
if (eflags & VIF_FLAG)
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
if (cpu_state.eflags & VIF_FLAG)
temp |= I_FLAG;
PUSH_W(temp);
}
@@ -137,7 +137,7 @@ static int opPUSHF(uint32_t fetchdat)
else
{
flags_rebuild();
PUSH_W(flags);
PUSH_W(cpu_state.flags);
}
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
@@ -146,16 +146,16 @@ static int opPUSHF(uint32_t fetchdat)
static int opPUSHFD(uint32_t fetchdat)
{
uint16_t tempw;
if ((eflags & VM_FLAG) && (IOPL < 3))
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
{
x86gpf(NULL, 0);
return 1;
}
if (cpu_CR4_mask & CR4_VME) tempw = eflags & 0x3c;
else if (CPUID) tempw = eflags & 0x24;
else tempw = eflags & 4;
if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c;
else if (CPUID) tempw = cpu_state.eflags & 0x24;
else tempw = cpu_state.eflags & 4;
flags_rebuild();
PUSH_L(flags | (tempw << 16));
PUSH_L(cpu_state.flags | (tempw << 16));
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0);
return cpu_state.abrt;
@@ -165,7 +165,7 @@ static int opPOPF_286(uint32_t fetchdat)
{
uint16_t tempw;
if ((eflags & VM_FLAG) && (IOPL < 3))
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
{
x86gpf(NULL, 0);
return 1;
@@ -173,10 +173,10 @@ static int opPOPF_286(uint32_t fetchdat)
tempw = POP_W(); if (cpu_state.abrt) return 1;
if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2;
else if (!(CPL)) flags = (tempw & 0x7fd5) | 2;
else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2;
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
flags_extract();
CLOCK_CYCLES(5);
@@ -192,7 +192,7 @@ static int opPOPF(uint32_t fetchdat)
{
uint16_t tempw;
if ((eflags & VM_FLAG) && (IOPL < 3))
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
{
if (cr4 & CR4_VME)
{
@@ -206,17 +206,17 @@ static int opPOPF(uint32_t fetchdat)
return 1;
}
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (eflags & VIP_FLAG)))
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
{
ESP = old_esp;
x86gpf(NULL, 0);
return 1;
}
if (tempw & I_FLAG)
eflags |= VIF_FLAG;
cpu_state.eflags |= VIF_FLAG;
else
eflags &= ~VIF_FLAG;
flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
}
else
{
@@ -231,11 +231,11 @@ static int opPOPF(uint32_t fetchdat)
return 1;
if (!(CPL) || !(msw & 1))
flags = (tempw & 0x7fd5) | 2;
cpu_state.flags = (tempw & 0x7fd5) | 2;
else if (IOPLp)
flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
else
flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
}
flags_extract();
@@ -252,7 +252,7 @@ static int opPOPFD(uint32_t fetchdat)
{
uint32_t templ;
if ((eflags & VM_FLAG) && (IOPL < 3))
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
{
x86gpf(NULL, 0);
return 1;
@@ -260,16 +260,16 @@ static int opPOPFD(uint32_t fetchdat)
templ = POP_L(); if (cpu_state.abrt) return 1;
if (!(CPL) || !(msw & 1)) flags = (templ & 0x7fd5) | 2;
else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2;
else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2;
if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2;
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
templ &= is486 ? 0x3c0000 : 0;
templ |= ((eflags&3) << 16);
if (cpu_CR4_mask & CR4_VME) eflags = (templ >> 16) & 0x3f;
else if (CPUID) eflags = (templ >> 16) & 0x27;
else if (is486) eflags = (templ >> 16) & 7;
else eflags = (templ >> 16) & 3;
templ |= ((cpu_state.eflags&3) << 16);
if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f;
else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27;
else if (is486) cpu_state.eflags = (templ >> 16) & 7;
else cpu_state.eflags = (templ >> 16) & 3;
flags_extract();

View File

@@ -43,15 +43,15 @@ static int opSYSENTER(uint32_t fetchdat)
x386_dynarec_log("SYSENTER called\n");
#endif
if (!(cr0 & 1)) return internal_illegal("SYSENTER: CPU not in protected mode");
if (!(msw & 1)) return internal_illegal("SYSENTER: CPU not in protected mode");
if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSENTER: CS MSR is zero");
#ifdef SYSENTER_LOG
x386_dynarec_log("SYSENTER started:\n");
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32);
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32);
#endif
if (cpu_state.abrt) return 1;
@@ -63,17 +63,17 @@ static int opSYSENTER(uint32_t fetchdat)
cgate16 = cgate32 = 0; \
/* Set VM, RF, and IF to 0. */
eflags &= ~0x0003;
flags &= ~0x0200;
cpu_state.eflags &= ~(VM_FLAG | 0x0001);
cpu_state.flags &= ~I_FLAG;
CS = (cs_msr & 0xFFFC);
make_seg_data(sysenter_cs_seg_data, 0, 0xFFFFF, 11, 1, 0, 1, 1, 1, 0);
do_seg_load(&_cs, sysenter_cs_seg_data);
do_seg_load(&cpu_state.seg_cs, sysenter_cs_seg_data);
use32 = 0x300;
SS = ((cs_msr + 8) & 0xFFFC);
make_seg_data(sysenter_ss_seg_data, 0, 0xFFFFF, 3, 1, 0, 1, 1, 1, 0);
do_seg_load(&_ss, sysenter_ss_seg_data);
do_seg_load(&cpu_state.seg_ss, sysenter_ss_seg_data);
stack32 = 1;
cycles -= timing_call_pm;
@@ -84,10 +84,10 @@ static int opSYSENTER(uint32_t fetchdat)
#ifdef SYSENTER_LOG
x386_dynarec_log("SYSENTER completed:\n");
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32);
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32);
#endif
return 0;
@@ -103,15 +103,15 @@ static int opSYSEXIT(uint32_t fetchdat)
#endif
if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSEXIT: CS MSR is zero");
if (!(cr0 & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode");
if (CS & 3) return internal_illegal("SYSEXIT: CPL not 0");
if (!(msw & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode");
if (CPL) return internal_illegal("SYSEXIT: CPL not 0");
#ifdef SYSEXIT_LOG
x386_dynarec_log("SYSEXIT start:\n");
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX);
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32, ECX, EDX);
#endif
if (cpu_state.abrt) return 1;
@@ -124,12 +124,12 @@ static int opSYSEXIT(uint32_t fetchdat)
CS = ((cs_msr + 16) & 0xFFFC) | 3;
make_seg_data(sysexit_cs_seg_data, 0, 0xFFFFF, 11, 1, 3, 1, 1, 1, 0);
do_seg_load(&_cs, sysexit_cs_seg_data);
do_seg_load(&cpu_state.seg_cs, sysexit_cs_seg_data);
use32 = 0x300;
SS = CS + 8;
make_seg_data(sysexit_ss_seg_data, 0, 0xFFFFF, 3, 1, 3, 1, 1, 1, 0);
do_seg_load(&_ss, sysexit_ss_seg_data);
do_seg_load(&cpu_state.seg_ss, sysexit_ss_seg_data);
stack32 = 1;
flushmmucache_cr3();
@@ -142,10 +142,10 @@ static int opSYSEXIT(uint32_t fetchdat)
#ifdef SYSEXIT_LOG
x386_dynarec_log("SYSEXIT completed:\n");
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX);
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32, ECX, EDX);
#endif
return 0;
@@ -202,7 +202,7 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
/* if (cr0 & 1)
{
x87_pc_seg &= 0xFFFC;
x87_pc_seg |= ((_cs.access >> 5) & 3);
x87_pc_seg |= ((cpu_state.seg_cs.access >> 5) & 3);
} */
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
@@ -380,7 +380,7 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
/* if (cr0 & 1)
{
x87_pc_seg &= 0xFFFC;
x87_pc_seg |= ((_cs.access >> 5) & 3);
x87_pc_seg |= ((cpu_state.seg_cs.access >> 5) & 3);
} */
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);

View File

@@ -49,7 +49,9 @@ static int opINCDEC_b_a16(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp=geteab(); if (cpu_state.abrt) return 1;
if (rmdat&0x38)
@@ -70,7 +72,9 @@ static int opINCDEC_b_a32(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp=geteab(); if (cpu_state.abrt) return 1;
if (rmdat&0x38)

View File

@@ -1,7 +1,7 @@
static int opINT3(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
return 1;
@@ -15,7 +15,7 @@ static int opINT3(uint32_t fetchdat)
static int opINT1(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
return 1;
@@ -31,7 +31,7 @@ static int opINT(uint32_t fetchdat)
int cycles_old = cycles; UN_USED(cycles_old);
uint8_t temp = getbytef();
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
if (cr4 & CR4_VME)
{
@@ -72,7 +72,7 @@ static int opINTO(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
return 1;

View File

@@ -247,12 +247,12 @@ static int opJMP_r32(uint32_t fetchdat)
static int opJMP_far_a16(uint32_t fetchdat)
{
uint16_t addr, seg;
uint32_t oxpc;
uint32_t old_pc;
addr = getwordf();
seg = getword(); if (cpu_state.abrt) return 1;
oxpc = cpu_state.pc;
old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, oxpc);
loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0);
PREFETCH_FLUSH();
@@ -261,12 +261,12 @@ static int opJMP_far_a16(uint32_t fetchdat)
static int opJMP_far_a32(uint32_t fetchdat)
{
uint16_t seg;
uint32_t addr, oxpc;
uint32_t addr, old_pc;
addr = getlong();
seg = getword(); if (cpu_state.abrt) return 1;
oxpc = cpu_state.pc;
old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, oxpc);
loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0);
PREFETCH_FLUSH();

View File

@@ -70,15 +70,15 @@ static int opF6_a16(uint32_t fetchdat)
int8_t temps;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
{
if (cpu_mod != 3) {
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
}
dst = geteab(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
case 0x00: /*TEST b,#8*/
case 0x08:
case 0x08:
src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
setznp8(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -86,11 +86,15 @@ static int opF6_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
case 0x10: /*NOT b*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteab(~dst); if (cpu_state.abrt) return 1;
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
break;
case 0x18: /*NEG b*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteab(0 - dst); if (cpu_state.abrt) return 1;
setsub8(0, dst);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
@@ -99,8 +103,8 @@ static int opF6_a16(uint32_t fetchdat)
case 0x20: /*MUL AL,b*/
AX = AL * dst;
flags_rebuild();
if (AH) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (AH) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(13);
PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
@@ -108,8 +112,8 @@ static int opF6_a16(uint32_t fetchdat)
tempws = (int)((int8_t)AL) * (int)((int8_t)dst);
AX = tempws & 0xffff;
flags_rebuild();
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(14);
PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
@@ -123,8 +127,8 @@ static int opF6_a16(uint32_t fetchdat)
if (!cpu_iscyrix)
{
flags_rebuild();
flags |= 0x8D5; /*Not a Cyrix*/
flags &= ~1;
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
cpu_state.flags &= ~1;
}
}
else
@@ -146,8 +150,8 @@ static int opF6_a16(uint32_t fetchdat)
if (!cpu_iscyrix)
{
flags_rebuild();
flags|=0x8D5; /*Not a Cyrix*/
flags &= ~1;
cpu_state.flags|=0x8D5; /*Not a Cyrix*/
cpu_state.flags &= ~1;
}
}
else
@@ -173,11 +177,13 @@ static int opF6_a32(uint32_t fetchdat)
int8_t temps;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteab(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
case 0x00: /*TEST b,#8*/
case 0x08:
case 0x08:
src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
setznp8(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -185,11 +191,15 @@ static int opF6_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
case 0x10: /*NOT b*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteab(~dst); if (cpu_state.abrt) return 1;
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
break;
case 0x18: /*NEG b*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteab(0 - dst); if (cpu_state.abrt) return 1;
setsub8(0, dst);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
@@ -198,8 +208,8 @@ static int opF6_a32(uint32_t fetchdat)
case 0x20: /*MUL AL,b*/
AX = AL * dst;
flags_rebuild();
if (AH) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (AH) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(13);
PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
@@ -207,8 +217,8 @@ static int opF6_a32(uint32_t fetchdat)
tempws = (int)((int8_t)AL) * (int)((int8_t)dst);
AX = tempws & 0xffff;
flags_rebuild();
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(14);
PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
@@ -222,8 +232,8 @@ static int opF6_a32(uint32_t fetchdat)
if (!cpu_iscyrix)
{
flags_rebuild();
flags |= 0x8D5; /*Not a Cyrix*/
flags &= ~1;
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
cpu_state.flags &= ~1;
}
}
else
@@ -245,8 +255,8 @@ static int opF6_a32(uint32_t fetchdat)
if (!cpu_iscyrix)
{
flags_rebuild();
flags|=0x8D5; /*Not a Cyrix*/
flags &= ~1;
cpu_state.flags|=0x8D5; /*Not a Cyrix*/
cpu_state.flags &= ~1;
}
}
else
@@ -275,6 +285,8 @@ static int opF7_w_a16(uint32_t fetchdat)
uint16_t src, dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteaw(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
@@ -287,11 +299,15 @@ static int opF7_w_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
case 0x10: /*NOT w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(~dst); if (cpu_state.abrt) return 1;
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
break;
case 0x18: /*NEG w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(0 - dst); if (cpu_state.abrt) return 1;
setsub16(0, dst);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
@@ -302,8 +318,8 @@ static int opF7_w_a16(uint32_t fetchdat)
AX = templ & 0xFFFF;
DX = templ >> 16;
flags_rebuild();
if (DX) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (DX) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(21);
PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
@@ -312,8 +328,8 @@ static int opF7_w_a16(uint32_t fetchdat)
AX = templ & 0xFFFF;
DX = templ >> 16;
flags_rebuild();
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(22);
PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
@@ -362,11 +378,13 @@ static int opF7_w_a16(uint32_t fetchdat)
static int opF7_w_a32(uint32_t fetchdat)
{
uint32_t templ, templ2;
int tempws, tempws2 = 0;
int tempws, tempws2 = 1;
int16_t temps16;
uint16_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteaw(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
@@ -379,11 +397,15 @@ static int opF7_w_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
case 0x10: /*NOT w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(~dst); if (cpu_state.abrt) return 1;
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
break;
case 0x18: /*NEG w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(0 - dst); if (cpu_state.abrt) return 1;
setsub16(0, dst);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
@@ -394,8 +416,8 @@ static int opF7_w_a32(uint32_t fetchdat)
AX = templ & 0xFFFF;
DX = templ >> 16;
flags_rebuild();
if (DX) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (DX) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(21);
PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
@@ -404,8 +426,8 @@ static int opF7_w_a32(uint32_t fetchdat)
AX = templ & 0xFFFF;
DX = templ >> 16;
flags_rebuild();
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(22);
PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
@@ -458,6 +480,8 @@ static int opF7_l_a16(uint32_t fetchdat)
uint32_t src, dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteal(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
@@ -471,11 +495,15 @@ static int opF7_l_a16(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
break;
case 0x10: /*NOT l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(~dst); if (cpu_state.abrt) return 1;
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
break;
case 0x18: /*NEG l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(0 - dst); if (cpu_state.abrt) return 1;
setsub32(0, dst);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
@@ -486,8 +514,8 @@ static int opF7_l_a16(uint32_t fetchdat)
EAX = temp64 & 0xffffffff;
EDX = temp64 >> 32;
flags_rebuild();
if (EDX) flags |= (C_FLAG|V_FLAG);
else flags &= ~(C_FLAG|V_FLAG);
if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG);
else cpu_state.flags &= ~(C_FLAG|V_FLAG);
CLOCK_CYCLES(21);
PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
break;
@@ -496,8 +524,8 @@ static int opF7_l_a16(uint32_t fetchdat)
EAX = temp64 & 0xffffffff;
EDX = temp64 >> 32;
flags_rebuild();
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(38);
PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
break;
@@ -528,6 +556,8 @@ static int opF7_l_a32(uint32_t fetchdat)
uint32_t src, dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteal(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
@@ -541,11 +571,15 @@ static int opF7_l_a32(uint32_t fetchdat)
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
break;
case 0x10: /*NOT l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(~dst); if (cpu_state.abrt) return 1;
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
break;
case 0x18: /*NEG l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(0 - dst); if (cpu_state.abrt) return 1;
setsub32(0, dst);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
@@ -556,8 +590,8 @@ static int opF7_l_a32(uint32_t fetchdat)
EAX = temp64 & 0xffffffff;
EDX = temp64 >> 32;
flags_rebuild();
if (EDX) flags |= (C_FLAG|V_FLAG);
else flags &= ~(C_FLAG|V_FLAG);
if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG);
else cpu_state.flags &= ~(C_FLAG|V_FLAG);
CLOCK_CYCLES(21);
PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
break;
@@ -566,8 +600,8 @@ static int opF7_l_a32(uint32_t fetchdat)
EAX = temp64 & 0xffffffff;
EDX = temp64 >> 32;
flags_rebuild();
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG);
else flags &= ~(C_FLAG | V_FLAG);
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(38);
PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
break;
@@ -596,12 +630,12 @@ static int opF7_l_a32(uint32_t fetchdat)
static int opHLT(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x86gpf(NULL,0);
return 1;
}
if (!((flags&I_FLAG) && pic_intpending))
if (!((cpu_state.flags&I_FLAG) && pic_intpending))
{
CLOCK_CYCLES_ALWAYS(100);
cpu_state.pc--;
@@ -637,6 +671,7 @@ static int opBOUND_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
low = geteaw();
high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
@@ -656,6 +691,7 @@ static int opBOUND_w_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
low = geteaw();
high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
@@ -676,6 +712,7 @@ static int opBOUND_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
low = geteal();
high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
@@ -695,6 +732,7 @@ static int opBOUND_l_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
low = geteal();
high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
@@ -712,7 +750,7 @@ static int opBOUND_l_a32(uint32_t fetchdat)
static int opCLTS(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't CLTS\n");
x86gpf(NULL,0);
@@ -755,7 +793,7 @@ static int opLOADALL(uint32_t fetchdat)
return 1;
}
msw = (msw & 1) | readmemw(0, 0x806);
flags = (readmemw(0, 0x818) & 0xffd5) | 2;
cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2;
flags_extract();
tr.seg = readmemw(0, 0x816);
cpu_state.pc = readmemw(0, 0x81A);
@@ -773,22 +811,22 @@ static int opLOADALL(uint32_t fetchdat)
CX = readmemw(0, 0x832);
AX = readmemw(0, 0x834);
es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16);
_es.access = readmemb(0, 0x839);
_es.limit = readmemw(0, 0x83A);
cpu_state.seg_es.access = readmemb(0, 0x839);
cpu_state.seg_es.limit = readmemw(0, 0x83A);
cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16);
_cs.access = readmemb(0, 0x83F);
_cs.limit = readmemw(0, 0x840);
cpu_state.seg_cs.access = readmemb(0, 0x83F);
cpu_state.seg_cs.limit = readmemw(0, 0x840);
ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16);
_ss.access = readmemb(0, 0x845);
_ss.limit = readmemw(0, 0x846);
if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff)
cpu_state.seg_ss.access = readmemb(0, 0x845);
cpu_state.seg_ss.limit = readmemw(0, 0x846);
if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16);
_ds.access = readmemb(0, 0x84B);
_ds.limit = readmemw(0, 0x84C);
if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff)
cpu_state.seg_ds.access = readmemb(0, 0x84B);
cpu_state.seg_ds.limit = readmemw(0, 0x84C);
if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
@@ -829,8 +867,8 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
s->base = readmeml(0, addr + 4);
s->limit = readmeml(0, addr + 8);
if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0;
if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0;
if (s == &cpu_state.seg_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0;
if (s == &cpu_state.seg_ss) stack32 = (segdat3 & 0x40) ? 1 : 0;
cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32);
if (use32)
cpu_cur_status |= CPU_STATUS_USE32;
@@ -839,14 +877,14 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
set_segment_limit(s, segdat3);
if (s == &_ds)
if (s == &cpu_state.seg_ds)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
}
if (s == &_ss)
if (s == &cpu_state.seg_ss)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
@@ -860,8 +898,8 @@ static int opLOADALL386(uint32_t fetchdat)
uint32_t la_addr = es + EDI;
cr0 = readmeml(0, la_addr);
flags = readmemw(0, la_addr + 4);
eflags = readmemw(0, la_addr + 6);
cpu_state.flags = readmemw(0, la_addr + 4);
cpu_state.eflags = readmemw(0, la_addr + 6);
flags_extract();
cpu_state.pc = readmeml(0, la_addr + 8);
EDI = readmeml(0, la_addr + 0xC);
@@ -887,12 +925,12 @@ static int opLOADALL386(uint32_t fetchdat)
loadall_load_segment(la_addr + 0x60, &idt);
loadall_load_segment(la_addr + 0x6c, &gdt);
loadall_load_segment(la_addr + 0x78, &ldt);
loadall_load_segment(la_addr + 0x84, &_gs);
loadall_load_segment(la_addr + 0x90, &_fs);
loadall_load_segment(la_addr + 0x9c, &_ds);
loadall_load_segment(la_addr + 0xa8, &_ss);
loadall_load_segment(la_addr + 0xb4, &_cs);
loadall_load_segment(la_addr + 0xc0, &_es);
loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs);
loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs);
loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds);
loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss);
loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs);
loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
@@ -915,7 +953,7 @@ static int opCPUID(uint32_t fetchdat)
static int opRDMSR(uint32_t fetchdat)
{
if (cpu_hasMSR)
if (cpu_has_feature(CPU_FEATURE_MSR))
{
cpu_RDMSR();
CLOCK_CYCLES(9);
@@ -928,7 +966,7 @@ static int opRDMSR(uint32_t fetchdat)
static int opWRMSR(uint32_t fetchdat)
{
if (cpu_hasMSR)
if (cpu_has_feature(CPU_FEATURE_MSR))
{
cpu_WRMSR();
CLOCK_CYCLES(9);

View File

@@ -11,12 +11,13 @@
} \
else \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \
CLOCK_CYCLES(2); \
}
#define MMX_ENTER() \
if (!cpu_hasMMX) \
if (!cpu_has_feature(CPU_FEATURE_MMX)) \
{ \
cpu_state.pc = cpu_state.oldpc; \
x86illegal(); \
@@ -31,7 +32,7 @@
static int opEMMS(uint32_t fetchdat)
{
if (!cpu_hasMMX)
if (!cpu_has_feature(CPU_FEATURE_MMX))
{
cpu_state.pc = cpu_state.oldpc;
x86illegal();

View File

@@ -293,7 +293,8 @@ static int opPMULLW_a16(uint32_t fetchdat)
else
{
MMX_REG src;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
cpu_state.MM[cpu_reg].w[0] *= src.w[0];
@@ -320,7 +321,8 @@ static int opPMULLW_a32(uint32_t fetchdat)
else
{
MMX_REG src;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
cpu_state.MM[cpu_reg].w[0] *= src.w[0];
@@ -348,7 +350,8 @@ static int opPMULHW_a16(uint32_t fetchdat)
else
{
MMX_REG src;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16;
@@ -375,7 +378,8 @@ static int opPMULHW_a32(uint32_t fetchdat)
else
{
MMX_REG src;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16;

View File

@@ -166,7 +166,7 @@ static int opPCMPEQD_a32(uint32_t fetchdat)
MMX_ENTER();
fetch_ea_16(fetchdat);
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
@@ -195,7 +195,7 @@ static int opPCMPGTD_a32(uint32_t fetchdat)
MMX_ENTER();
fetch_ea_16(fetchdat);
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;

View File

@@ -13,6 +13,7 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat)
{
uint32_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
@@ -36,6 +37,7 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat)
{
uint32_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
@@ -57,6 +59,7 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
CLOCK_CYCLES(2);
@@ -75,6 +78,7 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
CLOCK_CYCLES(2);
@@ -96,6 +100,7 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat)
{
uint64_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
cpu_state.MM[cpu_reg].q = dst;
CLOCK_CYCLES(2);
@@ -115,7 +120,8 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat)
else
{
uint64_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
cpu_state.MM[cpu_reg].q = dst;
CLOCK_CYCLES(2);
@@ -135,6 +141,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
CLOCK_CYCLES(2);
@@ -153,6 +160,7 @@ static int opMOVQ_mm_q_a32(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
CLOCK_CYCLES(2);

View File

@@ -12,6 +12,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat)
{
uint32_t src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0;
cpu_state.MM[cpu_reg].l[1] = src;
@@ -33,6 +34,7 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat)
{
uint32_t src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0;
cpu_state.MM[cpu_reg].l[1] = src;

View File

@@ -6,6 +6,7 @@
} \
else \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \
CLOCK_CYCLES(2); \
}

View File

@@ -181,7 +181,8 @@ static int opMOV_b_imm_a16(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_16(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
ILLEGAL_ON((rmdat & 0x38) != 0);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
seteab(temp);
@@ -193,7 +194,8 @@ static int opMOV_b_imm_a32(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_32(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
ILLEGAL_ON((rmdat & 0x38) != 0);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = getbyte(); if (cpu_state.abrt) return 1;
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
seteab(temp);
@@ -206,7 +208,8 @@ static int opMOV_w_imm_a16(uint32_t fetchdat)
{
uint16_t temp;
fetch_ea_16(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
ILLEGAL_ON((rmdat & 0x38) != 0);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = getword(); if (cpu_state.abrt) return 1;
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1);
seteaw(temp);
@@ -218,7 +221,8 @@ static int opMOV_w_imm_a32(uint32_t fetchdat)
{
uint16_t temp;
fetch_ea_32(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
ILLEGAL_ON((rmdat & 0x38) != 0);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = getword(); if (cpu_state.abrt) return 1;
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1);
seteaw(temp);
@@ -230,7 +234,8 @@ static int opMOV_l_imm_a16(uint32_t fetchdat)
{
uint32_t temp;
fetch_ea_16(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
ILLEGAL_ON((rmdat & 0x38) != 0);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = getlong(); if (cpu_state.abrt) return 1;
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
seteal(temp);
@@ -242,7 +247,8 @@ static int opMOV_l_imm_a32(uint32_t fetchdat)
{
uint32_t temp;
fetch_ea_32(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
ILLEGAL_ON((rmdat & 0x38) != 0);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = getlong(); if (cpu_state.abrt) return 1;
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
seteal(temp);
@@ -256,6 +262,7 @@ static int opMOV_AL_a16(uint32_t fetchdat)
{
uint8_t temp;
uint16_t addr = getwordf();
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, addr, addr);
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AL = temp;
@@ -267,6 +274,7 @@ static int opMOV_AL_a32(uint32_t fetchdat)
{
uint8_t temp;
uint32_t addr = getlong();
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, addr, addr);
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AL = temp;
@@ -278,7 +286,8 @@ static int opMOV_AX_a16(uint32_t fetchdat)
{
uint16_t temp;
uint16_t addr = getwordf();
CHECK_READ(cpu_state.ea_seg, addr, addr + 1);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, addr, addr+1);
temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
@@ -289,7 +298,8 @@ static int opMOV_AX_a32(uint32_t fetchdat)
{
uint16_t temp;
uint32_t addr = getlong();
CHECK_READ(cpu_state.ea_seg, addr, addr + 1);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, addr, addr+1);
temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
@@ -300,7 +310,8 @@ static int opMOV_EAX_a16(uint32_t fetchdat)
{
uint32_t temp;
uint16_t addr = getwordf();
CHECK_READ(cpu_state.ea_seg, addr, addr + 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, addr, addr+3);
temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
EAX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
@@ -311,7 +322,8 @@ static int opMOV_EAX_a32(uint32_t fetchdat)
{
uint32_t temp;
uint32_t addr = getlong();
CHECK_READ(cpu_state.ea_seg, addr, addr + 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, addr, addr+3);
temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
EAX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
@@ -322,6 +334,7 @@ static int opMOV_EAX_a32(uint32_t fetchdat)
static int opMOV_a16_AL(uint32_t fetchdat)
{
uint16_t addr = getwordf();
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, addr, addr);
writememb(cpu_state.ea_seg->base, addr, AL);
CLOCK_CYCLES((is486) ? 1 : 2);
@@ -331,6 +344,7 @@ static int opMOV_a16_AL(uint32_t fetchdat)
static int opMOV_a32_AL(uint32_t fetchdat)
{
uint32_t addr = getlong();
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, addr, addr);
writememb(cpu_state.ea_seg->base, addr, AL);
CLOCK_CYCLES((is486) ? 1 : 2);
@@ -340,6 +354,7 @@ static int opMOV_a32_AL(uint32_t fetchdat)
static int opMOV_a16_AX(uint32_t fetchdat)
{
uint16_t addr = getwordf();
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1);
writememw(cpu_state.ea_seg->base, addr, AX);
CLOCK_CYCLES((is486) ? 1 : 2);
@@ -349,6 +364,7 @@ static int opMOV_a16_AX(uint32_t fetchdat)
static int opMOV_a32_AX(uint32_t fetchdat)
{
uint32_t addr = getlong(); if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1);
writememw(cpu_state.ea_seg->base, addr, AX);
CLOCK_CYCLES((is486) ? 1 : 2);
@@ -358,6 +374,7 @@ static int opMOV_a32_AX(uint32_t fetchdat)
static int opMOV_a16_EAX(uint32_t fetchdat)
{
uint16_t addr = getwordf();
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3);
writememl(cpu_state.ea_seg->base, addr, EAX);
CLOCK_CYCLES((is486) ? 1 : 2);
@@ -367,6 +384,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat)
static int opMOV_a32_EAX(uint32_t fetchdat)
{
uint32_t addr = getlong(); if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3);
writememl(cpu_state.ea_seg->base, addr, EAX);
CLOCK_CYCLES((is486) ? 1 : 2);
@@ -378,8 +396,8 @@ static int opMOV_a32_EAX(uint32_t fetchdat)
static int opLEA_w_a16(uint32_t fetchdat)
{
fetch_ea_16(fetchdat);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr;
ILLEGAL_ON(cpu_mod == 3);
cpu_state.regs[cpu_reg].w = cpu_state.eaaddr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
return 0;
@@ -387,8 +405,8 @@ static int opLEA_w_a16(uint32_t fetchdat)
static int opLEA_w_a32(uint32_t fetchdat)
{
fetch_ea_32(fetchdat);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr;
ILLEGAL_ON(cpu_mod == 3);
cpu_state.regs[cpu_reg].w = cpu_state.eaaddr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1);
return 0;
@@ -397,8 +415,8 @@ static int opLEA_w_a32(uint32_t fetchdat)
static int opLEA_l_a16(uint32_t fetchdat)
{
fetch_ea_16(fetchdat);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].l = ((cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr) & 0xffff;
ILLEGAL_ON(cpu_mod == 3);
cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
return 0;
@@ -406,8 +424,8 @@ static int opLEA_l_a16(uint32_t fetchdat)
static int opLEA_l_a32(uint32_t fetchdat)
{
fetch_ea_32(fetchdat);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].l = (cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr;
ILLEGAL_ON(cpu_mod == 3);
cpu_state.regs[cpu_reg].l = cpu_state.eaaddr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1);
return 0;
@@ -419,9 +437,9 @@ static int opXLAT_a16(uint32_t fetchdat)
{
uint32_t addr = (BX + AL)&0xFFFF;
uint8_t temp;
cpu_state.last_ea = addr;
temp = readmemb(cpu_state.ea_seg->base, addr);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AL = temp;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
@@ -431,9 +449,9 @@ static int opXLAT_a32(uint32_t fetchdat)
{
uint32_t addr = EBX + AL;
uint8_t temp;
cpu_state.last_ea = addr;
temp = readmemb(cpu_state.ea_seg->base, addr);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AL = temp;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1);
@@ -451,6 +469,7 @@ static int opMOV_b_r_a16(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
seteab(getr8(cpu_reg));
CLOCK_CYCLES(is486 ? 1 : 2);
@@ -469,6 +488,7 @@ static int opMOV_b_r_a32(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
seteab(getr8(cpu_reg));
CLOCK_CYCLES(is486 ? 1 : 2);
@@ -487,6 +507,7 @@ static int opMOV_w_r_a16(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
seteaw(cpu_state.regs[cpu_reg].w);
CLOCK_CYCLES(is486 ? 1 : 2);
@@ -505,6 +526,7 @@ static int opMOV_w_r_a32(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
seteaw(cpu_state.regs[cpu_reg].w);
CLOCK_CYCLES(is486 ? 1 : 2);
@@ -523,6 +545,7 @@ static int opMOV_l_r_a16(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
seteal(cpu_state.regs[cpu_reg].l);
CLOCK_CYCLES(is486 ? 1 : 2);
@@ -541,6 +564,7 @@ static int opMOV_l_r_a32(uint32_t fetchdat)
}
else
{
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
seteal(cpu_state.regs[cpu_reg].l);
CLOCK_CYCLES(is486 ? 1 : 2);
@@ -561,6 +585,7 @@ static int opMOV_r_b_a16(uint32_t fetchdat)
else
{
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
temp = geteab(); if (cpu_state.abrt) return 1;
setr8(cpu_reg, temp);
@@ -581,6 +606,7 @@ static int opMOV_r_b_a32(uint32_t fetchdat)
else
{
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
temp = geteab(); if (cpu_state.abrt) return 1;
setr8(cpu_reg, temp);
@@ -601,6 +627,7 @@ static int opMOV_r_w_a16(uint32_t fetchdat)
else
{
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = temp;
@@ -621,6 +648,7 @@ static int opMOV_r_w_a32(uint32_t fetchdat)
else
{
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = temp;
@@ -641,6 +669,7 @@ static int opMOV_r_l_a16(uint32_t fetchdat)
else
{
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
temp = geteal(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = temp;
@@ -661,6 +690,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
else
{
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
temp = geteal(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = temp;
@@ -670,6 +700,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
return 0;
}
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
#define opCMOV(condition) \
static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \
{ \
@@ -681,6 +712,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
else \
{ \
uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \
temp = geteaw(); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].w = temp; \
@@ -699,6 +731,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
else \
{ \
uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \
temp = geteaw(); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].w = temp; \
@@ -717,6 +750,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
else \
{ \
uint32_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \
temp = geteal(); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].l = temp; \
@@ -736,6 +770,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
{ \
uint32_t temp; \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \
SEG_CHECK_READ(cpu_state.ea_seg); \
temp = geteal(); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].l = temp; \
} \
@@ -760,3 +795,4 @@ opCMOV(L)
opCMOV(NL)
opCMOV(LE)
opCMOV(NLE)
#endif

View File

@@ -1,6 +1,6 @@
static int opMOV_r_CRx_a16(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load from CRx\n");
x86gpf(NULL, 0);
@@ -21,7 +21,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat)
cpu_state.regs[cpu_rm].l = cr3;
break;
case 4:
if (cpu_hasCR4)
if (cpu_has_feature(CPU_FEATURE_CR4))
{
cpu_state.regs[cpu_rm].l = cr4;
break;
@@ -38,7 +38,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat)
}
static int opMOV_r_CRx_a32(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load from CRx\n");
x86gpf(NULL, 0);
@@ -59,7 +59,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat)
cpu_state.regs[cpu_rm].l = cr3;
break;
case 4:
if (cpu_hasCR4)
if (cpu_has_feature(CPU_FEATURE_CR4))
{
cpu_state.regs[cpu_rm].l = cr4;
break;
@@ -77,7 +77,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat)
static int opMOV_r_DRx_a16(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load from DRx\n");
x86gpf(NULL, 0);
@@ -91,7 +91,7 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat)
}
static int opMOV_r_DRx_a32(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load from DRx\n");
x86gpf(NULL, 0);
@@ -108,7 +108,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat)
{
uint32_t old_cr0 = cr0;
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load CRx\n");
x86gpf(NULL,0);
@@ -144,7 +144,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat)
flushmmucache();
break;
case 4:
if (cpu_hasCR4)
if (cpu_has_feature(CPU_FEATURE_CR4))
{
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
@@ -164,7 +164,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
{
uint32_t old_cr0 = cr0;
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load CRx\n");
x86gpf(NULL,0);
@@ -200,7 +200,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
flushmmucache();
break;
case 4:
if (cpu_hasCR4)
if (cpu_has_feature(CPU_FEATURE_CR4))
{
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
@@ -219,7 +219,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
static int opMOV_DRx_r_a16(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load DRx\n");
x86gpf(NULL, 0);
@@ -233,7 +233,7 @@ static int opMOV_DRx_r_a16(uint32_t fetchdat)
}
static int opMOV_DRx_r_a32(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load DRx\n");
x86gpf(NULL, 0);
@@ -248,7 +248,7 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat)
static int opMOV_r_TRx_a16(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load from TRx\n");
x86gpf(NULL, 0);
@@ -262,7 +262,7 @@ static int opMOV_r_TRx_a16(uint32_t fetchdat)
}
static int opMOV_r_TRx_a32(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load from TRx\n");
x86gpf(NULL, 0);
@@ -277,7 +277,7 @@ static int opMOV_r_TRx_a32(uint32_t fetchdat)
static int opMOV_TRx_r_a16(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load TRx\n");
x86gpf(NULL, 0);
@@ -290,7 +290,7 @@ static int opMOV_TRx_r_a16(uint32_t fetchdat)
}
static int opMOV_TRx_r_a32(uint32_t fetchdat)
{
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x386_dynarec_log("Can't load TRx\n");
x86gpf(NULL, 0);

View File

@@ -1,7 +1,9 @@
static int opMOV_w_seg_a16(uint32_t fetchdat)
{
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38)
{
case 0x00: /*ES*/
@@ -31,7 +33,9 @@ static int opMOV_w_seg_a16(uint32_t fetchdat)
static int opMOV_w_seg_a32(uint32_t fetchdat)
{
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38)
{
case 0x00: /*ES*/
@@ -62,7 +66,9 @@ static int opMOV_w_seg_a32(uint32_t fetchdat)
static int opMOV_l_seg_a16(uint32_t fetchdat)
{
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38)
{
case 0x00: /*ES*/
@@ -98,7 +104,9 @@ static int opMOV_l_seg_a16(uint32_t fetchdat)
static int opMOV_l_seg_a32(uint32_t fetchdat)
{
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38)
{
case 0x00: /*ES*/
@@ -137,34 +145,35 @@ static int opMOV_seg_w_a16(uint32_t fetchdat)
uint16_t new_seg;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_seg=geteaw(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
case 0x00: /*ES*/
loadseg(new_seg, &_es);
loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &_ds);
loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &_ss);
loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt) return 1;
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt) return 1;
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &_fs);
loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &_gs);
loadseg(new_seg, &cpu_state.seg_gs);
break;
}
@@ -177,34 +186,35 @@ static int opMOV_seg_w_a32(uint32_t fetchdat)
uint16_t new_seg;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_seg=geteaw(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
case 0x00: /*ES*/
loadseg(new_seg, &_es);
loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &_ds);
loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &_ss);
loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt) return 1;
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt) return 1;
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &_fs);
loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &_gs);
loadseg(new_seg, &cpu_state.seg_gs);
break;
}
@@ -220,9 +230,10 @@ static int opLDS_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
@@ -235,9 +246,10 @@ static int opLDS_w_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
@@ -251,9 +263,10 @@ static int opLDS_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
@@ -267,9 +280,10 @@ static int opLDS_l_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
@@ -283,9 +297,10 @@ static int opLSS_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
@@ -298,9 +313,10 @@ static int opLSS_w_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
@@ -314,9 +330,10 @@ static int opLSS_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
@@ -330,9 +347,10 @@ static int opLSS_l_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
@@ -346,6 +364,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
uint16_t addr, seg; \
\
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
@@ -362,6 +381,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
uint16_t addr, seg; \
\
fetch_ea_32(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
@@ -379,6 +399,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
uint16_t seg; \
\
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
@@ -396,6 +417,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
uint16_t seg; \
\
fetch_ea_32(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
@@ -407,6 +429,6 @@ static int opLSS_l_a32(uint32_t fetchdat)
return 0; \
}
opLsel(ES, _es)
opLsel(FS, _fs)
opLsel(GS, _gs)
opLsel(ES, cpu_state.seg_es)
opLsel(FS, cpu_state.seg_fs)
opLsel(GS, cpu_state.seg_gs)

View File

@@ -3,6 +3,8 @@ static int opMOVZX_w_b_a16(uint32_t fetchdat)
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
@@ -15,6 +17,8 @@ static int opMOVZX_w_b_a32(uint32_t fetchdat)
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
@@ -27,6 +31,8 @@ static int opMOVZX_l_b_a16(uint32_t fetchdat)
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
@@ -39,6 +45,8 @@ static int opMOVZX_l_b_a32(uint32_t fetchdat)
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
@@ -51,6 +59,8 @@ static int opMOVZX_w_w_a16(uint32_t fetchdat)
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = temp;
@@ -63,6 +73,8 @@ static int opMOVZX_w_w_a32(uint32_t fetchdat)
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = temp;
@@ -75,6 +87,8 @@ static int opMOVZX_l_w_a16(uint32_t fetchdat)
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
@@ -87,6 +101,8 @@ static int opMOVZX_l_w_a32(uint32_t fetchdat)
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
@@ -100,6 +116,8 @@ static int opMOVSX_w_b_a16(uint32_t fetchdat)
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
if (temp & 0x80)
@@ -114,6 +132,8 @@ static int opMOVSX_w_b_a32(uint32_t fetchdat)
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
if (temp & 0x80)
@@ -128,6 +148,8 @@ static int opMOVSX_l_b_a16(uint32_t fetchdat)
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x80)
@@ -142,6 +164,8 @@ static int opMOVSX_l_b_a32(uint32_t fetchdat)
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x80)
@@ -156,6 +180,8 @@ static int opMOVSX_l_w_a16(uint32_t fetchdat)
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x8000)
@@ -170,6 +196,8 @@ static int opMOVSX_l_w_a32(uint32_t fetchdat)
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x8000)

View File

@@ -1,6 +1,6 @@
static int opRDTSC(uint32_t fetchdat)
{
if (!cpu_hasrdtsc)
if (!cpu_has_feature(CPU_FEATURE_RDTSC))
{
cpu_state.pc = cpu_state.oldpc;
x86illegal();

View File

@@ -4,14 +4,16 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat)
int16_t tempw, tempw2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw(); if (cpu_state.abrt) return 1;
tempw2 = getword(); if (cpu_state.abrt) return 1;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
@@ -24,14 +26,16 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat)
int16_t tempw, tempw2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw(); if (cpu_state.abrt) return 1;
tempw2 = getword(); if (cpu_state.abrt) return 1;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
@@ -45,14 +49,16 @@ static int opIMUL_l_il_a16(uint32_t fetchdat)
int32_t templ, templ2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
templ2 = getlong(); if (cpu_state.abrt) return 1;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(25);
@@ -65,14 +71,16 @@ static int opIMUL_l_il_a32(uint32_t fetchdat)
int32_t templ, templ2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
templ2 = getlong(); if (cpu_state.abrt) return 1;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(25);
@@ -86,6 +94,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat)
int16_t tempw, tempw2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw(); if (cpu_state.abrt) return 1;
tempw2 = getbyte(); if (cpu_state.abrt) return 1;
@@ -93,8 +103,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat)
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
@@ -107,6 +117,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat)
int16_t tempw, tempw2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw(); if (cpu_state.abrt) return 1;
tempw2 = getbyte(); if (cpu_state.abrt) return 1;
@@ -114,8 +126,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat)
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
@@ -129,14 +141,17 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat)
int32_t templ, templ2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
templ2 = getbyte(); if (cpu_state.abrt) return 1;
if (templ2 & 0x80) templ2 |= 0xffffff00;
temp64 = ((int64_t)templ)*((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(20);
@@ -149,14 +164,17 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat)
int32_t templ, templ2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
templ2 = getbyte(); if (cpu_state.abrt) return 1;
if (templ2 & 0x80) templ2 |= 0xffffff00;
temp64 = ((int64_t)templ)*((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(20);
@@ -171,12 +189,15 @@ static int opIMUL_w_w_a16(uint32_t fetchdat)
int32_t templ;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(18);
PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0);
@@ -187,12 +208,15 @@ static int opIMUL_w_w_a32(uint32_t fetchdat)
int32_t templ;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(18);
PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1);
@@ -204,12 +228,15 @@ static int opIMUL_l_l_a16(uint32_t fetchdat)
int64_t temp64;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(30);
PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0);
@@ -220,12 +247,15 @@ static int opIMUL_l_l_a32(uint32_t fetchdat)
int64_t temp64;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
else flags &= ~(C_FLAG | V_FLAG);
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(30);
PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1);

View File

@@ -5,6 +5,9 @@ static int opARPL_a16(uint32_t fetchdat)
NOTRM
fetch_ea_16(fetchdat);
/* x386_dynarec_log("ARPL_a16\n"); */
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
@@ -12,10 +15,10 @@ static int opARPL_a16(uint32_t fetchdat)
{
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
seteaw(temp_seg); if (cpu_state.abrt) return 1;
flags |= Z_FLAG;
cpu_state.flags |= Z_FLAG;
}
else
flags &= ~Z_FLAG;
cpu_state.flags &= ~Z_FLAG;
CLOCK_CYCLES(is486 ? 9 : 20);
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0);
@@ -28,6 +31,9 @@ static int opARPL_a32(uint32_t fetchdat)
NOTRM
fetch_ea_32(fetchdat);
/* x386_dynarec_log("ARPL_a32\n"); */
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
@@ -35,10 +41,10 @@ static int opARPL_a32(uint32_t fetchdat)
{
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
seteaw(temp_seg); if (cpu_state.abrt) return 1;
flags |= Z_FLAG;
cpu_state.flags |= Z_FLAG;
}
else
flags &= ~Z_FLAG;
cpu_state.flags &= ~Z_FLAG;
CLOCK_CYCLES(is486 ? 9 : 20);
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1);
@@ -53,11 +59,13 @@ static int opARPL_a32(uint32_t fetchdat)
\
NOTRM \
fetch_ea(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
\
sel = geteaw(); if (cpu_state.abrt) return 1; \
\
flags_rebuild(); \
if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/ \
if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
if (valid) \
{ \
@@ -65,7 +73,7 @@ static int opARPL_a32(uint32_t fetchdat)
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
cpl_override = 0; if (cpu_state.abrt) return 1; \
} \
flags &= ~Z_FLAG; \
cpu_state.flags &= ~Z_FLAG; \
if ((desc & 0x1f00) == 0x000) valid = 0; \
if ((desc & 0x1f00) == 0x800) valid = 0; \
if ((desc & 0x1f00) == 0xa00) valid = 0; \
@@ -77,7 +85,7 @@ static int opARPL_a32(uint32_t fetchdat)
} \
if (valid) \
{ \
flags |= Z_FLAG; \
cpu_state.flags |= Z_FLAG; \
cpl_override = 1; \
if (is32) \
cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \
@@ -103,10 +111,12 @@ opLAR(l_a32, fetch_ea_32, 1, 1)
\
NOTRM \
fetch_ea(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
\
sel = geteaw(); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
flags &= ~Z_FLAG; \
cpu_state.flags &= ~Z_FLAG; \
if (!(sel & 0xfffc)) return 0; /*Null selector*/ \
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
if (valid) \
@@ -125,7 +135,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1)
} \
if (valid) \
{ \
flags |= Z_FLAG; \
cpu_state.flags |= Z_FLAG; \
cpl_override = 1; \
if (is32) \
{ \
@@ -163,22 +173,28 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
switch (rmdat & 0x38)
{
case 0x00: /*SLDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(ldt.seg);
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
break;
case 0x08: /*STR*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(tr.seg);
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
break;
case 0x10: /*LLDT*/
if ((CPL || eflags&VM_FLAG) && (cr0&1))
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
{
x386_dynarec_log("Invalid LLDT!\n");
x86gpf(NULL,0);
return 1;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw(); if (cpu_state.abrt) return 1;
addr = (sel & ~7) + gdt.base;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
@@ -199,12 +215,14 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32);
break;
case 0x18: /*LTR*/
if ((CPL || eflags&VM_FLAG) && (cr0&1))
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
{
x386_dynarec_log("Invalid LTR!\n");
x86gpf(NULL,0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw(); if (cpu_state.abrt) return 1;
addr = (sel & ~7) + gdt.base;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
@@ -228,9 +246,11 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32);
break;
case 0x20: /*VERR*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
flags &= ~Z_FLAG;
cpu_state.flags &= ~Z_FLAG;
if (!(sel & 0xfffc)) return 0; /*Null selector*/
cpl_override = 1;
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
@@ -243,14 +263,16 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
if (dpl < CPL || dpl < (sel & 3)) valid = 0;
}
if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/
if (valid) flags |= Z_FLAG;
if (valid) cpu_state.flags |= Z_FLAG;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32);
break;
case 0x28: /*VERW*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
flags &= ~Z_FLAG;
cpu_state.flags &= ~Z_FLAG;
if (!(sel & 0xfffc)) return 0; /*Null selector*/
cpl_override = 1;
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
@@ -261,7 +283,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
if (dpl < CPL || dpl < (sel & 3)) valid = 0;
if (desc & 0x0800) valid = 0; /*Code*/
if (!(desc & 0x0200)) valid = 0; /*Read-only data*/
if (valid) flags |= Z_FLAG;
if (valid) cpu_state.flags |= Z_FLAG;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32);
break;
@@ -300,6 +322,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
switch (rmdat & 0x38)
{
case 0x00: /*SGDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(gdt.limit);
base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */
if (is286)
@@ -309,6 +333,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32);
break;
case 0x08: /*SIDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(idt.limit);
base = idt.base;
if (is286)
@@ -318,13 +344,15 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32);
break;
case 0x10: /*LGDT*/
if ((CPL || eflags&VM_FLAG) && (cr0&1))
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
{
x386_dynarec_log("Invalid LGDT!\n");
x86gpf(NULL,0);
break;
}
/* x386_dynarec_log("LGDT %08X:%08X\n", easeg, eaaddr); */
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
/* x386_dynarec_log(" %08X %04X\n", base, limit); */
@@ -335,13 +363,15 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32);
break;
case 0x18: /*LIDT*/
if ((CPL || eflags&VM_FLAG) && (cr0&1))
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
{
x386_dynarec_log("Invalid LIDT!\n");
x86gpf(NULL,0);
break;
}
/* x386_dynarec_log("LIDT %08X:%08X\n", easeg, eaaddr); */
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
/* x386_dynarec_log(" %08X %04X\n", base, limit); */
@@ -353,6 +383,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
break;
case 0x20: /*SMSW*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is486) seteaw(msw);
else if (is386) seteaw(msw | 0xFF00);
else seteaw(msw | 0xFFF0);
@@ -360,12 +392,14 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
break;
case 0x30: /*LMSW*/
if ((CPL || eflags&VM_FLAG) && (msw&1))
if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1))
{
x386_dynarec_log("LMSW - ring not zero!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw(); if (cpu_state.abrt) return 1;
if (msw & 1) tempw |= 1;
if (is386)
@@ -385,12 +419,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
case 0x38: /*INVLPG*/
if (is486)
{
if ((CPL || eflags&VM_FLAG) && (cr0&1))
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
{
x386_dynarec_log("Invalid INVLPG!\n");
x86gpf(NULL, 0);
break;
}
SEG_CHECK_READ(cpu_state.ea_seg);
mmu_invalidate(ds + cpu_state.eaaddr);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32);

View File

@@ -63,26 +63,26 @@ static int op ## name ## _l_a32(uint32_t fetchdat) \
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
}
op_seg(CS, _cs, x86_opcodes, x86_opcodes)
op_seg(DS, _ds, x86_opcodes, x86_opcodes)
op_seg(ES, _es, x86_opcodes, x86_opcodes)
op_seg(FS, _fs, x86_opcodes, x86_opcodes)
op_seg(GS, _gs, x86_opcodes, x86_opcodes)
op_seg(SS, _ss, x86_opcodes, x86_opcodes)
op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes)
op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes)
op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes)
op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes)
op_seg(GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes)
op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes)
op_seg(CS_REPE, _cs, x86_opcodes_REPE, x86_opcodes)
op_seg(DS_REPE, _ds, x86_opcodes_REPE, x86_opcodes)
op_seg(ES_REPE, _es, x86_opcodes_REPE, x86_opcodes)
op_seg(FS_REPE, _fs, x86_opcodes_REPE, x86_opcodes)
op_seg(GS_REPE, _gs, x86_opcodes_REPE, x86_opcodes)
op_seg(SS_REPE, _ss, x86_opcodes_REPE, x86_opcodes)
op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE, x86_opcodes)
op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE, x86_opcodes)
op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes)
op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE, x86_opcodes)
op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE, x86_opcodes)
op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes)
op_seg(CS_REPNE, _cs, x86_opcodes_REPNE, x86_opcodes)
op_seg(DS_REPNE, _ds, x86_opcodes_REPNE, x86_opcodes)
op_seg(ES_REPNE, _es, x86_opcodes_REPNE, x86_opcodes)
op_seg(FS_REPNE, _fs, x86_opcodes_REPNE, x86_opcodes)
op_seg(GS_REPNE, _gs, x86_opcodes_REPNE, x86_opcodes)
op_seg(SS_REPNE, _ss, x86_opcodes_REPNE, x86_opcodes)
op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE, x86_opcodes)
op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes)
op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes)
op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes)
op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes)
op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes)
static int op_66(uint32_t fetchdat) /*Data size select*/
{

View File

@@ -1,5 +1,3 @@
extern int trap;
#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \
static int opREP_INSB_ ## size(uint32_t fetchdat) \
{ \
@@ -9,11 +7,13 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
{ \
uint8_t temp; \
\
check_io_perm(DX); \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
check_io_perm(DX); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
temp = inb(DX); \
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) DEST_REG--; \
if (cpu_state.flags & D_FLAG) DEST_REG--; \
else DEST_REG++; \
CNT_REG--; \
cycles -= 15; \
@@ -36,12 +36,14 @@ static int opREP_INSW_ ## size(uint32_t fetchdat)
{ \
uint16_t temp; \
\
check_io_perm(DX); \
check_io_perm(DX+1); \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
check_io_perm(DX); \
check_io_perm(DX+1); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
temp = inw(DX); \
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) DEST_REG -= 2; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
else DEST_REG += 2; \
CNT_REG--; \
cycles -= 15; \
@@ -64,14 +66,16 @@ static int opREP_INSL_ ## size(uint32_t fetchdat)
{ \
uint32_t temp; \
\
check_io_perm(DX); \
check_io_perm(DX+1); \
check_io_perm(DX+2); \
check_io_perm(DX+3); \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
check_io_perm(DX); \
check_io_perm(DX+1); \
check_io_perm(DX+2); \
check_io_perm(DX+3); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
temp = inl(DX); \
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) DEST_REG -= 4; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
else DEST_REG += 4; \
CNT_REG--; \
cycles -= 15; \
@@ -93,10 +97,13 @@ static int opREP_OUTSB_ ## size(uint32_t fetchdat)
\
if (CNT_REG > 0) \
{ \
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
uint8_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \
outb(DX, temp); \
if (flags & D_FLAG) SRC_REG--; \
if (cpu_state.flags & D_FLAG) SRC_REG--; \
else SRC_REG++; \
CNT_REG--; \
cycles -= 14; \
@@ -117,11 +124,14 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat)
\
if (CNT_REG > 0) \
{ \
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \
check_io_perm(DX+1); \
outw(DX, temp); \
if (flags & D_FLAG) SRC_REG -= 2; \
if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \
else SRC_REG += 2; \
CNT_REG--; \
cycles -= 14; \
@@ -142,13 +152,16 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat)
\
if (CNT_REG > 0) \
{ \
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
uint32_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \
check_io_perm(DX+1); \
check_io_perm(DX+2); \
check_io_perm(DX+3); \
outl(DX, temp); \
if (flags & D_FLAG) SRC_REG -= 4; \
if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \
else SRC_REG += 4; \
CNT_REG--; \
cycles -= 14; \
@@ -170,15 +183,21 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
} \
while (CNT_REG > 0) \
{ \
uint8_t temp; \
\
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \
CNT_REG--; \
cycles -= is486 ? 3 : 4; \
@@ -203,15 +222,21 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
} \
while (CNT_REG > 0) \
{ \
uint16_t temp; \
\
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \
CNT_REG--; \
cycles -= is486 ? 3 : 4; \
@@ -236,15 +261,21 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
} \
while (CNT_REG > 0) \
{ \
uint32_t temp; \
\
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { DEST_REG += 4; SRC_REG += 4; } \
CNT_REG--; \
cycles -= is486 ? 3 : 4; \
@@ -271,11 +302,13 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
while (CNT_REG > 0) \
{ \
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \
if (flags & D_FLAG) DEST_REG--; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) DEST_REG--; \
else DEST_REG++; \
CNT_REG--; \
cycles -= is486 ? 4 : 5; \
@@ -299,11 +332,13 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
while (CNT_REG > 0) \
{ \
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \
writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \
if (flags & D_FLAG) DEST_REG -= 2; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
else DEST_REG += 2; \
CNT_REG--; \
cycles -= is486 ? 4 : 5; \
@@ -327,11 +362,13 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_WRITE(&cpu_state.seg_es); \
while (CNT_REG > 0) \
{ \
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \
writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \
if (flags & D_FLAG) DEST_REG -= 4; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
else DEST_REG += 4; \
CNT_REG--; \
cycles -= is486 ? 4 : 5; \
@@ -356,10 +393,13 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \
{ \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
if (flags & D_FLAG) SRC_REG--; \
if (cpu_state.flags & D_FLAG) SRC_REG--; \
else SRC_REG++; \
CNT_REG--; \
cycles -= is486 ? 4 : 5; \
@@ -383,10 +423,13 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \
{ \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
if (flags & D_FLAG) SRC_REG -= 2; \
if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \
else SRC_REG += 2; \
CNT_REG--; \
cycles -= is486 ? 4 : 5; \
@@ -410,10 +453,13 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \
{ \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
if (flags & D_FLAG) SRC_REG -= 4; \
if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \
else SRC_REG += 4; \
CNT_REG--; \
cycles -= is486 ? 4 : 5; \
@@ -441,10 +487,15 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat)
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
uint8_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \
CNT_REG--; \
cycles -= is486 ? 7 : 9; \
@@ -468,10 +519,15 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat)
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
uint16_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \
CNT_REG--; \
cycles -= is486 ? 7 : 9; \
@@ -495,10 +551,15 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat)
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
uint32_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { DEST_REG += 4; SRC_REG += 4; } \
CNT_REG--; \
cycles -= is486 ? 7 : 9; \
@@ -523,12 +584,15 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat)
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
SEG_CHECK_READ(&cpu_state.seg_es); \
while ((CNT_REG > 0) && (FV == tempz)) \
{ \
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\
setsub8(AL, temp); \
tempz = (ZF_SET()) ? 1 : 0; \
if (flags & D_FLAG) DEST_REG--; \
if (cpu_state.flags & D_FLAG) DEST_REG--; \
else DEST_REG++; \
CNT_REG--; \
cycles -= is486 ? 5 : 8; \
@@ -554,12 +618,15 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat)
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
SEG_CHECK_READ(&cpu_state.seg_es); \
while ((CNT_REG > 0) && (FV == tempz)) \
{ \
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\
setsub16(AX, temp); \
tempz = (ZF_SET()) ? 1 : 0; \
if (flags & D_FLAG) DEST_REG -= 2; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
else DEST_REG += 2; \
CNT_REG--; \
cycles -= is486 ? 5 : 8; \
@@ -585,12 +652,15 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat)
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
SEG_CHECK_READ(&cpu_state.seg_es); \
while ((CNT_REG > 0) && (FV == tempz)) \
{ \
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\
setsub32(EAX, temp); \
tempz = (ZF_SET()) ? 1 : 0; \
if (flags & D_FLAG) DEST_REG -= 4; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
else DEST_REG += 4; \
CNT_REG--; \
cycles -= is486 ? 5 : 8; \

View File

@@ -1,10 +1,10 @@
#define RETF_a16(stack_offset) \
if ((msw&1) && !(eflags&VM_FLAG)) \
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
{ \
pmoderetf(0, stack_offset); \
return 1; \
} \
oxpc = cpu_state.pc; \
oxpc = cpu_state.pc; \
if (stack32) \
{ \
cpu_state.pc = readmemw(ss, ESP); \
@@ -21,12 +21,12 @@
cycles -= timing_retf_rm;
#define RETF_a32(stack_offset) \
if ((msw&1) && !(eflags&VM_FLAG)) \
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
{ \
pmoderetf(1, stack_offset); \
return 1; \
} \
oxpc = cpu_state.pc; \
oxpc = cpu_state.pc; \
if (stack32) \
{ \
cpu_state.pc = readmeml(ss, ESP); \
@@ -94,7 +94,7 @@ static int opIRET_286(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
return 1;
@@ -108,19 +108,19 @@ static int opIRET_286(uint32_t fetchdat)
else
{
uint16_t new_cs;
oxpc = cpu_state.pc;
oxpc = cpu_state.pc;
if (stack32)
{
cpu_state.pc = readmemw(ss, ESP);
new_cs = readmemw(ss, ESP + 2);
flags = (flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
ESP += 6;
}
else
{
cpu_state.pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
flags = (flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
SP += 6;
}
loadcs(new_cs);
@@ -139,7 +139,7 @@ static int opIRET(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
if (cr4 & CR4_VME)
{
@@ -151,17 +151,17 @@ static int opIRET(uint32_t fetchdat)
if (cpu_state.abrt)
return 1;
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (eflags & VIP_FLAG)))
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
{
x86gpf(NULL, 0);
return 1;
}
SP += 6;
if (new_flags & I_FLAG)
eflags |= VIF_FLAG;
cpu_state.eflags |= VIF_FLAG;
else
eflags &= ~VIF_FLAG;
flags = (flags & 0x3300) | (new_flags & 0x4cd5) | 2;
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
loadcs(new_cs);
cpu_state.pc = new_pc;
@@ -184,19 +184,19 @@ static int opIRET(uint32_t fetchdat)
else
{
uint16_t new_cs;
oxpc = cpu_state.pc;
oxpc = cpu_state.pc;
if (stack32)
{
cpu_state.pc = readmemw(ss, ESP);
new_cs = readmemw(ss, ESP + 2);
flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
ESP += 6;
}
else
{
cpu_state.pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
SP += 6;
}
loadcs(new_cs);
@@ -216,7 +216,7 @@ static int opIRETD(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
return 1;
@@ -230,21 +230,21 @@ static int opIRETD(uint32_t fetchdat)
else
{
uint16_t new_cs;
oxpc = cpu_state.pc;
oxpc = cpu_state.pc;
if (stack32)
{
cpu_state.pc = readmeml(ss, ESP);
new_cs = readmemw(ss, ESP + 4);
flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
eflags = readmemw(ss, ESP + 10);
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
cpu_state.eflags = readmemw(ss, ESP + 10);
ESP += 12;
}
else
{
cpu_state.pc = readmeml(ss, SP);
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
eflags = readmemw(ss, (SP + 10) & 0xffff);
cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
SP += 12;
}
loadcs(new_cs);

View File

@@ -2,6 +2,8 @@
static int opSET ## condition ## _a16(uint32_t fetchdat) \
{ \
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
seteab((cond_ ## condition) ? 1 : 0); \
CLOCK_CYCLES(4); \
return cpu_state.abrt; \
@@ -10,6 +12,8 @@
static int opSET ## condition ## _a32(uint32_t fetchdat) \
{ \
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
seteab((cond_ ## condition) ? 1 : 0); \
CLOCK_CYCLES(4); \
return cpu_state.abrt; \

View File

@@ -6,36 +6,25 @@
switch (rmdat & 0x38) \
{ \
case 0x00: /*ROL b, c*/ \
while (c > 0) \
{ \
temp2 = (temp & 0x80) ? 1 : 0; \
temp = (temp << 1) | temp2; \
c--; \
} \
seteab(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \
temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \
seteab(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp & 1) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x08: /*ROR b,CL*/ \
while (c > 0) \
{ \
temp2 = temp & 1; \
temp >>= 1; \
if (temp2) temp |= 0x80; \
c--; \
} \
seteab(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \
temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \
seteab(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp & 0x80) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
break; \
case 0x10: /*RCL b,CL*/ \
temp2 = flags & C_FLAG; \
temp2 = cpu_state.flags & C_FLAG; \
if (is486) CLOCK_CYCLES_ALWAYS(c); \
while (c > 0) \
{ \
@@ -45,14 +34,14 @@
c--; \
} \
seteab(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp2) cpu_state.flags |= C_FLAG; \
if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x18: /*RCR b,CL*/ \
temp2 = flags & C_FLAG; \
temp2 = cpu_state.flags & C_FLAG; \
if (is486) CLOCK_CYCLES_ALWAYS(c); \
while (c > 0) \
{ \
@@ -62,9 +51,9 @@
c--; \
} \
seteab(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp2) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
@@ -98,36 +87,25 @@
switch (rmdat & 0x38) \
{ \
case 0x00: /*ROL w, c*/ \
while (c > 0) \
{ \
temp2 = (temp & 0x8000) ? 1 : 0; \
temp = (temp << 1) | temp2; \
c--; \
} \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \
seteaw(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp & 1) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x08: /*ROR w, c*/ \
while (c > 0) \
{ \
temp2 = temp & 1; \
temp >>= 1; \
if (temp2) temp |= 0x8000; \
c--; \
} \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
case 0x08: /*ROR w,CL*/ \
temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \
seteaw(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp & 0x8000) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x10: /*RCL w, c*/ \
temp2 = flags & C_FLAG; \
temp2 = cpu_state.flags & C_FLAG; \
if (is486) CLOCK_CYCLES_ALWAYS(c); \
while (c > 0) \
{ \
@@ -137,14 +115,14 @@
c--; \
} \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp2) cpu_state.flags |= C_FLAG; \
if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x18: /*RCR w, c*/ \
temp2 = flags & C_FLAG; \
temp2 = cpu_state.flags & C_FLAG; \
if (is486) CLOCK_CYCLES_ALWAYS(c); \
while (c > 0) \
{ \
@@ -154,9 +132,9 @@
c--; \
} \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp2) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
@@ -190,33 +168,22 @@
switch (rmdat & 0x38) \
{ \
case 0x00: /*ROL l, c*/ \
while (c > 0) \
{ \
temp2 = (temp & 0x80000000) ? 1 : 0; \
temp = (temp << 1) | temp2; \
c--; \
} \
seteal(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
temp = (temp << c) | (temp >> (32-c)); \
seteal(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp & 1) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x08: /*ROR l, c*/ \
while (c > 0) \
{ \
temp2 = temp & 1; \
temp >>= 1; \
if (temp2) temp |= 0x80000000; \
c--; \
} \
seteal(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
case 0x08: /*ROR l,CL*/ \
temp = (temp >> c) | (temp << (32-c)); \
seteal(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \
case 0x10: /*RCL l, c*/ \
temp2 = CF_SET(); \
@@ -229,14 +196,14 @@
c--; \
} \
seteal(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp2) cpu_state.flags |= C_FLAG; \
if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
break; \
case 0x18: /*RCR l, c*/ \
temp2 = flags & C_FLAG; \
temp2 = cpu_state.flags & C_FLAG; \
if (is486) CLOCK_CYCLES_ALWAYS(c); \
while (c > 0) \
{ \
@@ -246,9 +213,9 @@
c--; \
} \
seteal(temp); if (cpu_state.abrt) return 1; \
flags &= ~(C_FLAG | V_FLAG); \
if (temp2) flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
if (temp2) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
break; \
@@ -281,6 +248,8 @@ static int opC0_a16(uint32_t fetchdat)
uint8_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
PREFETCH_PREFIX();
temp = geteab(); if (cpu_state.abrt) return 1;
@@ -294,6 +263,8 @@ static int opC0_a32(uint32_t fetchdat)
uint8_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
PREFETCH_PREFIX();
temp = geteab(); if (cpu_state.abrt) return 1;
@@ -307,6 +278,8 @@ static int opC1_w_a16(uint32_t fetchdat)
uint16_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
PREFETCH_PREFIX();
temp = geteaw(); if (cpu_state.abrt) return 1;
@@ -320,6 +293,8 @@ static int opC1_w_a32(uint32_t fetchdat)
uint16_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
PREFETCH_PREFIX();
temp = geteaw(); if (cpu_state.abrt) return 1;
@@ -333,6 +308,8 @@ static int opC1_l_a16(uint32_t fetchdat)
uint32_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
PREFETCH_PREFIX();
temp = geteal(); if (cpu_state.abrt) return 1;
@@ -346,6 +323,8 @@ static int opC1_l_a32(uint32_t fetchdat)
uint32_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
PREFETCH_PREFIX();
temp = geteal(); if (cpu_state.abrt) return 1;
@@ -360,6 +339,8 @@ static int opD0_a16(uint32_t fetchdat)
uint8_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
OP_SHIFT_b(c, 0);
return 0;
@@ -371,6 +352,8 @@ static int opD0_a32(uint32_t fetchdat)
uint8_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
OP_SHIFT_b(c, 1);
return 0;
@@ -382,6 +365,8 @@ static int opD1_w_a16(uint32_t fetchdat)
uint16_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
OP_SHIFT_w(c, 0);
return 0;
@@ -393,6 +378,8 @@ static int opD1_w_a32(uint32_t fetchdat)
uint16_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
OP_SHIFT_w(c, 1);
return 0;
@@ -404,6 +391,8 @@ static int opD1_l_a16(uint32_t fetchdat)
uint32_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
OP_SHIFT_l(c, 0);
return 0;
@@ -415,6 +404,8 @@ static int opD1_l_a32(uint32_t fetchdat)
uint32_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
OP_SHIFT_l(c, 1);
return 0;
@@ -427,6 +418,8 @@ static int opD2_a16(uint32_t fetchdat)
uint8_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = CL & 31;
temp = geteab(); if (cpu_state.abrt) return 1;
OP_SHIFT_b(c, 0);
@@ -439,6 +432,8 @@ static int opD2_a32(uint32_t fetchdat)
uint8_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = CL & 31;
temp = geteab(); if (cpu_state.abrt) return 1;
OP_SHIFT_b(c, 1);
@@ -451,6 +446,8 @@ static int opD3_w_a16(uint32_t fetchdat)
uint16_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = CL & 31;
temp = geteaw(); if (cpu_state.abrt) return 1;
OP_SHIFT_w(c, 0);
@@ -463,6 +460,8 @@ static int opD3_w_a32(uint32_t fetchdat)
uint16_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = CL & 31;
temp = geteaw(); if (cpu_state.abrt) return 1;
OP_SHIFT_w(c, 1);
@@ -475,6 +474,8 @@ static int opD3_l_a16(uint32_t fetchdat)
uint32_t temp, temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = CL & 31;
temp = geteal(); if (cpu_state.abrt) return 1;
OP_SHIFT_l(c, 0);
@@ -487,6 +488,8 @@ static int opD3_l_a32(uint32_t fetchdat)
uint32_t temp, temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
c = CL & 31;
temp = geteal(); if (cpu_state.abrt) return 1;
OP_SHIFT_l(c, 1);
@@ -507,7 +510,7 @@ static int opD3_l_a32(uint32_t fetchdat)
seteaw(tempw); if (cpu_state.abrt) return 1; \
setznp16(tempw); \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
}
#define SHLD_l() \
@@ -520,7 +523,7 @@ static int opD3_l_a32(uint32_t fetchdat)
seteal(templ); if (cpu_state.abrt) return 1; \
setznp32(templ); \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
}
@@ -536,7 +539,7 @@ static int opD3_l_a32(uint32_t fetchdat)
seteaw(tempw); if (cpu_state.abrt) return 1; \
setznp16(tempw); \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
}
#define SHRD_l() \
@@ -549,7 +552,7 @@ static int opD3_l_a32(uint32_t fetchdat)
seteal(templ); if (cpu_state.abrt) return 1; \
setznp32(templ); \
flags_rebuild(); \
if (tempc) flags |= C_FLAG; \
if (tempc) cpu_state.flags |= C_FLAG; \
}
#define opSHxD(operation) \
@@ -558,6 +561,8 @@ static int opD3_l_a32(uint32_t fetchdat)
int count; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
count = getbyte() & 31; \
operation() \
\
@@ -570,6 +575,8 @@ static int opD3_l_a32(uint32_t fetchdat)
int count; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
count = CL & 31; \
operation() \
\
@@ -582,6 +589,8 @@ static int opD3_l_a32(uint32_t fetchdat)
int count; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
count = getbyte() & 31; \
operation() \
\
@@ -594,6 +603,8 @@ static int opD3_l_a32(uint32_t fetchdat)
int count; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
count = CL & 31; \
operation() \
\

View File

@@ -236,6 +236,8 @@ static int opPOPW_a16(uint32_t fetchdat)
temp = POP_W(); if (cpu_state.abrt) return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(temp);
if (cpu_state.abrt)
{
@@ -255,6 +257,8 @@ static int opPOPW_a32(uint32_t fetchdat)
temp = POP_W(); if (cpu_state.abrt) return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(temp);
if (cpu_state.abrt)
{
@@ -274,7 +278,9 @@ static int opPOPL_a16(uint32_t fetchdat)
temp = POP_L(); if (cpu_state.abrt) return 1;
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(temp);
if (cpu_state.abrt)
{
@@ -294,6 +300,8 @@ static int opPOPL_a32(uint32_t fetchdat)
temp = POP_L(); if (cpu_state.abrt) return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(temp);
if (cpu_state.abrt)
{
@@ -469,10 +477,10 @@ PUSH_SEG_OPS(FS)
PUSH_SEG_OPS(GS)
PUSH_SEG_OPS(SS)
POP_SEG_OPS(DS, &_ds)
POP_SEG_OPS(ES, &_es)
POP_SEG_OPS(FS, &_fs)
POP_SEG_OPS(GS, &_gs)
POP_SEG_OPS(DS, &cpu_state.seg_ds)
POP_SEG_OPS(ES, &cpu_state.seg_es)
POP_SEG_OPS(FS, &cpu_state.seg_fs)
POP_SEG_OPS(GS, &cpu_state.seg_gs)
static int opPOP_SS_w(uint32_t fetchdat)
@@ -480,14 +488,14 @@ static int opPOP_SS_w(uint32_t fetchdat)
uint16_t temp_seg;
uint32_t temp_esp = ESP;
temp_seg = POP_W(); if (cpu_state.abrt) return 1;
loadseg(temp_seg, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
CLOCK_CYCLES(is486 ? 3 : 7);
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt) return 1;
@@ -500,14 +508,14 @@ static int opPOP_SS_l(uint32_t fetchdat)
uint32_t temp_seg;
uint32_t temp_esp = ESP;
temp_seg = POP_L(); if (cpu_state.abrt) return 1;
loadseg(temp_seg & 0xffff, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
CLOCK_CYCLES(is486 ? 3 : 7);
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &_ds;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt) return 1;

View File

@@ -1,8 +1,12 @@
static int opMOVSB_a16(uint32_t fetchdat)
{
uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
writememb(es, DI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) { DI--; SI--; }
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0);
@@ -10,9 +14,13 @@ static int opMOVSB_a16(uint32_t fetchdat)
}
static int opMOVSB_a32(uint32_t fetchdat)
{
uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
writememb(es, EDI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) { EDI--; ESI--; }
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1);
@@ -21,9 +29,13 @@ static int opMOVSB_a32(uint32_t fetchdat)
static int opMOVSW_a16(uint32_t fetchdat)
{
uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
writememw(es, DI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) { DI -= 2; SI -= 2; }
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { DI += 2; SI += 2; }
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0);
@@ -31,9 +43,13 @@ static int opMOVSW_a16(uint32_t fetchdat)
}
static int opMOVSW_a32(uint32_t fetchdat)
{
uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
writememw(es, EDI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { EDI += 2; ESI += 2; }
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1);
@@ -42,9 +58,13 @@ static int opMOVSW_a32(uint32_t fetchdat)
static int opMOVSL_a16(uint32_t fetchdat)
{
uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
writememl(es, DI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) { DI -= 4; SI -= 4; }
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { DI += 4; SI += 4; }
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0);
@@ -52,9 +72,13 @@ static int opMOVSL_a16(uint32_t fetchdat)
}
static int opMOVSL_a32(uint32_t fetchdat)
{
uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
writememl(es, EDI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { EDI += 4; ESI += 4; }
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1);
@@ -64,10 +88,14 @@ static int opMOVSL_a32(uint32_t fetchdat)
static int opCMPSB_a16(uint32_t fetchdat)
{
uint8_t src = readmemb(cpu_state.ea_seg->base, SI);
uint8_t dst = readmemb(es, DI); if (cpu_state.abrt) return 1;
uint8_t src, dst;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemb(cpu_state.ea_seg->base, SI);
dst = readmemb(es, DI); if (cpu_state.abrt) return 1;
setsub8(src, dst);
if (flags & D_FLAG) { DI--; SI--; }
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
CLOCK_CYCLES((is486) ? 8 : 10);
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0);
@@ -75,10 +103,14 @@ static int opCMPSB_a16(uint32_t fetchdat)
}
static int opCMPSB_a32(uint32_t fetchdat)
{
uint8_t src = readmemb(cpu_state.ea_seg->base, ESI);
uint8_t dst = readmemb(es, EDI); if (cpu_state.abrt) return 1;
uint8_t src, dst;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemb(cpu_state.ea_seg->base, ESI);
dst = readmemb(es, EDI); if (cpu_state.abrt) return 1;
setsub8(src, dst);
if (flags & D_FLAG) { EDI--; ESI--; }
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
CLOCK_CYCLES((is486) ? 8 : 10);
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1);
@@ -87,10 +119,14 @@ static int opCMPSB_a32(uint32_t fetchdat)
static int opCMPSW_a16(uint32_t fetchdat)
{
uint16_t src = readmemw(cpu_state.ea_seg->base, SI);
uint16_t dst = readmemw(es, DI); if (cpu_state.abrt) return 1;
uint16_t src, dst;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemw(cpu_state.ea_seg->base, SI);
dst = readmemw(es, DI); if (cpu_state.abrt) return 1;
setsub16(src, dst);
if (flags & D_FLAG) { DI -= 2; SI -= 2; }
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { DI += 2; SI += 2; }
CLOCK_CYCLES((is486) ? 8 : 10);
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0);
@@ -98,10 +134,14 @@ static int opCMPSW_a16(uint32_t fetchdat)
}
static int opCMPSW_a32(uint32_t fetchdat)
{
uint16_t src = readmemw(cpu_state.ea_seg->base, ESI);
uint16_t dst = readmemw(es, EDI); if (cpu_state.abrt) return 1;
uint16_t src, dst;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemw(cpu_state.ea_seg->base, ESI);
dst = readmemw(es, EDI); if (cpu_state.abrt) return 1;
setsub16(src, dst);
if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { EDI += 2; ESI += 2; }
CLOCK_CYCLES((is486) ? 8 : 10);
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1);
@@ -110,10 +150,14 @@ static int opCMPSW_a32(uint32_t fetchdat)
static int opCMPSL_a16(uint32_t fetchdat)
{
uint32_t src = readmeml(cpu_state.ea_seg->base, SI);
uint32_t dst = readmeml(es, DI); if (cpu_state.abrt) return 1;
uint32_t src, dst;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmeml(cpu_state.ea_seg->base, SI);
dst = readmeml(es, DI); if (cpu_state.abrt) return 1;
setsub32(src, dst);
if (flags & D_FLAG) { DI -= 4; SI -= 4; }
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { DI += 4; SI += 4; }
CLOCK_CYCLES((is486) ? 8 : 10);
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0);
@@ -121,10 +165,14 @@ static int opCMPSL_a16(uint32_t fetchdat)
}
static int opCMPSL_a32(uint32_t fetchdat)
{
uint32_t src = readmeml(cpu_state.ea_seg->base, ESI);
uint32_t dst = readmeml(es, EDI); if (cpu_state.abrt) return 1;
uint32_t src, dst;
SEG_CHECK_READ(cpu_state.ea_seg);
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmeml(cpu_state.ea_seg->base, ESI);
dst = readmeml(es, EDI); if (cpu_state.abrt) return 1;
setsub32(src, dst);
if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { EDI += 4; ESI += 4; }
CLOCK_CYCLES((is486) ? 8 : 10);
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1);
@@ -133,8 +181,9 @@ static int opCMPSL_a32(uint32_t fetchdat)
static int opSTOSB_a16(uint32_t fetchdat)
{
SEG_CHECK_WRITE(&cpu_state.seg_es);
writememb(es, DI, AL); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) DI--;
if (cpu_state.flags & D_FLAG) DI--;
else DI++;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
@@ -142,8 +191,9 @@ static int opSTOSB_a16(uint32_t fetchdat)
}
static int opSTOSB_a32(uint32_t fetchdat)
{
SEG_CHECK_WRITE(&cpu_state.seg_es);
writememb(es, EDI, AL); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) EDI--;
if (cpu_state.flags & D_FLAG) EDI--;
else EDI++;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1);
@@ -152,8 +202,9 @@ static int opSTOSB_a32(uint32_t fetchdat)
static int opSTOSW_a16(uint32_t fetchdat)
{
SEG_CHECK_WRITE(&cpu_state.seg_es);
writememw(es, DI, AX); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) DI -= 2;
if (cpu_state.flags & D_FLAG) DI -= 2;
else DI += 2;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
@@ -161,8 +212,9 @@ static int opSTOSW_a16(uint32_t fetchdat)
}
static int opSTOSW_a32(uint32_t fetchdat)
{
SEG_CHECK_WRITE(&cpu_state.seg_es);
writememw(es, EDI, AX); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) EDI -= 2;
if (cpu_state.flags & D_FLAG) EDI -= 2;
else EDI += 2;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1);
@@ -171,8 +223,9 @@ static int opSTOSW_a32(uint32_t fetchdat)
static int opSTOSL_a16(uint32_t fetchdat)
{
SEG_CHECK_WRITE(&cpu_state.seg_es);
writememl(es, DI, EAX); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) DI -= 4;
if (cpu_state.flags & D_FLAG) DI -= 4;
else DI += 4;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0);
@@ -180,8 +233,9 @@ static int opSTOSL_a16(uint32_t fetchdat)
}
static int opSTOSL_a32(uint32_t fetchdat)
{
SEG_CHECK_WRITE(&cpu_state.seg_es);
writememl(es, EDI, EAX); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) EDI -= 4;
if (cpu_state.flags & D_FLAG) EDI -= 4;
else EDI += 4;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1);
@@ -191,9 +245,12 @@ static int opSTOSL_a32(uint32_t fetchdat)
static int opLODSB_a16(uint32_t fetchdat)
{
uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
AL = temp;
if (flags & D_FLAG) SI--;
if (cpu_state.flags & D_FLAG) SI--;
else SI++;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
@@ -201,9 +258,12 @@ static int opLODSB_a16(uint32_t fetchdat)
}
static int opLODSB_a32(uint32_t fetchdat)
{
uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
AL = temp;
if (flags & D_FLAG) ESI--;
if (cpu_state.flags & D_FLAG) ESI--;
else ESI++;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1);
@@ -212,9 +272,12 @@ static int opLODSB_a32(uint32_t fetchdat)
static int opLODSW_a16(uint32_t fetchdat)
{
uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
AX = temp;
if (flags & D_FLAG) SI -= 2;
if (cpu_state.flags & D_FLAG) SI -= 2;
else SI += 2;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
@@ -222,9 +285,12 @@ static int opLODSW_a16(uint32_t fetchdat)
}
static int opLODSW_a32(uint32_t fetchdat)
{
uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
AX = temp;
if (flags & D_FLAG) ESI -= 2;
if (cpu_state.flags & D_FLAG) ESI -= 2;
else ESI += 2;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1);
@@ -233,9 +299,12 @@ static int opLODSW_a32(uint32_t fetchdat)
static int opLODSL_a16(uint32_t fetchdat)
{
uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
EAX = temp;
if (flags & D_FLAG) SI -= 4;
if (cpu_state.flags & D_FLAG) SI -= 4;
else SI += 4;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0);
@@ -243,9 +312,12 @@ static int opLODSL_a16(uint32_t fetchdat)
}
static int opLODSL_a32(uint32_t fetchdat)
{
uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
EAX = temp;
if (flags & D_FLAG) ESI -= 4;
if (cpu_state.flags & D_FLAG) ESI -= 4;
else ESI += 4;
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1);
@@ -255,9 +327,12 @@ static int opLODSL_a32(uint32_t fetchdat)
static int opSCASB_a16(uint32_t fetchdat)
{
uint8_t temp = readmemb(es, DI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(&cpu_state.seg_es);
temp = readmemb(es, DI); if (cpu_state.abrt) return 1;
setsub8(AL, temp);
if (flags & D_FLAG) DI--;
if (cpu_state.flags & D_FLAG) DI--;
else DI++;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0);
@@ -265,9 +340,12 @@ static int opSCASB_a16(uint32_t fetchdat)
}
static int opSCASB_a32(uint32_t fetchdat)
{
uint8_t temp = readmemb(es, EDI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(&cpu_state.seg_es);
temp = readmemb(es, EDI); if (cpu_state.abrt) return 1;
setsub8(AL, temp);
if (flags & D_FLAG) EDI--;
if (cpu_state.flags & D_FLAG) EDI--;
else EDI++;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1);
@@ -276,9 +354,12 @@ static int opSCASB_a32(uint32_t fetchdat)
static int opSCASW_a16(uint32_t fetchdat)
{
uint16_t temp = readmemw(es, DI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(&cpu_state.seg_es);
temp = readmemw(es, DI); if (cpu_state.abrt) return 1;
setsub16(AX, temp);
if (flags & D_FLAG) DI -= 2;
if (cpu_state.flags & D_FLAG) DI -= 2;
else DI += 2;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0);
@@ -286,9 +367,12 @@ static int opSCASW_a16(uint32_t fetchdat)
}
static int opSCASW_a32(uint32_t fetchdat)
{
uint16_t temp = readmemw(es, EDI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(&cpu_state.seg_es);
temp = readmemw(es, EDI); if (cpu_state.abrt) return 1;
setsub16(AX, temp);
if (flags & D_FLAG) EDI -= 2;
if (cpu_state.flags & D_FLAG) EDI -= 2;
else EDI += 2;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1);
@@ -297,9 +381,12 @@ static int opSCASW_a32(uint32_t fetchdat)
static int opSCASL_a16(uint32_t fetchdat)
{
uint32_t temp = readmeml(es, DI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(&cpu_state.seg_es);
temp = readmeml(es, DI); if (cpu_state.abrt) return 1;
setsub32(EAX, temp);
if (flags & D_FLAG) DI -= 4;
if (cpu_state.flags & D_FLAG) DI -= 4;
else DI += 4;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0);
@@ -307,9 +394,12 @@ static int opSCASL_a16(uint32_t fetchdat)
}
static int opSCASL_a32(uint32_t fetchdat)
{
uint32_t temp = readmeml(es, EDI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(&cpu_state.seg_es);
temp = readmeml(es, EDI); if (cpu_state.abrt) return 1;
setsub32(EAX, temp);
if (flags & D_FLAG) EDI -= 4;
if (cpu_state.flags & D_FLAG) EDI -= 4;
else EDI += 4;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1);
@@ -319,10 +409,12 @@ static int opSCASL_a32(uint32_t fetchdat)
static int opINSB_a16(uint32_t fetchdat)
{
uint8_t temp;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
temp = inb(DX);
writememb(es, DI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) DI--;
if (cpu_state.flags & D_FLAG) DI--;
else DI++;
CLOCK_CYCLES(15);
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0);
@@ -331,10 +423,12 @@ static int opINSB_a16(uint32_t fetchdat)
static int opINSB_a32(uint32_t fetchdat)
{
uint8_t temp;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
temp = inb(DX);
writememb(es, EDI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) EDI--;
if (cpu_state.flags & D_FLAG) EDI--;
else EDI++;
CLOCK_CYCLES(15);
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1);
@@ -344,11 +438,13 @@ static int opINSB_a32(uint32_t fetchdat)
static int opINSW_a16(uint32_t fetchdat)
{
uint16_t temp;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
temp = inw(DX);
writememw(es, DI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) DI -= 2;
if (cpu_state.flags & D_FLAG) DI -= 2;
else DI += 2;
CLOCK_CYCLES(15);
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0);
@@ -357,11 +453,13 @@ static int opINSW_a16(uint32_t fetchdat)
static int opINSW_a32(uint32_t fetchdat)
{
uint16_t temp;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
temp = inw(DX);
writememw(es, EDI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) EDI -= 2;
if (cpu_state.flags & D_FLAG) EDI -= 2;
else EDI += 2;
CLOCK_CYCLES(15);
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1);
@@ -371,13 +469,15 @@ static int opINSW_a32(uint32_t fetchdat)
static int opINSL_a16(uint32_t fetchdat)
{
uint32_t temp;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
temp = inl(DX);
writememl(es, DI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) DI -= 4;
if (cpu_state.flags & D_FLAG) DI -= 4;
else DI += 4;
CLOCK_CYCLES(15);
PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0);
@@ -386,13 +486,15 @@ static int opINSL_a16(uint32_t fetchdat)
static int opINSL_a32(uint32_t fetchdat)
{
uint32_t temp;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
temp = inl(DX);
writememl(es, EDI, temp); if (cpu_state.abrt) return 1;
if (flags & D_FLAG) EDI -= 4;
if (cpu_state.flags & D_FLAG) EDI -= 4;
else EDI += 4;
CLOCK_CYCLES(15);
PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1);
@@ -401,9 +503,12 @@ static int opINSL_a32(uint32_t fetchdat)
static int opOUTSB_a16(uint32_t fetchdat)
{
uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
check_io_perm(DX);
if (flags & D_FLAG) SI--;
if (cpu_state.flags & D_FLAG) SI--;
else SI++;
outb(DX, temp);
CLOCK_CYCLES(14);
@@ -412,9 +517,12 @@ static int opOUTSB_a16(uint32_t fetchdat)
}
static int opOUTSB_a32(uint32_t fetchdat)
{
uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint8_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
check_io_perm(DX);
if (flags & D_FLAG) ESI--;
if (cpu_state.flags & D_FLAG) ESI--;
else ESI++;
outb(DX, temp);
CLOCK_CYCLES(14);
@@ -424,10 +532,13 @@ static int opOUTSB_a32(uint32_t fetchdat)
static int opOUTSW_a16(uint32_t fetchdat)
{
uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
check_io_perm(DX);
check_io_perm(DX + 1);
if (flags & D_FLAG) SI -= 2;
if (cpu_state.flags & D_FLAG) SI -= 2;
else SI += 2;
outw(DX, temp);
CLOCK_CYCLES(14);
@@ -436,10 +547,13 @@ static int opOUTSW_a16(uint32_t fetchdat)
}
static int opOUTSW_a32(uint32_t fetchdat)
{
uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint16_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
check_io_perm(DX);
check_io_perm(DX + 1);
if (flags & D_FLAG) ESI -= 2;
if (cpu_state.flags & D_FLAG) ESI -= 2;
else ESI += 2;
outw(DX, temp);
CLOCK_CYCLES(14);
@@ -449,12 +563,15 @@ static int opOUTSW_a32(uint32_t fetchdat)
static int opOUTSL_a16(uint32_t fetchdat)
{
uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
if (flags & D_FLAG) SI -= 4;
if (cpu_state.flags & D_FLAG) SI -= 4;
else SI += 4;
outl(EDX, temp);
CLOCK_CYCLES(14);
@@ -463,12 +580,15 @@ static int opOUTSL_a16(uint32_t fetchdat)
}
static int opOUTSL_a32(uint32_t fetchdat)
{
uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
if (flags & D_FLAG) ESI -= 4;
if (cpu_state.flags & D_FLAG) ESI -= 4;
else ESI += 4;
outl(EDX, temp);
CLOCK_CYCLES(14);

View File

@@ -2,6 +2,8 @@ static int opXCHG_b_a16(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1;
setr8(cpu_reg, temp);
@@ -13,6 +15,8 @@ static int opXCHG_b_a32(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1;
setr8(cpu_reg, temp);
@@ -25,6 +29,8 @@ static int opXCHG_w_a16(uint32_t fetchdat)
{
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = temp;
@@ -36,6 +42,8 @@ static int opXCHG_w_a32(uint32_t fetchdat)
{
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].w = temp;
@@ -48,6 +56,8 @@ static int opXCHG_l_a16(uint32_t fetchdat)
{
uint32_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = temp;
@@ -59,6 +69,8 @@ static int opXCHG_l_a32(uint32_t fetchdat)
{
uint32_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
cpu_state.regs[cpu_reg].l = temp;

View File

@@ -27,11 +27,12 @@
#include "../86box.h"
#include "cpu.h"
#include "../device.h"
#include "../timer.h"
#include "../machine/machine.h"
#include "../mem.h"
#include "../nvr.h"
#include "x86.h"
#include "386.h"
#include "x86_flags.h"
#include "386_common.h"
@@ -80,13 +81,14 @@ x86seg_log(const char *fmt, ...)
#endif
void x86abort(const char *format, ...)
void x86abort(const char *fmt, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stdlog, format, ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
fflush(stdlog);
nvr_save();
#ifdef ENABLE_808X_LOG
dumpregs(1);
@@ -103,7 +105,7 @@ static void seg_reset(x86seg *s)
s->limit = 0xFFFF;
s->limit_low = 0;
s->limit_high = 0xffff;
if(s == &_cs)
if(s == &cpu_state.seg_cs)
{
// TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below.
//s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0;
@@ -120,19 +122,19 @@ static void seg_reset(x86seg *s)
void x86seg_reset()
{
seg_reset(&_cs);
seg_reset(&_ds);
seg_reset(&_es);
seg_reset(&_fs);
seg_reset(&_gs);
seg_reset(&_ss);
seg_reset(&cpu_state.seg_cs);
seg_reset(&cpu_state.seg_ds);
seg_reset(&cpu_state.seg_es);
seg_reset(&cpu_state.seg_fs);
seg_reset(&cpu_state.seg_gs);
seg_reset(&cpu_state.seg_ss);
}
void x86_doabrt(int x86_abrt)
{
CS = oldcs;
cpu_state.pc = cpu_state.oldpc;
_cs.access = (oldcpl << 5) | 0x80;
cpu_state.seg_cs.access = (oldcpl << 5) | 0x80;
if (msw & 1)
pmodeint(x86_abrt, 0);
@@ -141,22 +143,22 @@ void x86_doabrt(int x86_abrt)
uint32_t addr = (x86_abrt << 2) + idt.base;
if (stack32)
{
writememw(ss,ESP-2,flags);
writememw(ss,ESP-2,cpu_state.flags);
writememw(ss,ESP-4,CS);
writememw(ss,ESP-6,cpu_state.pc);
ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
SP-=6;
}
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.flags&=~I_FLAG;
cpu_state.flags&=~T_FLAG;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
return;
@@ -257,14 +259,14 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
s->limit_low = s->limit + 1;
}
if (s == &_ds)
if (s == &cpu_state.seg_ds)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
}
if (s == &_ss)
if (s == &cpu_state.seg_ss)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
@@ -331,11 +333,11 @@ void loadseg(uint16_t seg, x86seg *s)
uint32_t addr;
int dpl;
if (msw&1 && !(eflags&VM_FLAG))
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
{
if (!(seg&~3))
{
if (s==&_ss)
if (s==&cpu_state.seg_ss)
{
x86ss(NULL,0);
return;
@@ -343,14 +345,18 @@ void loadseg(uint16_t seg, x86seg *s)
s->seg=0;
s->access = 0x80;
s->base=-1;
if (s == &_ds)
if (s == &cpu_state.seg_ds)
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
return;
}
addr=seg&~7;
if (seg&4)
{
#if 0
if (addr>=ldt.limit)
#else
if ((addr+7)>ldt.limit)
#endif
{
x86gpf("loadseg(): Bigger than LDT limit",seg&~3);
return;
@@ -359,7 +365,11 @@ void loadseg(uint16_t seg, x86seg *s)
}
else
{
#if 0
if (addr>=gdt.limit)
#else
if ((addr+7)>gdt.limit)
#endif
{
x86gpf("loadseg(): Bigger than GDT limit",seg&~3);
return;
@@ -372,7 +382,7 @@ void loadseg(uint16_t seg, x86seg *s)
segdat[2]=readmemw(0,addr+4);
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
dpl=(segdat[2]>>13)&3;
if (s==&_ss)
if (s==&cpu_state.seg_ss)
{
if (!(seg&~3))
{
@@ -399,7 +409,7 @@ void loadseg(uint16_t seg, x86seg *s)
}
set_stack32((segdat[3] & 0x40) ? 1 : 0);
}
else if (s!=&_cs)
else if (s!=&cpu_state.seg_cs)
{
x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]);
x86seg_log("Seg type %03X\n",segdat[2]&0x1F00);
@@ -431,7 +441,7 @@ void loadseg(uint16_t seg, x86seg *s)
do_seg_load(s, segdat);
#ifndef CS_ACCESSED
if (s != &_cs)
if (s != &cpu_state.seg_cs)
{
#endif
#ifdef SEL_ACCESSED
@@ -444,9 +454,9 @@ void loadseg(uint16_t seg, x86seg *s)
#endif
s->checked = 0;
#ifdef USE_DYNAREC
if (s == &_ds)
if (s == &cpu_state.seg_ds)
codegen_flat_ds = 0;
if (s == &_ss)
if (s == &cpu_state.seg_ss)
codegen_flat_ss = 0;
#endif
}
@@ -455,25 +465,25 @@ void loadseg(uint16_t seg, x86seg *s)
s->access = (3 << 5) | 2 | 0x80;
s->base = seg << 4;
s->seg = seg;
if (s == &_ss)
set_stack32(0);
s->checked = 1;
#ifdef USE_DYNAREC
if (s == &_ds)
if (s == &cpu_state.seg_ds)
codegen_flat_ds = 0;
if (s == &_ss)
if (s == &cpu_state.seg_ss)
codegen_flat_ss = 0;
#endif
if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG))
set_stack32(0);
}
if (s == &_ds)
if (s == &cpu_state.seg_ds)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
}
if (s == &_ss)
if (s == &cpu_state.seg_ss)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
@@ -491,7 +501,7 @@ void loadcs(uint16_t seg)
uint16_t segdat[4];
uint32_t addr;
x86seg_log("Load CS %04X\n",seg);
if (msw&1 && !(eflags&VM_FLAG))
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
{
if (!(seg&~3))
{
@@ -549,10 +559,10 @@ void loadcs(uint16_t seg)
}
set_use32(segdat[3] & 0x40);
CS=(seg&~3)|CPL;
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
use32=(segdat[3]&0x40)?0x300:0;
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
#ifdef CS_ACCESSED
cpl_override = 1;
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
@@ -576,24 +586,24 @@ void loadcs(uint16_t seg)
}
else
{
_cs.base=seg<<4;
_cs.limit=0xFFFF;
_cs.limit_low = 0;
_cs.limit_high = 0xffff;
cpu_state.seg_cs.base=seg<<4;
cpu_state.seg_cs.limit=0xFFFF;
cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit_high = 0xffff;
CS=seg & 0xFFFF;
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80;
else _cs.access=(0<<5) | 2 | 0x80;
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
}
}
void loadcsjmp(uint16_t seg, uint32_t oxpc)
void loadcsjmp(uint16_t seg, uint32_t old_pc)
{
uint16_t segdat[4];
uint32_t addr;
uint16_t type,seg2;
uint32_t newpc;
if (msw&1 && !(eflags&VM_FLAG))
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
{
if (!(seg&~3))
{
@@ -661,7 +671,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
CS = (seg & ~3) | CPL;
segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
cycles -= timing_jmp_pm;
}
@@ -757,8 +767,9 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
}
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
CS=seg2;
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3]&0x40);
cpu_state.pc=newpc;
@@ -779,11 +790,11 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
case 0x100: /*286 Task gate*/
case 0x900: /*386 Task gate*/
cpu_state.pc=oxpc;
cpu_state.pc=old_pc;
optype=JMP;
cpl_override=1;
taskswitch286(seg,segdat,segdat[2]&0x800);
flags &= ~NT_FLAG;
cpu_state.flags &= ~NT_FLAG;
cpl_override=0;
return;
@@ -795,13 +806,13 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
}
else
{
_cs.base=seg<<4;
_cs.limit=0xFFFF;
_cs.limit_low = 0;
_cs.limit_high = 0xffff;
cpu_state.seg_cs.base=seg<<4;
cpu_state.seg_cs.limit=0xFFFF;
cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit_high = 0xffff;
CS=seg;
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80;
else _cs.access=(0<<5) | 2 | 0x80;
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
cycles -= timing_jmp_rm;
}
@@ -885,7 +896,7 @@ void loadcscall(uint16_t seg)
int csout = output;
if (msw&1 && !(eflags&VM_FLAG))
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
{
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
if (!(seg&~3))
@@ -964,8 +975,9 @@ void loadcscall(uint16_t seg)
else /*On non-conforming segments, set RPL = CPL*/
seg = (seg & ~3) | CPL;
CS=seg;
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
if (csout) x86seg_log("Complete\n");
cycles -= timing_call_pm;
}
@@ -1080,7 +1092,11 @@ void loadcscall(uint16_t seg)
addr=newss&~7;
if (newss&4)
{
#if 0
if (addr>=ldt.limit)
#else
if ((addr+7)>ldt.limit)
#endif
{
x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit);
x86ts(NULL,newss&~3);
@@ -1090,7 +1106,11 @@ void loadcscall(uint16_t seg)
}
else
{
#if 0
if (addr>=gdt.limit)
#else
if ((addr+7)>gdt.limit)
#endif
{
x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit);
x86ts(NULL,newss&~3);
@@ -1126,7 +1146,7 @@ void loadcscall(uint16_t seg)
if (stack32) ESP=newsp;
else SP=newsp;
do_seg_load(&_ss, segdat2);
do_seg_load(&cpu_state.seg_ss, segdat2);
x86seg_log("Set access 1\n");
@@ -1137,8 +1157,9 @@ void loadcscall(uint16_t seg)
#endif
CS=seg2;
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3]&0x40);
cpu_state.pc=newpc;
@@ -1216,7 +1237,7 @@ void loadcscall(uint16_t seg)
}
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
CS=seg2;
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3]&0x40);
cpu_state.pc=newpc;
@@ -1251,13 +1272,13 @@ void loadcscall(uint16_t seg)
}
else
{
_cs.base=seg<<4;
_cs.limit=0xFFFF;
_cs.limit_low = 0;
_cs.limit_high = 0xffff;
cpu_state.seg_cs.base=seg<<4;
cpu_state.seg_cs.limit=0xFFFF;
cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit_high = 0xffff;
CS=seg;
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80;
else _cs.access=(0<<5) | 2 | 0x80;
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
}
}
@@ -1269,7 +1290,7 @@ void pmoderetf(int is32, uint16_t off)
uint32_t addr, oaddr;
uint16_t segdat[4],segdat2[4],seg,newss;
uint32_t oldsp=ESP;
x86seg_log("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags);
x86seg_log("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,cpu_state.eflags);
if (is32)
{
newpc=POPL();
@@ -1367,8 +1388,8 @@ void pmoderetf(int is32, uint16_t off)
if (segdat[2] & 0x400)
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
CS = seg;
do_seg_load(&_cs, segdat);
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
do_seg_load(&cpu_state.seg_cs, segdat);
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3] & 0x40);
@@ -1481,7 +1502,7 @@ void pmoderetf(int is32, uint16_t off)
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
if (stack32) ESP=newsp;
else SP=newsp;
do_seg_load(&_ss, segdat2);
do_seg_load(&cpu_state.seg_ss, segdat2);
#ifdef SEL_ACCESSED
cpl_override = 1;
@@ -1498,24 +1519,24 @@ void pmoderetf(int is32, uint16_t off)
cpu_state.pc=newpc;
CS=seg;
do_seg_load(&_cs, segdat);
do_seg_load(&cpu_state.seg_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3] & 0x40);
if (stack32) ESP+=off;
else SP+=off;
check_seg_valid(&_ds);
check_seg_valid(&_es);
check_seg_valid(&_fs);
check_seg_valid(&_gs);
check_seg_valid(&cpu_state.seg_ds);
check_seg_valid(&cpu_state.seg_es);
check_seg_valid(&cpu_state.seg_fs);
check_seg_valid(&cpu_state.seg_gs);
cycles -= timing_retf_pm_outer;
}
}
void restore_stack()
{
ss=oldss; _ss.limit=oldsslimit;
ss=oldss; cpu_state.seg_ss.limit=oldsslimit;
}
void pmodeint(int num, int soft)
@@ -1529,7 +1550,7 @@ void pmodeint(int num, int soft)
uint16_t seg = 0;
int new_cpl;
if (eflags&VM_FLAG && IOPL!=3 && soft)
if (cpu_state.eflags&VM_FLAG && IOPL!=3 && soft)
{
x86seg_log("V86 banned int\n");
x86gpf(NULL,0);
@@ -1628,7 +1649,7 @@ void pmodeint(int num, int soft)
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
return;
}
if ((eflags&VM_FLAG) && DPL2)
if ((cpu_state.eflags&VM_FLAG) && DPL2)
{
x86gpf(NULL,segdat[1]&0xFFFC);
return;
@@ -1698,7 +1719,7 @@ void pmodeint(int num, int soft)
set_stack32((segdat3[3] & 0x40) ? 1 : 0);
if (stack32) ESP=newsp;
else SP=newsp;
do_seg_load(&_ss, segdat3);
do_seg_load(&cpu_state.seg_ss, segdat3);
#ifdef CS_ACCESSED
cpl_override = 1;
@@ -1710,20 +1731,20 @@ void pmodeint(int num, int soft)
cpl_override=1;
if (type>=0x800)
{
if (eflags & VM_FLAG)
if (cpu_state.eflags & VM_FLAG)
{
PUSHL(GS);
PUSHL(FS);
PUSHL(DS);
PUSHL(ES); if (cpu_state.abrt) return;
loadseg(0,&_ds);
loadseg(0,&_es);
loadseg(0,&_fs);
loadseg(0,&_gs);
loadseg(0,&cpu_state.seg_ds);
loadseg(0,&cpu_state.seg_es);
loadseg(0,&cpu_state.seg_fs);
loadseg(0,&cpu_state.seg_gs);
}
PUSHL(oldss);
PUSHL(oldsp);
PUSHL(flags|(eflags<<16));
PUSHL(cpu_state.flags|(cpu_state.eflags<<16));
PUSHL(CS);
PUSHL(cpu_state.pc); if (cpu_state.abrt) return;
}
@@ -1731,12 +1752,12 @@ void pmodeint(int num, int soft)
{
PUSHW(oldss);
PUSHW(oldsp);
PUSHW(flags);
PUSHW(cpu_state.flags);
PUSHW(CS);
PUSHW(cpu_state.pc); if (cpu_state.abrt) return;
}
cpl_override=0;
_cs.access=0 | 0x80;
cpu_state.seg_cs.access=0 | 0x80;
cycles -= timing_int_pm_outer - timing_int_pm;
break;
}
@@ -1751,20 +1772,20 @@ void pmodeint(int num, int soft)
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
return;
}
if ((eflags & VM_FLAG) && DPL2<CPL)
if ((cpu_state.eflags & VM_FLAG) && DPL2<CPL)
{
x86gpf(NULL,seg&~3);
return;
}
if (type>0x800)
{
PUSHL(flags|(eflags<<16));
PUSHL(cpu_state.flags|(cpu_state.eflags<<16));
PUSHL(CS);
PUSHL(cpu_state.pc); if (cpu_state.abrt) return;
}
else
{
PUSHW(flags);
PUSHW(cpu_state.flags);
PUSHW(CS);
PUSHW(cpu_state.pc); if (cpu_state.abrt) return;
}
@@ -1774,9 +1795,9 @@ void pmodeint(int num, int soft)
x86gpf(NULL,seg&~3);
return;
}
do_seg_load(&_cs, segdat2);
do_seg_load(&cpu_state.seg_cs, segdat2);
CS = (seg & ~3) | new_cpl;
_cs.access = (_cs.access & ~(3 << 5)) | (new_cpl << 5);
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16);
else cpu_state.pc=segdat[0];
@@ -1788,13 +1809,13 @@ void pmodeint(int num, int soft)
cpl_override = 0;
#endif
eflags&=~VM_FLAG;
cpu_state.eflags&=~VM_FLAG;
cpu_cur_status &= ~CPU_STATUS_V86;
if (!(type&0x100))
{
flags&=~I_FLAG;
cpu_state.flags&=~I_FLAG;
}
flags&=~(T_FLAG|NT_FLAG);
cpu_state.flags&=~(T_FLAG|NT_FLAG);
cycles -= timing_int_pm;
break;
@@ -1853,14 +1874,14 @@ void pmodeiret(int is32)
uint16_t seg;
uint32_t addr, oaddr;
uint32_t oldsp=ESP;
if (is386 && (eflags&VM_FLAG))
if (is386 && (cpu_state.eflags&VM_FLAG))
{
if (IOPL!=3)
{
x86gpf(NULL,0);
return;
}
oxpc=cpu_state.pc;
oxpc=cpu_state.pc;
if (is32)
{
newpc=POPL();
@@ -1873,19 +1894,19 @@ void pmodeiret(int is32)
seg=POPW();
tempflags=POPW(); if (cpu_state.abrt) return;
}
cpu_state.pc=newpc;
_cs.base=seg<<4;
_cs.limit=0xFFFF;
_cs.limit_low = 0;
_cs.limit_high = 0xffff;
_cs.access |= 0x80;
cpu_state.pc = newpc;
cpu_state.seg_cs.base=seg<<4;
cpu_state.seg_cs.limit=0xFFFF;
cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit_high = 0xffff;
cpu_state.seg_cs.access |= 0x80;
CS=seg;
flags=(flags&0x3000)|(tempflags&0xCFD5)|2;
cpu_state.flags=(cpu_state.flags&0x3000)|(tempflags&0xCFD5)|2;
cycles -= timing_iret_rm;
return;
}
if (flags&NT_FLAG)
if (cpu_state.flags&NT_FLAG)
{
seg=readmemw(tr.base,0);
addr=seg&~7;
@@ -1913,7 +1934,7 @@ void pmodeiret(int is32)
cpl_override=0;
return;
}
oxpc=cpu_state.pc;
oxpc=cpu_state.pc;
flagmask=0xFFFF;
if (CPL) flagmask&=~0x3000;
if (IOPL<CPL) flagmask&=~0x200;
@@ -1930,34 +1951,34 @@ void pmodeiret(int is32)
segs[1]=POPL();
segs[2]=POPL();
segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; }
eflags=tempflags>>16;
cpu_state.eflags=tempflags>>16;
cpu_cur_status |= CPU_STATUS_V86;
loadseg(segs[0],&_es);
do_seg_v86_init(&_es);
loadseg(segs[1],&_ds);
do_seg_v86_init(&_ds);
loadseg(segs[0],&cpu_state.seg_es);
do_seg_v86_init(&cpu_state.seg_es);
loadseg(segs[1],&cpu_state.seg_ds);
do_seg_v86_init(&cpu_state.seg_ds);
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
loadseg(segs[2],&_fs);
do_seg_v86_init(&_fs);
loadseg(segs[3],&_gs);
do_seg_v86_init(&_gs);
loadseg(segs[2],&cpu_state.seg_fs);
do_seg_v86_init(&cpu_state.seg_fs);
loadseg(segs[3],&cpu_state.seg_gs);
do_seg_v86_init(&cpu_state.seg_gs);
cpu_state.pc=newpc;
_cs.base=seg<<4;
_cs.limit=0xFFFF;
_cs.limit_low = 0;
_cs.limit_high = 0xffff;
cpu_state.seg_cs.base=seg<<4;
cpu_state.seg_cs.limit=0xFFFF;
cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit_high = 0xffff;
CS=seg;
_cs.access=(3<<5) | 2 | 0x80;
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
ESP=newsp;
loadseg(newss,&_ss);
do_seg_v86_init(&_ss);
loadseg(newss,&cpu_state.seg_ss);
do_seg_v86_init(&cpu_state.seg_ss);
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
use32=0;
cpu_cur_status &= ~CPU_STATUS_USE32;
flags=(tempflags&0xFFD5)|2;
cpu_state.flags=(tempflags&0xFFD5)|2;
cycles -= timing_iret_v86;
return;
}
@@ -2040,8 +2061,8 @@ void pmodeiret(int is32)
if ((seg&3) == CPL)
{
CS=seg;
do_seg_load(&_cs, segdat);
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
do_seg_load(&cpu_state.seg_cs, segdat);
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3]&0x40);
@@ -2129,7 +2150,7 @@ void pmodeiret(int is32)
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
if (stack32) ESP=newsp;
else SP=newsp;
do_seg_load(&_ss, segdat2);
do_seg_load(&cpu_state.seg_ss, segdat2);
#ifdef SEL_ACCESSED
cpl_override = 1;
@@ -2145,20 +2166,20 @@ void pmodeiret(int is32)
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
CS=seg;
do_seg_load(&_cs, segdat);
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
do_seg_load(&cpu_state.seg_cs, segdat);
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat[3] & 0x40);
check_seg_valid(&_ds);
check_seg_valid(&_es);
check_seg_valid(&_fs);
check_seg_valid(&_gs);
check_seg_valid(&cpu_state.seg_ds);
check_seg_valid(&cpu_state.seg_es);
check_seg_valid(&cpu_state.seg_fs);
check_seg_valid(&cpu_state.seg_gs);
cycles -= timing_iret_pm_outer;
}
cpu_state.pc=newpc;
flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
if (is32) eflags=tempflags>>16;
cpu_state.flags=(cpu_state.flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
if (is32) cpu_state.eflags=tempflags>>16;
}
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
@@ -2205,12 +2226,12 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
}
if (cpu_state.abrt) return;
if (optype==IRET) flags&=~NT_FLAG;
if (optype==IRET) cpu_state.flags&=~NT_FLAG;
cpu_386_flags_rebuild();
writememl(tr.base,0x1C,cr3);
writememl(tr.base,0x20,cpu_state.pc);
writememl(tr.base,0x24,flags|(eflags<<16));
writememl(tr.base,0x24,cpu_state.flags|(cpu_state.eflags<<16));
writememl(tr.base,0x28,EAX);
writememl(tr.base,0x2C,ECX);
@@ -2276,8 +2297,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
flushmmucache();
cpu_state.pc=new_pc;
flags=new_flags;
eflags=new_flags>>16;
cpu_state.flags=new_flags;
cpu_state.eflags=new_flags>>16;
cpu_386_flags_extract();
ldt.seg=new_ldt;
@@ -2290,7 +2311,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
}
ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24);
if (eflags & VM_FLAG)
if (cpu_state.eflags & VM_FLAG)
{
loadcs(new_cs);
set_use32(0);
@@ -2353,7 +2374,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
}
CS=new_cs;
do_seg_load(&_cs, segdat2);
do_seg_load(&cpu_state.seg_cs, segdat2);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(segdat2[3] & 0x40);
cpu_cur_status &= ~CPU_STATUS_V86;
@@ -2368,11 +2389,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
ESI=new_esi;
EDI=new_edi;
loadseg(new_es,&_es);
loadseg(new_ss,&_ss);
loadseg(new_ds,&_ds);
loadseg(new_fs,&_fs);
loadseg(new_gs,&_gs);
loadseg(new_es,&cpu_state.seg_es);
loadseg(new_ss,&cpu_state.seg_ss);
loadseg(new_ds,&cpu_state.seg_ds);
loadseg(new_fs,&cpu_state.seg_fs);
loadseg(new_gs,&cpu_state.seg_gs);
}
else
{
@@ -2393,11 +2414,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
}
if (cpu_state.abrt) return;
if (optype==IRET) flags&=~NT_FLAG;
if (optype==IRET) cpu_state.flags&=~NT_FLAG;
cpu_386_flags_rebuild();
writememw(tr.base,0x0E,cpu_state.pc);
writememw(tr.base,0x10,flags);
writememw(tr.base,0x10,cpu_state.flags);
writememw(tr.base,0x12,AX);
writememw(tr.base,0x14,CX);
@@ -2454,7 +2475,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
msw |= 8;
cpu_state.pc=new_pc;
flags=new_flags;
cpu_state.flags=new_flags;
cpu_386_flags_extract();
ldt.seg=new_ldt;
@@ -2526,7 +2547,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
}
CS=new_cs;
do_seg_load(&_cs, segdat2);
do_seg_load(&cpu_state.seg_cs, segdat2);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(0);
@@ -2539,13 +2560,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
ESI=new_esi | 0xFFFF0000;
EDI=new_edi | 0xFFFF0000;
loadseg(new_es,&_es);
loadseg(new_ss,&_ss);
loadseg(new_ds,&_ds);
loadseg(new_es,&cpu_state.seg_es);
loadseg(new_ss,&cpu_state.seg_ss);
loadseg(new_ds,&cpu_state.seg_ds);
if (is386)
{
loadseg(0,&_fs);
loadseg(0,&_gs);
loadseg(0,&cpu_state.seg_fs);
loadseg(0,&cpu_state.seg_gs);
}
}

View File

@@ -65,6 +65,7 @@ void x87_settag(uint16_t new_tag)
cpu_state.tag[7] = (new_tag >> 14) & 3;
}
#ifdef ENABLE_808X_LOG
void x87_dumpregs()
{

View File

@@ -1,6 +1,24 @@
uint32_t x87_pc_off,x87_op_off;
uint16_t x87_pc_seg,x87_op_seg;
static __inline void x87_set_mmx()
{
uint64_t *p;
cpu_state.TOP = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0;
cpu_state.ismmx = 1;
}
static __inline void x87_emms()
{
uint64_t *p;
p = (uint64_t *)cpu_state.tag;
*p = 0;
cpu_state.ismmx = 0;
}
uint16_t x87_gettag();
void x87_settag(uint16_t new_tag);

View File

@@ -1,42 +1,24 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the VARCem Project.
* This file is part of the 86Box distribution.
*
* x87 FPU instructions core.
*
* Version: @(#)x87_ops.h 1.0.7 2018/10/17
* Version: @(#)x87_ops.h 1.0.8 2019/06/11
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 leilei.
* Copyright 2016-2019 Miran Grca.
* Copyright 2018,2019 Fred N. van Kempen.
*/
#include <math.h>
#include <fenv.h>
@@ -63,41 +45,47 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ
#define STATUS_ZERODIVIDE 4
#ifdef FPU_8087
#define x87_div(dst, src1, src2) do \
{ \
if (((double)src2) == 0.0) \
{ \
cpu_state.npxs |= STATUS_ZERODIVIDE; \
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
cpu_state.npxs |= STATUS_ZERODIVIDE; \
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
dst = src1 / (double)src2; \
else \
{ \
fpu_log("FPU : divide by zero\n"); \
picint(1 << 13); \
if (!(cpu_state.npxc & 0x80)) { \
cpu_state.npxs |= 0x80; \
nmi = 1; \
} \
return 1; \
} \
return 1; \
} \
else \
dst = src1 / (double)src2; \
} while (0)
#else
#define x87_div(dst, src1, src2) do \
{ \
if (((double)src2) == 0.0) \
{ \
cpu_state.npxs |= STATUS_ZERODIVIDE; \
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
dst = src1 / (double)src2; \
else \
{ \
fpu_log("FPU : divide by zero\n"); \
picint(1 << 13); \
return 1; \
} \
} \
else \
dst = src1 / (double)src2; \
} while (0)
#endif
static __inline void x87_set_mmx()
{
uint64_t *p;
cpu_state.TOP = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0;
cpu_state.ismmx = 1;
}
static __inline void x87_emms()
{
uint64_t *p;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.ismmx = 0;
}
static __inline void x87_checkexceptions()
{
}
@@ -286,44 +274,24 @@ static __inline void x87_stmmx(MMX_REG r)
writememw(easeg, cpu_state.eaaddr + 8, 0xffff);
}
#include <inttypes.h>
static __inline uint16_t x87_compare(double a, double b)
{
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64
uint32_t result;
double ea = a, eb = b;
const uint64_t ia = 0x3fec1a6ff866a936ull;
const uint64_t ib = 0x3fec1a6ff866a938ull;
if (!is386)
{
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
{
/* fpu_log("Comparing infinity\n"); */
#ifndef _MSC_VER
__asm volatile ("" : : : "memory");
__asm(
"fldl %2\n"
"fldl %1\n"
"fclex\n"
"fcompp\n"
"fnstsw %0\n"
: "=m" (result)
: "m" (a), "m" (a)
);
#else
_ReadWriteBarrier();
__asm
{
fld a
fld a
fclex
fcompp
fnstsw result
}
#endif
/* Hack to make CHKCOP happy. */
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
return C3;
if (!is386 && !(cpu_state.npxc & 0x1000) &&
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
eb = ea;
return result & (C0|C2|C3);
}
}
#ifndef _MSC_VER
/* Memory barrier, to force GCC to write to the input parameters
* before the compare rather than after */
@@ -336,14 +304,14 @@ static __inline uint16_t x87_compare(double a, double b)
"fcompp\n"
"fnstsw %0\n"
: "=m" (result)
: "m" (a), "m" (b)
: "m" (ea), "m" (eb)
);
#else
_ReadWriteBarrier();
_asm
{
fld b
fld a
fld eb
fld ea
fclex
fcompp
fnstsw result
@@ -355,43 +323,32 @@ static __inline uint16_t x87_compare(double a, double b)
/* Generic C version is known to give incorrect results in some
* situations, eg comparison of infinity (Unreal) */
uint32_t result = 0;
double ea = a, eb = b;
if (is386)
{
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
{
result |= C3;
return result;
}
if (!is386 && !(cpu_state.npxc & 0x1000) &&
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
eb = ea;
if (a == b)
result |= C3;
else if (a < b)
result |= C0;
}
else
{
if (a == b)
result |= C3;
else if (a < b)
result |= C0;
}
if (ea == eb)
result |= C3;
else if (ea < eb)
result |= C0;
return result;
#endif
}
static __inline uint16_t x87_ucompare(double a, double b)
static inline uint16_t x87_ucompare(double a, double b)
{
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__
uint32_t result;
#ifndef _MSC_VER
/* Memory barrier, to force GCC to write to the input parameters
* before the compare rather than after */
__asm volatile ("" : : : "memory");
asm volatile ("" : : : "memory");
__asm(
asm(
"fldl %2\n"
"fldl %1\n"
"fclex\n"
@@ -439,6 +396,11 @@ typedef union
uint64_t i;
} x87_td;
#ifdef FPU_8087
#define FP_ENTER() { \
fpucount++; \
}
#else
#define FP_ENTER() do \
{ \
if (cr0 & 0xc) \
@@ -448,11 +410,13 @@ typedef union
} \
fpucount++; \
} while (0)
#endif
#include "x87_ops_arith.h"
#include "x87_ops_misc.h"
#include "x87_ops_loadstore.h"
#ifndef FPU_8087
static int op_nofpu_a16(uint32_t fetchdat)
{
if (cr0 & 0xc)
@@ -479,7 +443,16 @@ static int op_nofpu_a32(uint32_t fetchdat)
return 0;
}
}
#endif
#ifdef FPU_8087
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
{
geteaw();
wait(timing_rr, 0);
return 0;
}
#else
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
{
fetch_ea_16(fetchdat);
@@ -495,8 +468,261 @@ static int FPU_ILLEGAL_a32(uint32_t fetchdat)
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
return 0;
}
#endif
#define ILLEGAL_a16 FPU_ILLEGAL_a16
#ifdef FPU_8087
const OpFn OP_TABLE(fpu_8087_d8)[32] =
{
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
const OpFn OP_TABLE(fpu_8087_d9)[256] =
{
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD,
opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH,
opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/
opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP,
opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16
};
const OpFn OP_TABLE(fpu_8087_da)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
const OpFn OP_TABLE(fpu_8087_db)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFI, opFI, opFCLEX, opFINIT, ILLEGAL_a16, opFNOP, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
const OpFn OP_TABLE(fpu_8087_dc)[32] =
{
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
const OpFn OP_TABLE(fpu_8087_dd)[256] =
{
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST,
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
const OpFn OP_TABLE(fpu_8087_de)[256] =
{
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP,
opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP,
opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP,
opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP,
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
const OpFn OP_TABLE(fpu_8087_df)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
#else
#define ILLEGAL_a32 FPU_ILLEGAL_a32
const OpFn OP_TABLE(fpu_d8_a16)[32] =
@@ -824,6 +1050,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
const OpFn OP_TABLE(fpu_686_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
@@ -900,6 +1127,7 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
#endif
const OpFn OP_TABLE(fpu_287_db_a16)[256] =
{
@@ -1055,6 +1283,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
const OpFn OP_TABLE(fpu_686_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
@@ -1131,6 +1360,7 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] =
opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
#endif
const OpFn OP_TABLE(fpu_287_dc_a16)[32] =
{
@@ -1626,6 +1856,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
const OpFn OP_TABLE(fpu_686_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
@@ -1702,6 +1933,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] =
opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
#endif
const OpFn OP_TABLE(nofpu_a16)[256] =
{
@@ -1779,3 +2011,6 @@ const OpFn OP_TABLE(nofpu_a32)[256] =
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
};
#endif
#undef ILLEGAL

View File

@@ -4,13 +4,14 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
ST(0) += use_var; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(FE_TONEAREST); \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
CLOCK_CYCLES(8); \
return 0; \
} \
@@ -19,6 +20,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
cpu_state.npxs &= ~(C0|C2|C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
@@ -30,6 +32,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
cpu_state.npxs &= ~(C0|C2|C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
@@ -42,9 +45,10 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), ST(0), use_var); \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
CLOCK_CYCLES(73); \
return 0; \
} \
@@ -53,9 +57,10 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), use_var, ST(0)); \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
CLOCK_CYCLES(73); \
return 0; \
} \
@@ -64,6 +69,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) *= use_var; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
@@ -75,9 +81,10 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) -= use_var; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
CLOCK_CYCLES(8); \
return 0; \
} \
@@ -86,23 +93,32 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) = use_var - ST(0); \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
CLOCK_CYCLES(8); \
return 0; \
}
opFPU(s, x87_ts, 16, t.i, geteal, t.s)
#ifndef FPU_8087
opFPU(s, x87_ts, 32, t.i, geteal, t.s)
#endif
opFPU(d, x87_td, 16, t.i, geteaq, t.d)
#ifndef FPU_8087
opFPU(d, x87_td, 32, t.i, geteaq, t.d)
#endif
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t)
#ifndef FPU_8087
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t)
#endif
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t)
#ifndef FPU_8087
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t)
#endif
@@ -111,7 +127,6 @@ static int opFADD(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FADD\n");
ST(0) = ST(0) + ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(8);
@@ -121,7 +136,6 @@ static int opFADDr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FADD\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
CLOCK_CYCLES(8);
@@ -131,7 +145,6 @@ static int opFADDP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FADDP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -143,7 +156,6 @@ static int opFCOM(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FCOM\n");
cpu_state.npxs &= ~(C0|C2|C3);
if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0;
@@ -155,7 +167,6 @@ static int opFCOMP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FCOMP\n");
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
x87_pop();
@@ -168,7 +179,6 @@ static int opFCOMPP(uint32_t fetchdat)
uint64_t *p, *q;
FP_ENTER();
cpu_state.pc++;
fpu_log("FCOMPP\n");
cpu_state.npxs &= ~(C0|C2|C3);
p = (uint64_t *)&ST(0);
q = (uint64_t *)&ST(1);
@@ -182,11 +192,11 @@ static int opFCOMPP(uint32_t fetchdat)
CLOCK_CYCLES(4);
return 0;
}
#ifndef FPU_8087
static int opFUCOMPP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FUCOMPP\n", easeg, cpu_state.eaaddr);
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
x87_pop();
@@ -195,15 +205,15 @@ static int opFUCOMPP(uint32_t fetchdat)
return 0;
}
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
static int opFCOMI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FICOM\n");
flags_rebuild();
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(4);
return 0;
}
@@ -211,21 +221,21 @@ static int opFCOMIP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FICOMP\n");
flags_rebuild();
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
#endif
#endif
static int opFDIV(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDIV\n");
x87_div(ST(0), ST(0), ST(fetchdat & 7));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(73);
@@ -235,7 +245,6 @@ static int opFDIVr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDIV\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
CLOCK_CYCLES(73);
@@ -245,7 +254,6 @@ static int opFDIVP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDIVP\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -257,7 +265,6 @@ static int opFDIVR(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDIVR\n");
x87_div(ST(0), ST(fetchdat&7), ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(73);
@@ -267,7 +274,6 @@ static int opFDIVRr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
CLOCK_CYCLES(73);
@@ -277,7 +283,6 @@ static int opFDIVRP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -289,7 +294,6 @@ static int opFMUL(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FMUL\n");
ST(0) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(16);
@@ -299,7 +303,6 @@ static int opFMULr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FMUL\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
CLOCK_CYCLES(16);
@@ -309,7 +312,6 @@ static int opFMULP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FMULP\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -321,7 +323,6 @@ static int opFSUB(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSUB\n");
ST(0) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(8);
@@ -331,7 +332,6 @@ static int opFSUBr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSUB\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
CLOCK_CYCLES(8);
@@ -341,7 +341,6 @@ static int opFSUBP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSUBP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -353,7 +352,6 @@ static int opFSUBR(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSUBR\n");
ST(0) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(8);
@@ -363,7 +361,6 @@ static int opFSUBRr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSUBR\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
CLOCK_CYCLES(8);
@@ -373,7 +370,6 @@ static int opFSUBRP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSUBRP\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -381,11 +377,11 @@ static int opFSUBRP(uint32_t fetchdat)
return 0;
}
#ifndef FPU_8087
static int opFUCOM(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FUCOM\n");
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
CLOCK_CYCLES(4);
@@ -396,7 +392,6 @@ static int opFUCOMP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FUCOMP\n");
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
x87_pop();
@@ -404,15 +399,15 @@ static int opFUCOMP(uint32_t fetchdat)
return 0;
}
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
static int opFUCOMI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FUCOMI\n");
flags_rebuild();
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(4);
return 0;
}
@@ -420,12 +415,13 @@ static int opFUCOMIP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FUCOMIP\n");
flags_rebuild();
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
#endif
#endif

View File

@@ -8,12 +8,12 @@
*
* x87 FPU instructions core.
*
* Version: @(#)x87_ops_loadstore.h 1.0.1 2017/10/17
* Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
static int opFILDiw_a16(uint32_t fetchdat)
@@ -21,32 +21,32 @@ static int opFILDiw_a16(uint32_t fetchdat)
int16_t temp;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", (double)temp);
x87_push((double)temp);
CLOCK_CYCLES(13);
return 0;
}
#ifndef FPU_8087
static int opFILDiw_a32(uint32_t fetchdat)
{
int16_t temp;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", (double)temp);
x87_push((double)temp);
CLOCK_CYCLES(13);
return 0;
}
#endif
static int opFISTiw_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
@@ -54,12 +54,13 @@ static int opFISTiw_a16(uint32_t fetchdat)
CLOCK_CYCLES(29);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFISTiw_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
@@ -67,13 +68,14 @@ static int opFISTiw_a32(uint32_t fetchdat)
CLOCK_CYCLES(29);
return cpu_state.abrt;
}
#endif
static int opFISTPiw_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
@@ -82,12 +84,13 @@ static int opFISTPiw_a16(uint32_t fetchdat)
CLOCK_CYCLES(29);
return 0;
}
#ifndef FPU_8087
static int opFISTPiw_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
@@ -96,15 +99,15 @@ static int opFISTPiw_a32(uint32_t fetchdat)
CLOCK_CYCLES(29);
return 0;
}
#endif
static int opFILDiq_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = geteaq(); if (cpu_state.abrt) return 1;
fpu_log(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4));
x87_push((double)temp64);
cpu_state.MM[cpu_state.TOP].q = temp64;
cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
@@ -112,14 +115,14 @@ static int opFILDiq_a16(uint32_t fetchdat)
CLOCK_CYCLES(10);
return 0;
}
#ifndef FPU_8087
static int opFILDiq_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = geteaq(); if (cpu_state.abrt) return 1;
fpu_log(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4));
x87_push((double)temp64);
cpu_state.MM[cpu_state.TOP].q = temp64;
cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
@@ -127,6 +130,7 @@ static int opFILDiq_a32(uint32_t fetchdat)
CLOCK_CYCLES(10);
return 0;
}
#endif
static int FBSTP_a16(uint32_t fetchdat)
{
@@ -134,7 +138,7 @@ static int FBSTP_a16(uint32_t fetchdat)
int c;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
tempd = ST(0);
if (tempd < 0.0)
tempd = -tempd;
@@ -154,13 +158,14 @@ static int FBSTP_a16(uint32_t fetchdat)
x87_pop();
return 0;
}
#ifndef FPU_8087
static int FBSTP_a32(uint32_t fetchdat)
{
double tempd;
int c;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
tempd = ST(0);
if (tempd < 0.0)
tempd = -tempd;
@@ -180,13 +185,14 @@ static int FBSTP_a32(uint32_t fetchdat)
x87_pop();
return 0;
}
#endif
static int FISTPiq_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)
temp64 = cpu_state.MM[cpu_state.TOP].q;
else
@@ -196,12 +202,13 @@ static int FISTPiq_a16(uint32_t fetchdat)
CLOCK_CYCLES(29);
return 0;
}
#ifndef FPU_8087
static int FISTPiq_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)
temp64 = cpu_state.MM[cpu_state.TOP].q;
else
@@ -211,38 +218,39 @@ static int FISTPiq_a32(uint32_t fetchdat)
CLOCK_CYCLES(29);
return 0;
}
#endif
static int opFILDil_a16(uint32_t fetchdat)
{
int32_t templ;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
fpu_log(" %f %08X %i\n", (double)templ, templ, templ);
x87_push((double)templ);
CLOCK_CYCLES(9);
return 0;
}
#ifndef FPU_8087
static int opFILDil_a32(uint32_t fetchdat)
{
int32_t templ;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
fpu_log(" %f %08X %i\n", (double)templ, templ, templ);
x87_push((double)templ);
CLOCK_CYCLES(9);
return 0;
}
#endif
static int opFISTil_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
@@ -250,12 +258,13 @@ static int opFISTil_a16(uint32_t fetchdat)
CLOCK_CYCLES(28);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFISTil_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
@@ -263,13 +272,14 @@ static int opFISTil_a32(uint32_t fetchdat)
CLOCK_CYCLES(28);
return cpu_state.abrt;
}
#endif
static int opFISTPil_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
@@ -278,12 +288,13 @@ static int opFISTPil_a16(uint32_t fetchdat)
CLOCK_CYCLES(28);
return 0;
}
#ifndef FPU_8087
static int opFISTPil_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
@@ -292,197 +303,208 @@ static int opFISTPil_a32(uint32_t fetchdat)
CLOCK_CYCLES(28);
return 0;
}
#endif
static int opFLDe_a16(uint32_t fetchdat)
{
double t;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
t=x87_ld80(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", t);
x87_push(t);
CLOCK_CYCLES(6);
return 0;
}
#ifndef FPU_8087
static int opFLDe_a32(uint32_t fetchdat)
{
double t;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
t=x87_ld80(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", t);
x87_push(t);
CLOCK_CYCLES(6);
return 0;
}
#endif
static int opFSTPe_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(6);
return 0;
}
#ifndef FPU_8087
static int opFSTPe_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(6);
return 0;
}
#endif
static int opFLDd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
t.i = geteaq(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", t.d);
x87_push(t.d);
CLOCK_CYCLES(3);
return 0;
}
#ifndef FPU_8087
static int opFLDd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
t.i = geteaq(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", t.d);
x87_push(t.d);
CLOCK_CYCLES(3);
return 0;
}
#endif
static int opFSTd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
t.d = ST(0);
seteaq(t.i);
CLOCK_CYCLES(8);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
t.d = ST(0);
seteaq(t.i);
CLOCK_CYCLES(8);
return cpu_state.abrt;
}
#endif
static int opFSTPd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
t.d = ST(0);
seteaq(t.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
#ifndef FPU_8087
static int opFSTPd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
t.d = ST(0);
seteaq(t.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
#endif
static int opFLDs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
ts.i = geteal(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", ts.s);
x87_push((double)ts.s);
CLOCK_CYCLES(3);
return 0;
}
#ifndef FPU_8087
static int opFLDs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
ts.i = geteal(); if (cpu_state.abrt) return 1;
fpu_log(" %f\n", ts.s);
x87_push((double)ts.s);
CLOCK_CYCLES(3);
return 0;
}
#endif
static int opFSTs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i);
CLOCK_CYCLES(7);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i);
CLOCK_CYCLES(7);
return cpu_state.abrt;
}
#endif
static int opFSTPs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(7);
return 0;
}
#ifndef FPU_8087
static int opFSTPs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(7);
return 0;
}
#endif

View File

@@ -1,12 +1,24 @@
#ifdef FPU_8087
static int opFI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxc &= ~0x80;
if (rmdat == 0xe1)
cpu_state.npxc |= 0x80;
wait(3, 0);
return 0;
}
#else
static int opFSTSW_AX(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSTSW\n");
AX = cpu_state.npxs;
CLOCK_CYCLES(3);
return 0;
}
#endif
@@ -32,7 +44,11 @@ static int opFINIT(uint32_t fetchdat)
uint64_t *p;
FP_ENTER();
cpu_state.pc++;
#ifdef FPU_8087
cpu_state.npxc = 0x3FF;
#else
cpu_state.npxc = 0x37F;
#endif
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
@@ -40,6 +56,7 @@ static int opFINIT(uint32_t fetchdat)
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES(17);
CPU_BLOCK_END();
return 0;
}
@@ -48,7 +65,6 @@ static int opFFREE(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FFREE\n");
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3;
CLOCK_CYCLES(3);
return 0;
@@ -58,7 +74,6 @@ static int opFFREEP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FFREE\n");
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(3);
@@ -69,7 +84,6 @@ static int opFST(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FST\n");
ST(fetchdat & 7) = ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
CLOCK_CYCLES(3);
@@ -80,7 +94,6 @@ static int opFSTP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSTP\n");
ST(fetchdat & 7) = ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
x87_pop();
@@ -135,30 +148,32 @@ static int FSTOR()
cpu_state.ismmx = 1;
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
fpu_log("FRSTOR %08X:%08X %i %i %04X\n", easeg, cpu_state.eaaddr, cpu_state.ismmx, cpu_state.TOP, x87_gettag());
return cpu_state.abrt;
}
static int opFSTOR_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FSTOR();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTOR_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FSTOR();
return cpu_state.abrt;
}
#endif
static int FSAVE()
{
uint64_t *p;
FP_ENTER();
fpu_log("FSAVE %08X:%08X %i\n", easeg, cpu_state.eaaddr, cpu_state.ismmx);
cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11);
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
@@ -305,35 +320,41 @@ static int opFSAVE_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSAVE();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSAVE_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSAVE();
return cpu_state.abrt;
}
#endif
static int opFSTSW_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11));
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTSW_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11));
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#endif
static int opFLD(uint32_t fetchdat)
@@ -343,7 +364,6 @@ static int opFLD(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
fpu_log("FLD %f\n", ST(fetchdat & 7));
old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7];
old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q;
x87_push(ST(fetchdat&7));
@@ -360,7 +380,6 @@ static int opFXCH(uint32_t fetchdat)
uint64_t old_i64;
FP_ENTER();
cpu_state.pc++;
fpu_log("FXCH\n");
td = ST(0);
ST(0) = ST(fetchdat&7);
ST(fetchdat&7) = td;
@@ -379,7 +398,6 @@ static int opFCHS(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FCHS\n");
ST(0) = -ST(0);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(6);
@@ -390,7 +408,6 @@ static int opFABS(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FABS %f\n", ST(0));
ST(0) = fabs(ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(3);
@@ -401,7 +418,6 @@ static int opFTST(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FTST\n");
cpu_state.npxs &= ~(C0|C2|C3);
if (ST(0) == 0.0) cpu_state.npxs |= C3;
else if (ST(0) < 0.0) cpu_state.npxs |= C0;
@@ -413,9 +429,8 @@ static int opFXAM(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FXAM %i %f\n", cpu_state.tag[cpu_state.TOP&7], ST(0));
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
else cpu_state.npxs |= C2;
if (ST(0) < 0.0) cpu_state.npxs |= C1;
@@ -427,7 +442,6 @@ static int opFLD1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLD1\n");
x87_push(1.0);
CLOCK_CYCLES(4);
return 0;
@@ -437,7 +451,6 @@ static int opFLDL2T(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLDL2T\n");
x87_push(3.3219280948873623);
CLOCK_CYCLES(8);
return 0;
@@ -447,7 +460,6 @@ static int opFLDL2E(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLDL2E\n");
x87_push(1.4426950408889634);
CLOCK_CYCLES(8);
return 0;
@@ -457,7 +469,6 @@ static int opFLDPI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLDPI\n");
x87_push(3.141592653589793);
CLOCK_CYCLES(8);
return 0;
@@ -467,7 +478,6 @@ static int opFLDEG2(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLDEG2\n");
x87_push(0.3010299956639812);
CLOCK_CYCLES(8);
return 0;
@@ -477,7 +487,6 @@ static int opFLDLN2(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLDLN2\n");
x87_push_u64(0x3fe62e42fefa39f0ull);
CLOCK_CYCLES(8);
return 0;
@@ -487,7 +496,6 @@ static int opFLDZ(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FLDZ\n");
x87_push(0.0);
cpu_state.tag[cpu_state.TOP&7] = 1;
CLOCK_CYCLES(4);
@@ -498,7 +506,6 @@ static int opF2XM1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("F2XM1\n");
ST(0) = pow(2.0, ST(0)) - 1.0;
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(200);
@@ -509,7 +516,6 @@ static int opFYL2X(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FYL2X\n");
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -521,7 +527,6 @@ static int opFYL2XP1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FYL2XP1\n");
ST(1) = ST(1) * (log1p(ST(0)) / log(2.0));
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -533,7 +538,6 @@ static int opFPTAN(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FPTAN\n");
ST(0) = tan(ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
x87_push(1.0);
@@ -546,7 +550,6 @@ static int opFPATAN(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FPATAN\n");
ST(1) = atan2(ST(1), ST(0));
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
x87_pop();
@@ -558,7 +561,6 @@ static int opFDECSTP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDECSTP\n");
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
CLOCK_CYCLES(4);
return 0;
@@ -568,7 +570,6 @@ static int opFINCSTP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FDECSTP\n");
cpu_state.TOP = (cpu_state.TOP + 1) & 7;
CLOCK_CYCLES(4);
return 0;
@@ -579,11 +580,9 @@ static int opFPREM(uint32_t fetchdat)
int64_t temp64;
FP_ENTER();
cpu_state.pc++;
fpu_log("FPREM %f %f ", ST(0), ST(1));
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
fpu_log("%f\n", ST(0));
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) cpu_state.npxs|=C0;
if (temp64 & 2) cpu_state.npxs|=C3;
@@ -591,16 +590,15 @@ static int opFPREM(uint32_t fetchdat)
CLOCK_CYCLES(100);
return 0;
}
#ifndef FPU_8087
static int opFPREM1(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
cpu_state.pc++;
fpu_log("FPREM1 %f %f ", ST(0), ST(1));
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
fpu_log("%f\n", ST(0));
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) cpu_state.npxs|=C0;
if (temp64 & 2) cpu_state.npxs|=C3;
@@ -608,24 +606,24 @@ static int opFPREM1(uint32_t fetchdat)
CLOCK_CYCLES(100);
return 0;
}
#endif
static int opFSQRT(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSQRT\n");
ST(0) = sqrt(ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(83);
return 0;
}
#ifndef FPU_8087
static int opFSINCOS(uint32_t fetchdat)
{
double td;
FP_ENTER();
cpu_state.pc++;
fpu_log("FSINCOS\n");
td = ST(0);
ST(0) = sin(td);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
@@ -634,15 +632,14 @@ static int opFSINCOS(uint32_t fetchdat)
CLOCK_CYCLES(330);
return 0;
}
#endif
static int opFRNDINT(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FRNDINT %g ", ST(0));
ST(0) = (double)x87_fround(ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
fpu_log("%g\n", ST(0));
CLOCK_CYCLES(21);
return 0;
}
@@ -652,7 +649,6 @@ static int opFSCALE(uint32_t fetchdat)
int64_t temp64;
FP_ENTER();
cpu_state.pc++;
fpu_log("FSCALE\n");
temp64 = (int64_t)ST(1);
ST(0) = ST(0) * pow(2.0, (double)temp64);
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
@@ -660,11 +656,11 @@ static int opFSCALE(uint32_t fetchdat)
return 0;
}
#ifndef FPU_8087
static int opFSIN(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FSIN\n");
ST(0) = sin(ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
cpu_state.npxs &= ~C2;
@@ -676,19 +672,18 @@ static int opFCOS(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_log("FCOS\n");
ST(0) = cos(ST(0));
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;
}
#endif
static int FLDENV()
{
FP_ENTER();
fpu_log("FLDENV %08X:%08X\n", easeg, cpu_state.eaaddr);
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
@@ -716,23 +711,27 @@ static int opFLDENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FLDENV();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFLDENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FLDENV();
return cpu_state.abrt;
}
#endif
static int opFLDCW_a16(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt) return 1;
cpu_state.npxc = tempw;
@@ -740,12 +739,13 @@ static int opFLDCW_a16(uint32_t fetchdat)
CLOCK_CYCLES(4);
return 0;
}
#ifndef FPU_8087
static int opFLDCW_a32(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt) return 1;
cpu_state.npxc = tempw;
@@ -753,11 +753,11 @@ static int opFLDCW_a32(uint32_t fetchdat)
CLOCK_CYCLES(4);
return 0;
}
#endif
static int FSTENV()
{
FP_ENTER();
fpu_log("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr);
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
@@ -802,42 +802,49 @@ static int opFSTENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSTENV();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSTENV();
return cpu_state.abrt;
}
#endif
static int opFSTCW_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
fpu_log("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(cpu_state.npxc);
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTCW_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
fpu_log("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(cpu_state.npxc);
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#endif
#ifndef FPU_8087
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
#define opFCMOV(condition) \
static int opFCMOV ## condition(uint32_t fetchdat) \
{ \
FP_ENTER(); \
cpu_state.pc++; \
fpu_log("FCMOV %f\n", ST(fetchdat & 7)); \
if (cond_ ## condition) \
{ \
cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \
@@ -859,3 +866,5 @@ opFCMOV(NB)
opFCMOV(NE)
opFCMOV(NBE)
opFCMOV(NU)
#endif
#endif