New core_normal based on old core_16 for handling real and protected mode code.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1199
This commit is contained in:
parent
c71f9c3d1f
commit
e18440ce32
12 changed files with 3726 additions and 15 deletions
|
@ -1,6 +1,6 @@
|
|||
SUBDIRS = core_16 core_full
|
||||
SUBDIRS = core_16 core_full core_normal
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libcpu.a
|
||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \
|
||||
paging.cpp lazyflags.h
|
||||
paging.cpp lazyflags.h core_normal.cpp
|
221
src/cpu/core_normal.cpp
Normal file
221
src/cpu/core_normal.cpp
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "mem.h"
|
||||
#include "cpu.h"
|
||||
#include "lazyflags.h"
|
||||
#include "inout.h"
|
||||
#include "callback.h"
|
||||
#include "pic.h"
|
||||
#include "fpu.h"
|
||||
|
||||
#if C_DEBUG
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define SegBase(c) SegPhys(c)
|
||||
#if (!C_CORE_INLINE)
|
||||
|
||||
#define LoadMb(off) mem_readb(off)
|
||||
#define LoadMw(off) mem_readw(off)
|
||||
#define LoadMd(off) mem_readd(off)
|
||||
|
||||
#define SaveMb(off,val) mem_writeb(off,val)
|
||||
#define SaveMw(off,val) mem_writew(off,val)
|
||||
#define SaveMd(off,val) mem_writed(off,val)
|
||||
|
||||
#else
|
||||
|
||||
#include "paging.h"
|
||||
#define LoadMb(off) mem_readb_inline(off)
|
||||
#define LoadMw(off) mem_readw_inline(off)
|
||||
#define LoadMd(off) mem_readd_inline(off)
|
||||
|
||||
#define SaveMb(off,val) mem_writeb_inline(off,val)
|
||||
#define SaveMw(off,val) mem_writew_inline(off,val)
|
||||
#define SaveMd(off,val) mem_writed_inline(off,val)
|
||||
|
||||
#endif
|
||||
|
||||
#define LoadMbs(off) (Bit8s)(LoadMb(off))
|
||||
#define LoadMws(off) (Bit16s)(LoadMw(off))
|
||||
#define LoadMds(off) (Bit32s)(LoadMd(off))
|
||||
|
||||
#define LoadRb(reg) reg
|
||||
#define LoadRw(reg) reg
|
||||
#define LoadRd(reg) reg
|
||||
|
||||
#define SaveRb(reg,val) reg=val
|
||||
#define SaveRw(reg,val) reg=val
|
||||
#define SaveRd(reg,val) reg=val
|
||||
|
||||
extern Bitu cycle_count;
|
||||
|
||||
#if C_FPU
|
||||
#define CPU_FPU 1 //Enable FPU escape instructions
|
||||
#endif
|
||||
|
||||
#define CPU_PIC_CHECK 1
|
||||
#define CPU_TRAP_CHECK 1
|
||||
|
||||
#define OPCODE_NONE 0x000
|
||||
#define OPCODE_0F 0x100
|
||||
#define OPCODE_SIZE 0x200
|
||||
|
||||
#define PREFIX_SEG 0x1
|
||||
#define PREFIX_ADDR 0x2
|
||||
#define PREFIX_SEG_ADDR (PREFIX_SEG|PREFIX_ADDR)
|
||||
#define PREFIX_REP 0x4
|
||||
|
||||
#define TEST_PREFIX_SEG (core.prefixes & PREFIX_SEG)
|
||||
#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR)
|
||||
#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP)
|
||||
|
||||
#define DO_PREFIX_SEG(_SEG) \
|
||||
core.prefixes|=PREFIX_SEG; \
|
||||
core.seg_prefix_base=SegBase(_SEG); \
|
||||
goto restart_prefix;
|
||||
|
||||
#define DO_PREFIX_ADDR() \
|
||||
core.prefixes^=PREFIX_ADDR; \
|
||||
goto restart_prefix;
|
||||
|
||||
#define DO_PREFIX_REP(_ZERO) \
|
||||
core.prefixes|=PREFIX_REP; \
|
||||
core.rep_zero=_ZERO; \
|
||||
goto restart_prefix;
|
||||
|
||||
typedef PhysPt (*GetEATable[256])(void);
|
||||
|
||||
static struct {
|
||||
Bitu opcode_index;
|
||||
Bitu prefixes;
|
||||
Bitu index_default;
|
||||
Bitu prefix_default;
|
||||
PhysPt op_start;
|
||||
PhysPt ip_lookup;
|
||||
PhysPt seg_prefix_base;
|
||||
bool rep_zero;
|
||||
GetEATable * ea_table;
|
||||
} core;
|
||||
|
||||
#include "instructions.h"
|
||||
#include "core_normal/support.h"
|
||||
#include "core_normal/string.h"
|
||||
|
||||
static GetEATable * EAPrefixTable[8] = {
|
||||
&GetEA_NONE,&GetEA_SEG,&GetEA_ADDR,&GetEA_SEG_ADDR,
|
||||
&GetEA_NONE,&GetEA_SEG,&GetEA_ADDR,&GetEA_SEG_ADDR,
|
||||
};
|
||||
|
||||
#define CASE_W(_WHICH) \
|
||||
case (OPCODE_NONE+_WHICH):
|
||||
|
||||
#define CASE_D(_WHICH) \
|
||||
case (OPCODE_SIZE+_WHICH):
|
||||
|
||||
#define CASE_B(_WHICH) \
|
||||
CASE_W(_WHICH) \
|
||||
CASE_D(_WHICH)
|
||||
|
||||
#define CASE_0F_W(_WHICH) \
|
||||
case ((OPCODE_0F|OPCODE_NONE)+_WHICH):
|
||||
|
||||
#define CASE_0F_D(_WHICH) \
|
||||
case ((OPCODE_0F|OPCODE_SIZE)+_WHICH):
|
||||
|
||||
#define CASE_0F_B(_WHICH) \
|
||||
CASE_0F_W(_WHICH) \
|
||||
CASE_0F_D(_WHICH)
|
||||
|
||||
#define EALookupTable (*(core.ea_table))
|
||||
|
||||
|
||||
static Bits CPU_Core_Normal_Decode_Trap(void);
|
||||
|
||||
static Bits CPU_Core_Normal_Decode(void) {
|
||||
decode_start:
|
||||
LOADIP;
|
||||
flags.type=t_UNKNOWN;
|
||||
while (CPU_Cycles>0) {
|
||||
core.op_start=core.ip_lookup;
|
||||
core.opcode_index=core.index_default;
|
||||
core.prefixes=core.prefix_default;
|
||||
#if C_DEBUG
|
||||
cycle_count++;
|
||||
#if C_HEAVY_DEBUG
|
||||
SAVEIP;
|
||||
if (DEBUG_HeavyIsBreakpoint()) {
|
||||
LEAVECORE;
|
||||
return debugCallback;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
CPU_Cycles--;
|
||||
restart_prefix:
|
||||
core.ea_table=EAPrefixTable[core.prefixes];
|
||||
restart_opcode:
|
||||
switch (core.opcode_index+Fetchb()) {
|
||||
|
||||
#include "core_normal/prefix_none.h"
|
||||
#include "core_normal/prefix_0f.h"
|
||||
#include "core_normal/prefix_66.h"
|
||||
#include "core_normal/prefix_66_0f.h"
|
||||
default:
|
||||
ADDIPFAST(-1);
|
||||
LOG_MSG("Unhandled code %X",core.opcode_index+Fetchb());
|
||||
}
|
||||
}
|
||||
decode_end:
|
||||
LEAVECORE;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static Bits CPU_Core_Normal_Decode_Trap(void) {
|
||||
|
||||
Bits oldCycles = CPU_Cycles;
|
||||
CPU_Cycles = 1;
|
||||
Bits ret=CPU_Core_Normal_Decode();
|
||||
|
||||
Interrupt(1);
|
||||
|
||||
CPU_Cycles = oldCycles-1;
|
||||
cpudecoder = &CPU_Core_Normal_Decode;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPU_Core_Normal_Start(bool big) {
|
||||
|
||||
if (GETFLAG(TF)) cpudecoder=CPU_Core_Normal_Decode_Trap;
|
||||
else cpudecoder=CPU_Core_Normal_Decode;
|
||||
|
||||
if (big) {
|
||||
core.index_default=0x200;
|
||||
core.prefix_default=PREFIX_ADDR;
|
||||
} else {
|
||||
core.index_default=0;
|
||||
core.prefix_default=0;
|
||||
}
|
||||
}
|
||||
|
3
src/cpu/core_normal/Makefile.am
Normal file
3
src/cpu/core_normal/Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
noinst_HEADERS = helpers.h prefix_none.h prefix_66.h prefix_0f.h support.h table_ea.h \
|
||||
prefix_66_0f.h string.h
|
143
src/cpu/core_normal/helpers.h
Normal file
143
src/cpu/core_normal/helpers.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
|
||||
#define GetEAa \
|
||||
PhysPt eaa=EALookupTable[rm]();
|
||||
|
||||
#define GetRMEAa \
|
||||
GetRM; \
|
||||
GetEAa;
|
||||
|
||||
|
||||
#define RMEbGb(inst) \
|
||||
{ \
|
||||
GetRMrb; \
|
||||
if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \
|
||||
else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \
|
||||
}
|
||||
|
||||
#define RMGbEb(inst) \
|
||||
{ \
|
||||
GetRMrb; \
|
||||
if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \
|
||||
else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \
|
||||
}
|
||||
|
||||
#define RMEb(inst) \
|
||||
{ \
|
||||
if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \
|
||||
else {GetEAa;inst(eaa,LoadMb,SaveMb);} \
|
||||
}
|
||||
|
||||
#define RMEwGw(inst) \
|
||||
{ \
|
||||
GetRMrw; \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \
|
||||
}
|
||||
|
||||
#define RMEwGwOp3(inst,op3) \
|
||||
{ \
|
||||
GetRMrw; \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \
|
||||
}
|
||||
|
||||
#define RMGwEw(inst) \
|
||||
{ \
|
||||
GetRMrw; \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \
|
||||
}
|
||||
|
||||
#define RMGwEwOp3(inst,op3) \
|
||||
{ \
|
||||
GetRMrw; \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \
|
||||
}
|
||||
|
||||
#define RMEw(inst) \
|
||||
{ \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(eaa,LoadMw,SaveMw);} \
|
||||
}
|
||||
|
||||
#define RMEdGd(inst) \
|
||||
{ \
|
||||
GetRMrd; \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \
|
||||
}
|
||||
|
||||
#define RMEdGdOp3(inst,op3) \
|
||||
{ \
|
||||
GetRMrd; \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \
|
||||
}
|
||||
|
||||
|
||||
#define RMGdEd(inst) \
|
||||
{ \
|
||||
GetRMrd; \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \
|
||||
}
|
||||
|
||||
#define RMGdEdOp3(inst,op3) \
|
||||
{ \
|
||||
GetRMrd; \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define RMEw(inst) \
|
||||
{ \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(eaa,LoadMw,SaveMw);} \
|
||||
}
|
||||
|
||||
#define RMEd(inst) \
|
||||
{ \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(eaa,LoadMd,SaveMd);} \
|
||||
}
|
||||
|
||||
#define ALIb(inst) \
|
||||
{ inst(reg_al,Fetchb(),LoadRb,SaveRb)}
|
||||
|
||||
#define AXIw(inst) \
|
||||
{ inst(reg_ax,Fetchw(),LoadRw,SaveRw);}
|
||||
|
||||
#define EAXId(inst) \
|
||||
{ inst(reg_eax,Fetchd(),LoadRd,SaveRd);}
|
||||
|
||||
#define FPU_ESC(code) { \
|
||||
Bit8u rm=Fetchb(); \
|
||||
if (rm >= 0xc0) { \
|
||||
FPU_ESC ## code ## _Normal(rm); \
|
||||
} else { \
|
||||
GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \
|
||||
} \
|
||||
}
|
||||
|
449
src/cpu/core_normal/prefix_0f.h
Normal file
449
src/cpu/core_normal/prefix_0f.h
Normal file
|
@ -0,0 +1,449 @@
|
|||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
CASE_0F_W(0x00) /* GRP 6 Exxx */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* SLDT */
|
||||
case 0x01: /* STR */
|
||||
{
|
||||
Bitu saveval;
|
||||
if (!which) CPU_SLDT(saveval);
|
||||
else CPU_STR(saveval);
|
||||
if (rm >= 0xc0) {GetEArw;*earw=saveval;}
|
||||
else {GetEAa;SaveMw(eaa,saveval);}
|
||||
}
|
||||
break;
|
||||
case 0x02:case 0x03:case 0x04:case 0x05:
|
||||
{
|
||||
FillFlags();
|
||||
Bitu loadval;
|
||||
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
|
||||
else {GetEAa;loadval=LoadMw(eaa);}
|
||||
break;
|
||||
switch (which) {
|
||||
case 0x02:CPU_LLDT(loadval);break;
|
||||
case 0x03:CPU_LTR(loadval);break;
|
||||
case 0x04:CPU_VERR(loadval);break;
|
||||
case 0x05:CPU_VERW(loadval);break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_W(0x01) /* Group 7 Ew */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
if (rm < 0xc0) { //First ones all use EA
|
||||
GetEAa;Bitu limit,base;
|
||||
switch (which) {
|
||||
case 0x00: /* SGDT */
|
||||
CPU_SGDT(limit,base);
|
||||
SaveMw(eaa,limit);
|
||||
SaveMd(eaa+2,base);
|
||||
break;
|
||||
case 0x01: /* SIDT */
|
||||
CPU_SIDT(limit,base);
|
||||
SaveMw(eaa,limit);
|
||||
SaveMd(eaa+2,base);
|
||||
break;
|
||||
case 0x02: /* LGDT */
|
||||
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
|
||||
break;
|
||||
case 0x03: /* LIDT */
|
||||
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
|
||||
break;
|
||||
case 0x04: /* SMSW */
|
||||
CPU_SMSW(limit);
|
||||
SaveMw(eaa,limit);
|
||||
break;
|
||||
case 0x06: /* LMSW */
|
||||
limit=LoadMw(eaa);
|
||||
if (!CPU_LMSW(limit)) goto decode_end;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GetEArw;Bitu limit;
|
||||
switch (which) {
|
||||
case 0x04: /* SMSW */
|
||||
CPU_SMSW(limit);
|
||||
*earw=limit;
|
||||
break;
|
||||
case 0x06: /* LMSW */
|
||||
if (!CPU_LMSW(*earw)) goto decode_end;
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_W(0x02) /* LAR Gw,Ew */
|
||||
{
|
||||
FillFlags();
|
||||
GetRMrw;Bitu ar;
|
||||
if (rm >= 0xc0) {
|
||||
GetEArw;CPU_LAR(*earw,ar);
|
||||
} else {
|
||||
GetEAa;CPU_LAR(LoadMw(eaa),ar);
|
||||
}
|
||||
*rmrw=(Bit16u)ar;
|
||||
}
|
||||
break;
|
||||
CASE_0F_W(0x03) /* LSL Gw,Ew */
|
||||
{
|
||||
FillFlags();
|
||||
GetRMrw;Bitu limit;
|
||||
if (rm >= 0xc0) {
|
||||
GetEArw;CPU_LSL(*earw,limit);
|
||||
} else {
|
||||
GetEAa;CPU_LSL(LoadMw(eaa),limit);
|
||||
}
|
||||
*rmrw=(Bit16u)limit;
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x20) /* MOV Rd.CRx */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
*eard=CPU_GET_CRX(which);
|
||||
} else {
|
||||
GetEAa;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which);
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x22) /* MOV CRx,Rd */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
if (!CPU_SET_CRX(which,*eard)) goto decode_end;
|
||||
} else {
|
||||
GetEAa;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which);
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x23) /* MOV DRx,Rd */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
} else {
|
||||
GetEAa;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which);
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_W(0x80) /* JO */
|
||||
JumpSIw(get_OF());break;
|
||||
CASE_0F_W(0x81) /* JNO */
|
||||
JumpSIw(!get_OF());break;
|
||||
CASE_0F_W(0x82) /* JB */
|
||||
JumpSIw(get_CF());break;
|
||||
CASE_0F_W(0x83) /* JNB */
|
||||
JumpSIw(!get_CF());break;
|
||||
CASE_0F_W(0x84) /* JZ */
|
||||
JumpSIw(get_ZF());break;
|
||||
CASE_0F_W(0x85) /* JNZ */
|
||||
JumpSIw(!get_ZF());break;
|
||||
CASE_0F_W(0x86) /* JBE */
|
||||
JumpSIw(get_CF() || get_ZF());break;
|
||||
CASE_0F_W(0x87) /* JNBE */
|
||||
JumpSIw(!get_CF() && !get_ZF());break;
|
||||
CASE_0F_W(0x88) /* JS */
|
||||
JumpSIw(get_SF());break;
|
||||
CASE_0F_W(0x89) /* JNS */
|
||||
JumpSIw(!get_SF());break;
|
||||
CASE_0F_W(0x8a) /* JP */
|
||||
JumpSIw(get_PF());break;
|
||||
CASE_0F_W(0x8b) /* JNP */
|
||||
JumpSIw(!get_PF());break;
|
||||
CASE_0F_W(0x8c) /* JL */
|
||||
JumpSIw(get_SF() != get_OF());break;
|
||||
CASE_0F_W(0x8d) /* JNL */
|
||||
JumpSIw(get_SF() == get_OF());break;
|
||||
CASE_0F_W(0x8e) /* JLE */
|
||||
JumpSIw(get_ZF() || (get_SF() != get_OF()));break;
|
||||
CASE_0F_W(0x8f) /* JNLE */
|
||||
JumpSIw((get_SF() == get_OF()) && !get_ZF());break;
|
||||
CASE_0F_B(0x90) /* SETO */
|
||||
SETcc(get_OF());break;
|
||||
CASE_0F_B(0x91) /* SETNO */
|
||||
SETcc(!get_OF());break;
|
||||
CASE_0F_B(0x92) /* SETB */
|
||||
SETcc(get_CF());break;
|
||||
CASE_0F_B(0x93) /* SETNB */
|
||||
SETcc(!get_CF());break;
|
||||
CASE_0F_B(0x94) /* SETZ */
|
||||
SETcc(get_ZF());break;
|
||||
CASE_0F_B(0x95) /* SETNZ */
|
||||
SETcc(!get_ZF()); break;
|
||||
CASE_0F_B(0x96) /* SETBE */
|
||||
SETcc(get_CF() || get_ZF());break;
|
||||
CASE_0F_B(0x97) /* SETNBE */
|
||||
SETcc(!get_CF() && !get_ZF());break;
|
||||
CASE_0F_B(0x98) /* SETS */
|
||||
SETcc(get_SF());break;
|
||||
CASE_0F_B(0x99) /* SETNS */
|
||||
SETcc(!get_SF());break;
|
||||
CASE_0F_B(0x9a) /* SETP */
|
||||
SETcc(get_PF());break;
|
||||
CASE_0F_B(0x9b) /* SETNP */
|
||||
SETcc(!get_PF());break;
|
||||
CASE_0F_B(0x9c) /* SETL */
|
||||
SETcc(get_SF() != get_OF());break;
|
||||
CASE_0F_B(0x9d) /* SETNL */
|
||||
SETcc(get_SF() == get_OF());break;
|
||||
CASE_0F_B(0x9e) /* SETLE */
|
||||
SETcc(get_ZF() || (get_SF() != get_OF()));break;
|
||||
CASE_0F_B(0x9f) /* SETNLE */
|
||||
SETcc((get_SF() == get_OF()) && !get_ZF());break;
|
||||
|
||||
CASE_0F_W(0xa0) /* PUSH FS */
|
||||
Push_16(SegValue(fs));break;
|
||||
CASE_0F_W(0xa1) /* POP FS */
|
||||
CPU_SetSegGeneral(fs,Pop_16());break;
|
||||
CASE_0F_B(0xa2) /* CPUID */
|
||||
CPU_CPUID();break;
|
||||
CASE_0F_W(0xa3) /* BT Ew,Gw */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */
|
||||
RMEwGwOp3(DSHLW,Fetchb());
|
||||
break;
|
||||
CASE_0F_W(0xa5) /* SHLD Ew,Gw,CL */
|
||||
RMEwGwOp3(DSHLW,reg_cl);
|
||||
break;
|
||||
CASE_0F_W(0xa8) /* PUSH GS */
|
||||
Push_16(SegValue(gs));break;
|
||||
CASE_0F_W(0xa9) /* POP GS */
|
||||
CPU_SetSegGeneral(gs,Pop_16());break;
|
||||
CASE_0F_W(0xab) /* BTS Ew,Gw */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
*earw|=mask;
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMw(eaa,old | mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */
|
||||
RMEwGwOp3(DSHRW,Fetchb());
|
||||
break;
|
||||
CASE_0F_W(0xad) /* SHRD Ew,Gw,CL */
|
||||
RMEwGwOp3(DSHRW,reg_cl);
|
||||
break;
|
||||
CASE_0F_W(0xaf) /* IMUL Gw,Ew */
|
||||
RMGwEwOp3(DIMULW,*rmrw);
|
||||
break;
|
||||
CASE_0F_W(0xb2) /* LSS Ew */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+2));
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb3) /* BTR Ew,Gw */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
*earw&= ~mask;
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMw(eaa,old & ~mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb4) /* LFS Ew */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+2));
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb5) /* LGS Ew */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+2));
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb6) /* MOVZX Gw,Eb */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
|
||||
else {GetEAa;*rmrw=LoadMb(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb7) /* MOVZX Gw,Ew */
|
||||
CASE_0F_W(0xbf) /* MOVSX Gw,Ew */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;}
|
||||
else {GetEAa;*rmrw=LoadMw(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xba) /* GRP8 Ew,Ib */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
Bit16u mask=1 << (Fetchb() & 15);
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
case 0x28: /* BTS */
|
||||
*earw|=mask;
|
||||
break;
|
||||
case 0x30: /* BTR */
|
||||
*earw&= ~mask;
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
*earw^=mask;
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
Bit16u mask=1 << (Fetchb() & 15);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
case 0x28: /* BTS */
|
||||
SaveMw(eaa,old|mask);
|
||||
break;
|
||||
case 0x30: /* BTR */
|
||||
SaveMw(eaa,old & ~mask);
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
SaveMw(eaa,old ^ mask);
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
|
||||
}
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xbb) /* BTC Ew,Gw */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
*earw^=mask;
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMw(eaa,old ^ mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xbc) /* BSF Gw,Ew */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit16u result,value;
|
||||
if (rm >= 0xc0) { GetEArw; value=*earw; }
|
||||
else { GetEAa; value=LoadMw(eaa); }
|
||||
if (value==0) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 0;
|
||||
while ((value & 0x01)==0) { result++; value>>=1; }
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrw = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xbd) /* BSR Gw,Ew */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit16u result,value;
|
||||
if (rm >= 0xc0) { GetEArw; value=*earw; }
|
||||
else { GetEAa; value=LoadMw(eaa); }
|
||||
if (value==0) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 15; // Operandsize-1
|
||||
while ((value & 0x8000)==0) { result--; value<<=1; }
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrw = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xbe) /* MOVSX Gw,Eb */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;}
|
||||
else {GetEAa;*rmrw=LoadMbs(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_B(0xc8) /* BSWAP EAX */
|
||||
BSWAP(reg_eax);break;
|
||||
CASE_0F_B(0xc9) /* BSWAP ECX */
|
||||
BSWAP(reg_ecx);break;
|
||||
CASE_0F_B(0xca) /* BSWAP EDX */
|
||||
BSWAP(reg_edx);break;
|
||||
CASE_0F_B(0xcb) /* BSWAP EBX */
|
||||
BSWAP(reg_ebx);break;
|
||||
CASE_0F_B(0xcc) /* BSWAP ESP */
|
||||
BSWAP(reg_esp);break;
|
||||
CASE_0F_B(0xcd) /* BSWAP EBP */
|
||||
BSWAP(reg_ebp);break;
|
||||
CASE_0F_B(0xce) /* BSWAP ESI */
|
||||
BSWAP(reg_esi);break;
|
||||
CASE_0F_B(0xcf) /* BSWAP EDI */
|
||||
BSWAP(reg_edi);break;
|
||||
|
611
src/cpu/core_normal/prefix_66.h
Normal file
611
src/cpu/core_normal/prefix_66.h
Normal file
|
@ -0,0 +1,611 @@
|
|||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
CASE_D(0x01) /* ADD Ed,Gd */
|
||||
RMEdGd(ADDD);break;
|
||||
CASE_D(0x03) /* ADD Gd,Ed */
|
||||
RMGdEd(ADDD);break;
|
||||
CASE_D(0x05) /* ADD EAX,Id */
|
||||
EAXId(ADDD);break;
|
||||
CASE_D(0x06) /* PUSH ES */
|
||||
Push_32(SegValue(es));break;
|
||||
CASE_D(0x07) /* POP ES */
|
||||
CPU_SetSegGeneral(es,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x09) /* OR Ed,Gd */
|
||||
RMEdGd(ORD);break;
|
||||
CASE_D(0x0b) /* OR Gd,Ed */
|
||||
RMGdEd(ORD);break;
|
||||
CASE_D(0x0d) /* OR EAX,Id */
|
||||
EAXId(ORD);break;
|
||||
CASE_D(0x0e) /* PUSH CS */
|
||||
Push_32(SegValue(cs));break;
|
||||
CASE_D(0x11) /* ADC Ed,Gd */
|
||||
RMEdGd(ADCD);break;
|
||||
CASE_D(0x13) /* ADC Gd,Ed */
|
||||
RMGdEd(ADCD);break;
|
||||
CASE_D(0x15) /* ADC EAX,Id */
|
||||
EAXId(ADCD);break;
|
||||
CASE_D(0x16) /* PUSH SS */
|
||||
Push_32(SegValue(ss));break;
|
||||
CASE_D(0x17) /* POP SS */
|
||||
CPU_SetSegGeneral(ss,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x19) /* SBB Ed,Gd */
|
||||
RMEdGd(SBBD);break;
|
||||
CASE_D(0x1b) /* SBB Gd,Ed */
|
||||
RMGdEd(SBBD);break;
|
||||
CASE_D(0x1d) /* SBB EAX,Id */
|
||||
EAXId(SBBD);break;
|
||||
CASE_D(0x1e) /* PUSH DS */
|
||||
Push_32(SegValue(ds));break;
|
||||
CASE_D(0x1f) /* POP DS */
|
||||
CPU_SetSegGeneral(ds,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x21) /* AND Ed,Gd */
|
||||
RMEdGd(ANDD);break;
|
||||
CASE_D(0x23) /* AND Gd,Ed */
|
||||
RMGdEd(ANDD);break;
|
||||
CASE_D(0x25) /* AND EAX,Id */
|
||||
EAXId(ANDD);break;
|
||||
CASE_D(0x29) /* SUB Ed,Gd */
|
||||
RMEdGd(SUBD);break;
|
||||
CASE_D(0x2b) /* SUB Gd,Ed */
|
||||
RMGdEd(SUBD);break;
|
||||
CASE_D(0x2d) /* SUB EAX,Id */
|
||||
EAXId(SUBD);break;
|
||||
CASE_D(0x31) /* XOR Ed,Gd */
|
||||
RMEdGd(XORD);break;
|
||||
CASE_D(0x33) /* XOR Gd,Ed */
|
||||
RMGdEd(XORD);break;
|
||||
CASE_D(0x35) /* XOR EAX,Id */
|
||||
EAXId(XORD);break;
|
||||
CASE_D(0x39) /* CMP Ed,Gd */
|
||||
RMEdGd(CMPD);break;
|
||||
CASE_D(0x3b) /* CMP Gd,Ed */
|
||||
RMGdEd(CMPD);break;
|
||||
CASE_D(0x3d) /* CMP EAX,Id */
|
||||
EAXId(CMPD);break;
|
||||
CASE_D(0x40) /* INC EAX */
|
||||
INCD(reg_eax,LoadRd,SaveRd);break;
|
||||
CASE_D(0x41) /* INC ECX */
|
||||
INCD(reg_ecx,LoadRd,SaveRd);break;
|
||||
CASE_D(0x42) /* INC EDX */
|
||||
INCD(reg_edx,LoadRd,SaveRd);break;
|
||||
CASE_D(0x43) /* INC EBX */
|
||||
INCD(reg_ebx,LoadRd,SaveRd);break;
|
||||
CASE_D(0x44) /* INC ESP */
|
||||
INCD(reg_esp,LoadRd,SaveRd);break;
|
||||
CASE_D(0x45) /* INC EBP */
|
||||
INCD(reg_ebp,LoadRd,SaveRd);break;
|
||||
CASE_D(0x46) /* INC ESI */
|
||||
INCD(reg_esi,LoadRd,SaveRd);break;
|
||||
CASE_D(0x47) /* INC EDI */
|
||||
INCD(reg_edi,LoadRd,SaveRd);break;
|
||||
CASE_D(0x48) /* DEC EAX */
|
||||
DECD(reg_eax,LoadRd,SaveRd);break;
|
||||
CASE_D(0x49) /* DEC ECX */
|
||||
DECD(reg_ecx,LoadRd,SaveRd);break;
|
||||
CASE_D(0x4a) /* DEC EDX */
|
||||
DECD(reg_edx,LoadRd,SaveRd);break;
|
||||
CASE_D(0x4b) /* DEC EBX */
|
||||
DECD(reg_ebx,LoadRd,SaveRd);break;
|
||||
CASE_D(0x4c) /* DEC ESP */
|
||||
DECD(reg_esp,LoadRd,SaveRd);break;
|
||||
CASE_D(0x4d) /* DEC EBP */
|
||||
DECD(reg_ebp,LoadRd,SaveRd);break;
|
||||
CASE_D(0x4e) /* DEC ESI */
|
||||
DECD(reg_esi,LoadRd,SaveRd);break;
|
||||
CASE_D(0x4f) /* DEC EDI */
|
||||
DECD(reg_edi,LoadRd,SaveRd);break;
|
||||
CASE_D(0x50) /* PUSH EAX */
|
||||
Push_32(reg_eax);break;
|
||||
CASE_D(0x51) /* PUSH ECX */
|
||||
Push_32(reg_ecx);break;
|
||||
CASE_D(0x52) /* PUSH EDX */
|
||||
Push_32(reg_edx);break;
|
||||
CASE_D(0x53) /* PUSH EBX */
|
||||
Push_32(reg_ebx);break;
|
||||
CASE_D(0x54) /* PUSH ESP */
|
||||
Push_32(reg_esp);break;
|
||||
CASE_D(0x55) /* PUSH EBP */
|
||||
Push_32(reg_ebp);break;
|
||||
CASE_D(0x56) /* PUSH ESI */
|
||||
Push_32(reg_esi);break;
|
||||
CASE_D(0x57) /* PUSH EDI */
|
||||
Push_32(reg_edi);break;
|
||||
CASE_D(0x58) /* POP EAX */
|
||||
reg_eax=Pop_32();break;
|
||||
CASE_D(0x59) /* POP ECX */
|
||||
reg_ecx=Pop_32();break;
|
||||
CASE_D(0x5a) /* POP EDX */
|
||||
reg_edx=Pop_32();break;
|
||||
CASE_D(0x5b) /* POP EBX */
|
||||
reg_ebx=Pop_32();break;
|
||||
CASE_D(0x5c) /* POP ESP */
|
||||
reg_esp=Pop_32();break;
|
||||
CASE_D(0x5d) /* POP EBP */
|
||||
reg_ebp=Pop_32();break;
|
||||
CASE_D(0x5e) /* POP ESI */
|
||||
reg_esi=Pop_32();break;
|
||||
CASE_D(0x5f) /* POP EDI */
|
||||
reg_edi=Pop_32();break;
|
||||
CASE_D(0x60) /* PUSHAD */
|
||||
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
|
||||
Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
|
||||
break;
|
||||
CASE_D(0x61) /* POPAD */
|
||||
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
|
||||
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
|
||||
break;
|
||||
CASE_D(0x68) /* PUSH Id */
|
||||
Push_32(Fetchd());break;
|
||||
CASE_D(0x69) /* IMUL Gd,Ed,Id */
|
||||
RMGdEdOp3(DIMULD,Fetchds());
|
||||
break;
|
||||
CASE_D(0x6a) /* PUSH Ib */
|
||||
Push_32(Fetchbs());break;
|
||||
CASE_D(0x6b) /* IMUL Gd,Ed,Ib */
|
||||
RMGdEdOp3(DIMULD,Fetchbs());
|
||||
break;
|
||||
CASE_D(0x81) /* Grpl Ed,Id */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
if (rm >= 0xc0) {
|
||||
GetEArd;Bit32u id=Fetchd();
|
||||
switch (which) {
|
||||
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x01: ORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x06:XORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break;
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit32u id=Fetchd();
|
||||
switch (which) {
|
||||
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x01: ORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x06:XORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_D(0x83) /* Grpl Ed,Ix */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
if (rm >= 0xc0) {
|
||||
GetEArd;Bit32u id=(Bit32s)Fetchbs();
|
||||
switch (which) {
|
||||
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x01: ORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x06:XORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break;
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit32u id=(Bit32s)Fetchbs();
|
||||
switch (which) {
|
||||
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x01: ORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x06:XORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_D(0x85) /* TEST Ed,Gd */
|
||||
RMEdGd(TESTD);break;
|
||||
CASE_D(0x87) /* XCHG Ed,Gd */
|
||||
{
|
||||
GetRMrd;Bit32u oldrmrd=*rmrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;}
|
||||
else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);}
|
||||
break;
|
||||
}
|
||||
CASE_D(0x89) /* MOV Ed,Gd */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
|
||||
else {GetEAa;SaveMd(eaa,*rmrd);}
|
||||
break;
|
||||
}
|
||||
CASE_D(0x8b) /* MOV Gd,Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
|
||||
else {GetEAa;*rmrd=LoadMd(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_D(0x8c) /* Mov Ew,Sw */
|
||||
{
|
||||
GetRM;Bit16u val;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* MOV Ew,ES */
|
||||
val=SegValue(es);break;
|
||||
case 0x01: /* MOV Ew,CS */
|
||||
val=SegValue(cs);break;
|
||||
case 0x02: /* MOV Ew,SS */
|
||||
val=SegValue(ss);break;
|
||||
case 0x03: /* MOV Ew,DS */
|
||||
val=SegValue(ds);break;
|
||||
case 0x04: /* MOV Ew,FS */
|
||||
val=SegValue(fs);break;
|
||||
case 0x05: /* MOV Ew,GS */
|
||||
val=SegValue(gs);break;
|
||||
default:
|
||||
val=0;
|
||||
E_Exit("CPU:8c:Illegal RM Byte");
|
||||
}
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=val;}
|
||||
else {GetEAa;SaveMd(eaa,val);}
|
||||
break;
|
||||
}
|
||||
CASE_D(0x8d) /* LEA Gd */
|
||||
{
|
||||
//Little hack to always use segprefixed version
|
||||
core.seg_prefix_base=0;
|
||||
GetRMrd;
|
||||
if (TEST_PREFIX_ADDR) {
|
||||
*rmrd=(Bit32u)(*GetEA_SEG_ADDR[rm])();
|
||||
} else {
|
||||
*rmrd=(Bit32u)(*GetEA_SEG[rm])();
|
||||
}
|
||||
break;
|
||||
}
|
||||
CASE_D(0x8f) /* POP Ed */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
|
||||
else {GetEAa;SaveMd(eaa,Pop_32());}
|
||||
break;
|
||||
}
|
||||
CASE_D(0x91) /* XCHG ECX,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;}
|
||||
CASE_D(0x92) /* XCHG EDX,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;}
|
||||
break;
|
||||
CASE_D(0x93) /* XCHG EBX,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;}
|
||||
break;
|
||||
CASE_D(0x94) /* XCHG ESP,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;}
|
||||
break;
|
||||
CASE_D(0x95) /* XCHG EBP,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;}
|
||||
break;
|
||||
CASE_D(0x96) /* XCHG ESI,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;}
|
||||
break;
|
||||
CASE_D(0x97) /* XCHG EDI,EAX */
|
||||
{ Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;}
|
||||
break;
|
||||
CASE_D(0x98) /* CWDE */
|
||||
reg_eax=(Bit16s)reg_ax;break;
|
||||
CASE_D(0x99) /* CDQ */
|
||||
if (reg_eax & 0x80000000) reg_edx=0xffffffff;
|
||||
else reg_edx=0;
|
||||
break;
|
||||
CASE_D(0x9c) /* PUSHFD */
|
||||
FillFlags();
|
||||
Push_32(flags.word);
|
||||
break;
|
||||
CASE_D(0x9d) /* POPFD */
|
||||
SETFLAGSd(Pop_32())
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Decode_Trap;
|
||||
goto decode_end;
|
||||
}
|
||||
#endif
|
||||
#ifdef CPU_PIC_CHECK
|
||||
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
|
||||
#endif
|
||||
|
||||
break;
|
||||
CASE_D(0xa1) /* MOV EAX,Od */
|
||||
{
|
||||
GetEADirect;
|
||||
reg_eax=LoadMd(eaa);
|
||||
}
|
||||
break;
|
||||
CASE_D(0xa3) /* MOV Od,EAX */
|
||||
{
|
||||
GetEADirect;
|
||||
SaveMd(eaa,reg_eax);
|
||||
}
|
||||
break;
|
||||
CASE_D(0xa5) /* MOVSD */
|
||||
DoString(R_MOVSD);break;
|
||||
CASE_D(0xa7) /* CMPSD */
|
||||
DoString(R_CMPSD);break;
|
||||
CASE_D(0xa9) /* TEST EAX,Id */
|
||||
EAXId(TESTD);break;
|
||||
CASE_D(0xab) /* STOSD */
|
||||
DoString(R_STOSD);break;
|
||||
CASE_D(0xad) /* LODSD */
|
||||
DoString(R_LODSD);break;
|
||||
CASE_D(0xaf) /* SCASD */
|
||||
DoString(R_SCASD);break;
|
||||
CASE_D(0xb8) /* MOV EAX,Id */
|
||||
reg_eax=Fetchd();break;
|
||||
CASE_D(0xb9) /* MOV ECX,Id */
|
||||
reg_ecx=Fetchd();break;
|
||||
CASE_D(0xba) /* MOV EDX,Iw */
|
||||
reg_edx=Fetchd();break;
|
||||
CASE_D(0xbb) /* MOV EBX,Id */
|
||||
reg_ebx=Fetchd();break;
|
||||
CASE_D(0xbc) /* MOV ESP,Id */
|
||||
reg_esp=Fetchd();break;
|
||||
CASE_D(0xbd) /* MOV EBP.Id */
|
||||
reg_ebp=Fetchd();break;
|
||||
CASE_D(0xbe) /* MOV ESI,Id */
|
||||
reg_esi=Fetchd();break;
|
||||
CASE_D(0xbf) /* MOV EDI,Id */
|
||||
reg_edi=Fetchd();break;
|
||||
CASE_D(0xc1) /* GRP2 Ed,Ib */
|
||||
GRP2D(Fetchb());break;
|
||||
CASE_D(0xc2) /* RETN Iw */
|
||||
{
|
||||
Bit16u addsp=Fetchw();
|
||||
SETIP(Pop_32());reg_esp+=addsp;
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc3) /* RETN */
|
||||
SETIP(Pop_32());
|
||||
break;
|
||||
CASE_D(0xc4) /* LES */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+4));
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc5) /* LDS */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+4));
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc7) /* MOV Ed,Id */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0) {GetEArd;*eard=Fetchd();}
|
||||
else {GetEAa;SaveMd(eaa,Fetchd());}
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc8) /* ENTER Iw,Ib */
|
||||
{
|
||||
Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f;
|
||||
Bitu frame_ptr=reg_esp-4;
|
||||
if (cpu.stack.big) {
|
||||
reg_esp-=4;
|
||||
mem_writed(SegBase(ss)+reg_esp,reg_ebp);
|
||||
for (Bitu i=1;i<level;i++) {
|
||||
reg_ebp-=4;reg_esp-=4;
|
||||
mem_writed(SegBase(ss)+reg_esp,mem_readd(SegBase(ss)+reg_ebp));
|
||||
}
|
||||
if (level) {
|
||||
reg_esp-=4;
|
||||
mem_writed(SegBase(ss)+reg_esp,(Bit32u)frame_ptr);
|
||||
}
|
||||
reg_esp-=bytes;
|
||||
} else {
|
||||
reg_sp-=4;
|
||||
mem_writed(SegBase(ss)+reg_sp,reg_ebp);
|
||||
for (Bitu i=1;i<level;i++) {
|
||||
reg_bp-=4;reg_sp-=4;
|
||||
mem_writed(SegBase(ss)+reg_sp,mem_readd(SegBase(ss)+reg_bp));
|
||||
}
|
||||
if (level) {
|
||||
reg_sp-=4;
|
||||
mem_writed(SegBase(ss)+reg_sp,(Bit32u)frame_ptr);
|
||||
}
|
||||
reg_sp-=bytes;
|
||||
}
|
||||
reg_ebp=frame_ptr;
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc9) /* LEAVE */
|
||||
reg_esp&=~cpu.stack.mask;
|
||||
reg_esp|=(reg_ebp&cpu.stack.mask);
|
||||
reg_ebp=Pop_32();
|
||||
break;
|
||||
CASE_D(0xca) /* RETF Iw */
|
||||
{
|
||||
if (CPU_RET(true,Fetchw())) {
|
||||
LOADIP;
|
||||
} else {
|
||||
FillFlags();return CBRET_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CASE_D(0xcb) /* RETF */
|
||||
{
|
||||
if (CPU_RET(true,0)) {
|
||||
LOADIP;
|
||||
} else {
|
||||
FillFlags();return CBRET_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CASE_D(0xcf) /* IRET */
|
||||
{
|
||||
if (CPU_IRET(true)) {
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Decode_Trap;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
#ifdef CPU_PIC_CHECK
|
||||
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
||||
#endif
|
||||
//TODO TF check
|
||||
goto decode_start;
|
||||
} else return CBRET_NONE;
|
||||
break;
|
||||
}
|
||||
CASE_D(0xd1) /* GRP2 Ed,1 */
|
||||
GRP2D(1);break;
|
||||
CASE_D(0xd3) /* GRP2 Ed,CL */
|
||||
GRP2D(reg_cl);break;
|
||||
CASE_D(0xe8) /* CALL Jd */
|
||||
{
|
||||
Bit32s newip=Fetchds();
|
||||
Push_32((Bit32u)GETIP);
|
||||
ADDIPd(newip);
|
||||
break;
|
||||
}
|
||||
CASE_D(0xe9) /* JMP Jd */
|
||||
ADDIPd(Fetchds());
|
||||
break;
|
||||
CASE_D(0xea) /* JMP Ad */
|
||||
{
|
||||
Bit32u newip=Fetchd();
|
||||
Bit16u newcs=Fetchw();
|
||||
SAVEIP;
|
||||
if (CPU_JMP(true,newcs,newip)) {
|
||||
LOADIP;
|
||||
} else {
|
||||
FillFlags();return CBRET_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CASE_D(0xed) /* IN EAX,DX */
|
||||
reg_eax=IO_Read(reg_dx) |
|
||||
(IO_Read(reg_dx+1) << 8) |
|
||||
(IO_Read(reg_dx+2) << 16) |
|
||||
(IO_Read(reg_dx+3) << 24);
|
||||
break;
|
||||
CASE_D(0xef) /* OUT DX,EAX */
|
||||
IO_Write(reg_dx,(Bit8u)(reg_eax>>0));
|
||||
IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8));
|
||||
IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16));
|
||||
IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24));
|
||||
break;
|
||||
CASE_D(0xf7) /* GRP3 Ed(,Id) */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* TEST Ed,Id */
|
||||
case 0x01: /* TEST Ed,Id Undocumented*/
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
|
||||
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
|
||||
break;
|
||||
}
|
||||
case 0x02: /* NOT Ed */
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
|
||||
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
|
||||
break;
|
||||
}
|
||||
case 0x03: /* NEG Ed */
|
||||
{
|
||||
flags.type=t_NEGd;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
|
||||
*eard=flags.result.d;
|
||||
} else {
|
||||
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
|
||||
SaveMd(eaa,flags.result.d);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x04: /* MUL EAX,Ed */
|
||||
RMEd(MULD);
|
||||
break;
|
||||
case 0x05: /* IMUL EAX,Ed */
|
||||
RMEd(IMULD);
|
||||
break;
|
||||
case 0x06: /* DIV Ed */
|
||||
RMEd(DIVD);
|
||||
break;
|
||||
case 0x07: /* IDIV Ed */
|
||||
RMEd(IDIVD);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CASE_D(0xff) /* GRP 5 Ed */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* INC Ed */
|
||||
RMEd(INCD);
|
||||
break;
|
||||
case 0x01: /* DEC Ed */
|
||||
RMEd(DECD);
|
||||
break;
|
||||
case 0x02: /* CALL NEAR Ed */
|
||||
if (rm >= 0xc0 ) {GetEArd;Push_32(GETIP);SETIP(*eard);}
|
||||
else {GetEAa;Push_32(GETIP);SETIP(LoadMd(eaa));}
|
||||
break;
|
||||
case 0x03: /* CALL FAR Ed */
|
||||
{
|
||||
GetEAa;
|
||||
Bit32u newip=LoadMd(eaa);
|
||||
Bit16u newcs=LoadMw(eaa+4);
|
||||
SAVEIP;
|
||||
if (CPU_CALL(true,newcs,newip)) {
|
||||
LOADIP;
|
||||
} else {
|
||||
FillFlags();return CBRET_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x04: /* JMP NEAR Ed */
|
||||
if (rm >= 0xc0 ) {GetEArd;SETIP(*eard);}
|
||||
else {GetEAa;SETIP(LoadMd(eaa));}
|
||||
break;
|
||||
case 0x05: /* JMP FAR Ed */
|
||||
{
|
||||
GetEAa;
|
||||
Bit32u newip=LoadMd(eaa);
|
||||
Bit16u newcs=LoadMw(eaa+4);
|
||||
SAVEIP;
|
||||
if (CPU_JMP(true,newcs,newip)) {
|
||||
LOADIP;
|
||||
} else {
|
||||
FillFlags();return CBRET_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Push Ed */
|
||||
if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
|
||||
else {GetEAa;Push_32(LoadMd(eaa));}
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:66:GRP5:Illegal call %2X",which);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
370
src/cpu/core_normal/prefix_66_0f.h
Normal file
370
src/cpu/core_normal/prefix_66_0f.h
Normal file
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
CASE_0F_D(0x00) /* GRP 6 Exxx */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* SLDT */
|
||||
case 0x01: /* STR */
|
||||
{
|
||||
Bitu saveval;
|
||||
if (!which) CPU_SLDT(saveval);
|
||||
else CPU_STR(saveval);
|
||||
if (rm >= 0xc0) {GetEArd;*eard=saveval;}
|
||||
else {GetEAa;SaveMd(eaa,saveval);}
|
||||
}
|
||||
break;
|
||||
case 0x02:case 0x03:case 0x04:case 0x05:
|
||||
{
|
||||
/* Just use 16-bit loads since were only using selectors */
|
||||
FillFlags();
|
||||
Bitu loadval;
|
||||
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
|
||||
else {GetEAa;loadval=LoadMw(eaa);}
|
||||
break;
|
||||
switch (which) {
|
||||
case 0x02:CPU_LLDT(loadval);break;
|
||||
case 0x03:CPU_LTR(loadval);break;
|
||||
case 0x04:CPU_VERR(loadval);break;
|
||||
case 0x05:CPU_VERW(loadval);break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_D(0x01) /* Group 7 Ed */
|
||||
{
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
if (rm < 0xc0) { //First ones all use EA
|
||||
GetEAa;Bitu limit,base;
|
||||
switch (which) {
|
||||
case 0x00: /* SGDT */
|
||||
CPU_SGDT(limit,base);
|
||||
SaveMw(eaa,limit);
|
||||
SaveMd(eaa+2,base);
|
||||
break;
|
||||
case 0x01: /* SIDT */
|
||||
CPU_SIDT(limit,base);
|
||||
SaveMw(eaa,limit);
|
||||
SaveMd(eaa+2,base);
|
||||
break;
|
||||
case 0x02: /* LGDT */
|
||||
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2));
|
||||
break;
|
||||
case 0x03: /* LIDT */
|
||||
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2));
|
||||
break;
|
||||
case 0x04: /* SMSW */
|
||||
CPU_SMSW(limit);
|
||||
SaveMw(eaa,limit);
|
||||
break;
|
||||
case 0x06: /* LMSW */
|
||||
limit=LoadMw(eaa);
|
||||
if (!CPU_LMSW(limit)) goto decode_end;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GetEArw;Bitu limit;
|
||||
switch (which) {
|
||||
case 0x04: /* SMSW */
|
||||
CPU_SMSW(limit);
|
||||
*earw=limit;
|
||||
break;
|
||||
case 0x06: /* LMSW */
|
||||
if (!CPU_LMSW(*earw)) goto decode_end;
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
CASE_0F_D(0x02) /* LAR Gd,Ed */
|
||||
{
|
||||
FillFlags();
|
||||
GetRMrd;Bitu ar;
|
||||
if (rm >= 0xc0) {
|
||||
GetEArw;CPU_LAR(*earw,ar);
|
||||
} else {
|
||||
GetEAa;CPU_LAR(LoadMw(eaa),ar);
|
||||
}
|
||||
*rmrd=(Bit32u)ar;
|
||||
}
|
||||
break;
|
||||
CASE_0F_D(0x03) /* LSL Gd,Ew */
|
||||
{
|
||||
FillFlags();
|
||||
GetRMrd;Bitu limit;
|
||||
/* Just load 16-bit values for selectors */
|
||||
if (rm >= 0xc0) {
|
||||
GetEArw;CPU_LSL(*earw,limit);
|
||||
} else {
|
||||
GetEAa;CPU_LSL(LoadMw(eaa),limit);
|
||||
}
|
||||
*rmrd=(Bit16u)limit;
|
||||
}
|
||||
break;
|
||||
CASE_0F_D(0x80) /* JO */
|
||||
JumpSId(get_OF());break;
|
||||
CASE_0F_D(0x81) /* JNO */
|
||||
JumpSId(!get_OF());break;
|
||||
CASE_0F_D(0x82) /* JB */
|
||||
JumpSId(get_CF());break;
|
||||
CASE_0F_D(0x83) /* JNB */
|
||||
JumpSId(!get_CF());break;
|
||||
CASE_0F_D(0x84) /* JZ */
|
||||
JumpSId(get_ZF());break;
|
||||
CASE_0F_D(0x85) /* JNZ */
|
||||
JumpSId(!get_ZF());break;
|
||||
CASE_0F_D(0x86) /* JBE */
|
||||
JumpSId(get_CF() || get_ZF());break;
|
||||
CASE_0F_D(0x87) /* JNBE */
|
||||
JumpSId(!get_CF() && !get_ZF());break;
|
||||
CASE_0F_D(0x88) /* JS */
|
||||
JumpSId(get_SF());break;
|
||||
CASE_0F_D(0x89) /* JNS */
|
||||
JumpSId(!get_SF());break;
|
||||
CASE_0F_D(0x8a) /* JP */
|
||||
JumpSId(get_PF());break;
|
||||
CASE_0F_D(0x8b) /* JNP */
|
||||
JumpSId(!get_PF());break;
|
||||
CASE_0F_D(0x8c) /* JL */
|
||||
JumpSId(get_SF() != get_OF());break;
|
||||
CASE_0F_D(0x8d) /* JNL */
|
||||
JumpSId(get_SF() == get_OF());break;
|
||||
CASE_0F_D(0x8e) /* JLE */
|
||||
JumpSId(get_ZF() || (get_SF() != get_OF()));break;
|
||||
CASE_0F_D(0x8f) /* JNLE */
|
||||
JumpSId((get_SF() == get_OF()) && !get_ZF());break;
|
||||
|
||||
CASE_0F_D(0xa0) /* PUSH FS */
|
||||
Push_32(SegValue(fs));break;
|
||||
CASE_0F_D(0xa1) /* POP FS */
|
||||
CPU_SetSegGeneral(fs,(Bit16u)Pop_32());break;
|
||||
|
||||
CASE_0F_D(0xa3) /* BT Ed,Gd */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit32u mask=1 << (*rmrd & 31);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
SETFLAGBIT(CF,(*eard & mask));
|
||||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;DSHLD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
|
||||
else {GetEAa;DSHLD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
|
||||
break;
|
||||
}
|
||||
|
||||
CASE_0F_D(0xa8) /* PUSH GS */
|
||||
Push_32(SegValue(gs));break;
|
||||
CASE_0F_D(0xa9) /* POP GS */
|
||||
CPU_SetSegGeneral(gs,(Bit16u)Pop_32());break;
|
||||
CASE_0F_D(0xab) /* BTS Ed,Gd */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit32u mask=1 << (*rmrd & 31);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
SETFLAGBIT(CF,(*eard & mask));
|
||||
*eard|=mask;
|
||||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMd(eaa,old | mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
|
||||
CASE_0F_D(0xac) /* SHRD Ed,Gd,Ib */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
|
||||
else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xad) /* SHRD Ed,Gd,Cl */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);}
|
||||
else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb4) /* LFS Ed */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+4));
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb5) /* LGS Ed */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+4));
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb6) /* MOVZX Gd,Eb */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
|
||||
else {GetEAa;*rmrd=LoadMb(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xaf) /* IMUL Gd,Ed */
|
||||
{
|
||||
RMGdEdOp3(DIMULD,*rmrd);
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb2) /* LSS Ed */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4));
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb7) /* MOVXZ Gd,Ew */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;}
|
||||
else {GetEAa;*rmrd=LoadMw(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xba) /* GRP8 Ed,Ib */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
Bit32u mask=1 << (Fetchb() & 31);
|
||||
SETFLAGBIT(CF,(*eard & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
case 0x28: /* BTS */
|
||||
*eard|=mask;
|
||||
break;
|
||||
case 0x30: /* BTR */
|
||||
*eard&=~mask;
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
if (GETFLAG(CF)) *eard&=~mask;
|
||||
else *eard|=mask;
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
Bit32u mask=1 << (Fetchb() & 31);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
case 0x28: /* BTS */
|
||||
SaveMd(eaa,old|mask);
|
||||
break;
|
||||
case 0x30: /* BTR */
|
||||
SaveMd(eaa,old & ~mask);
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
if (GETFLAG(CF)) old&=~mask;
|
||||
else old|=mask;
|
||||
SaveMd(eaa,old);
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
|
||||
}
|
||||
}
|
||||
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||
flags.type=t_CF;
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xbb) /* BTC Ed,Gd */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit32u mask=1 << (*rmrd & 31);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
SETFLAGBIT(CF,(*eard & mask));
|
||||
*eard^=mask;
|
||||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMd(eaa,old ^ mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xbc) /* BSF Gd,Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit32u result,value;
|
||||
if (rm >= 0xc0) { GetEArd; value=*eard; }
|
||||
else { GetEAa; value=LoadMd(eaa); }
|
||||
if (value==0) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 0;
|
||||
while ((value & 0x01)==0) { result++; value>>=1; }
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrd = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xbd) /* BSR Gd,Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit32u result,value;
|
||||
if (rm >= 0xc0) { GetEArd; value=*eard; }
|
||||
else { GetEAa; value=LoadMd(eaa); }
|
||||
if (value==0) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 35; // Operandsize-1
|
||||
while ((value & 0x80000000)==0) { result--; value<<=1; }
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrd = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xbe) /* MOVSX Gd,Eb */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;}
|
||||
else {GetEAa;*rmrd=LoadMbs(eaa);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xbf) /* MOVSX Gd,Ew */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;}
|
||||
else {GetEAa;*rmrd=LoadMws(eaa);}
|
||||
break;
|
||||
}
|
1171
src/cpu/core_normal/prefix_none.h
Normal file
1171
src/cpu/core_normal/prefix_none.h
Normal file
File diff suppressed because it is too large
Load diff
243
src/cpu/core_normal/string.h
Normal file
243
src/cpu/core_normal/string.h
Normal file
|
@ -0,0 +1,243 @@
|
|||
enum STRING_OP {
|
||||
R_OUTSB,R_OUTSW,R_OUTSD,
|
||||
R_INSB,R_INSW,R_INSD,
|
||||
R_MOVSB,R_MOVSW,R_MOVSD,
|
||||
R_LODSB,R_LODSW,R_LODSD,
|
||||
R_STOSB,R_STOSW,R_STOSD,
|
||||
R_SCASB,R_SCASW,R_SCASD,
|
||||
R_CMPSB,R_CMPSW,R_CMPSD,
|
||||
};
|
||||
|
||||
#define LoadD(_BLAH) _BLAH
|
||||
|
||||
static void DoString(STRING_OP type) {
|
||||
PhysPt si_base,di_base;
|
||||
Bitu si_index,di_index;
|
||||
Bitu add_mask;
|
||||
Bitu count,count_left;
|
||||
Bits add_index;
|
||||
|
||||
if (TEST_PREFIX_SEG) si_base=core.seg_prefix_base;
|
||||
else si_base=SegBase(ds);
|
||||
di_base=SegBase(es);
|
||||
if (TEST_PREFIX_ADDR) {
|
||||
add_mask=0xFFFFFFFF;
|
||||
si_index=reg_esi;
|
||||
di_index=reg_edi;
|
||||
count=reg_ecx;
|
||||
} else {
|
||||
add_mask=0xFFFF;
|
||||
si_index=reg_si;
|
||||
di_index=reg_di;
|
||||
count=reg_cx;
|
||||
}
|
||||
if (!(TEST_PREFIX_REP)) {
|
||||
count=1;
|
||||
} else {
|
||||
CPU_Cycles++;
|
||||
/* Calculate amount of ops to do before cycles run out */
|
||||
if ((count>(Bitu)CPU_Cycles) && (type<R_SCASB)) {
|
||||
count_left=count-CPU_Cycles;
|
||||
count=CPU_Cycles;
|
||||
CPU_Cycles=0;
|
||||
core.ip_lookup=core.op_start; //Reset IP to start of instruction
|
||||
} else {
|
||||
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */
|
||||
count_left=0;
|
||||
}
|
||||
}
|
||||
add_index=GETFLAG(DF) ? -1 : 1;
|
||||
if (count) switch (type) {
|
||||
case R_OUTSB:
|
||||
for (;count>0;count--) {
|
||||
IO_Write(reg_dx,LoadMb(si_base+si_index));
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_OUTSW:
|
||||
add_index<<=1;
|
||||
for (;count>0;count--) {
|
||||
IO_Write(reg_dx,LoadMb(si_base+si_index));
|
||||
IO_Write(reg_dx+1,LoadMb(si_base+si_index+1));
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_OUTSD:
|
||||
add_index<<=2;
|
||||
for (;count>0;count--) {
|
||||
IO_Write(reg_dx,LoadMb(si_base+si_index));
|
||||
IO_Write(reg_dx+1,LoadMb(si_base+si_index+1));
|
||||
IO_Write(reg_dx+2,LoadMb(si_base+si_index+2));
|
||||
IO_Write(reg_dx+3,LoadMb(si_base+si_index+3));
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_INSB:
|
||||
for (;count>0;count--) {
|
||||
SaveMb(di_base+di_index,IO_Read(reg_dx));
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_INSW:
|
||||
add_index<<=1;
|
||||
for (;count>0;count--) {
|
||||
SaveMb(di_base+di_index,IO_Read(reg_dx));
|
||||
SaveMb(di_base+di_index+1,IO_Read(reg_dx+1));
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_STOSB:
|
||||
for (;count>0;count--) {
|
||||
SaveMb(di_base+di_index,reg_al);
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_STOSW:
|
||||
add_index<<=1;
|
||||
for (;count>0;count--) {
|
||||
SaveMw(di_base+di_index,reg_ax);
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_STOSD:
|
||||
add_index<<=2;
|
||||
for (;count>0;count--) {
|
||||
SaveMd(di_base+di_index,reg_eax);
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_MOVSB:
|
||||
for (;count>0;count--) {
|
||||
SaveMb(di_base+di_index,LoadMb(si_base+si_index));
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_MOVSW:
|
||||
add_index<<=1;
|
||||
for (;count>0;count--) {
|
||||
SaveMw(di_base+di_index,LoadMw(si_base+si_index));
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_MOVSD:
|
||||
add_index<<=2;
|
||||
for (;count>0;count--) {
|
||||
SaveMd(di_base+di_index,LoadMd(si_base+si_index));
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_LODSB:
|
||||
for (;count>0;count--) {
|
||||
reg_al=LoadMb(si_base+si_index);
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_LODSW:
|
||||
add_index<<=1;
|
||||
for (;count>0;count--) {
|
||||
reg_ax=LoadMw(si_base+si_index);
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_LODSD:
|
||||
add_index<<=2;
|
||||
for (;count>0;count--) {
|
||||
reg_eax=LoadMd(si_base+si_index);
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
}
|
||||
break;
|
||||
case R_SCASB:
|
||||
{
|
||||
Bit8u val2;
|
||||
for (;count>0;) {
|
||||
count--;CPU_Cycles--;
|
||||
val2=LoadMb(di_base+di_index);
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
if ((reg_al==val2)!=core.rep_zero) break;
|
||||
}
|
||||
CMPB(reg_al,val2,LoadD,0);
|
||||
}
|
||||
break;
|
||||
case R_SCASW:
|
||||
{
|
||||
add_index<<=1;Bit16u val2;
|
||||
for (;count>0;) {
|
||||
count--;CPU_Cycles--;
|
||||
val2=LoadMw(di_base+di_index);
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
if ((reg_ax==val2)!=core.rep_zero) break;
|
||||
}
|
||||
CMPW(reg_ax,val2,LoadD,0);
|
||||
}
|
||||
break;
|
||||
case R_SCASD:
|
||||
{
|
||||
add_index<<=2;Bit32u val2;
|
||||
for (;count>0;) {
|
||||
count--;CPU_Cycles--;
|
||||
val2=LoadMd(di_base+di_index);
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
if ((reg_eax==val2)!=core.rep_zero) break;
|
||||
}
|
||||
CMPD(reg_eax,val2,LoadD,0);
|
||||
}
|
||||
break;
|
||||
case R_CMPSB:
|
||||
{
|
||||
Bit8u val1,val2;
|
||||
for (;count>0;) {
|
||||
count--;CPU_Cycles--;
|
||||
val1=LoadMb(si_base+si_index);
|
||||
val2=LoadMb(di_base+di_index);
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
if ((val1==val2)!=core.rep_zero) break;
|
||||
}
|
||||
CMPB(val1,val2,LoadD,0);
|
||||
}
|
||||
break;
|
||||
case R_CMPSW:
|
||||
{
|
||||
add_index<<=1;Bit16u val1,val2;
|
||||
for (;count>0;) {
|
||||
count--;CPU_Cycles--;
|
||||
val1=LoadMw(si_base+si_index);
|
||||
val2=LoadMw(di_base+di_index);
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
if ((val1==val2)!=core.rep_zero) break;
|
||||
}
|
||||
CMPW(val1,val2,LoadD,0);
|
||||
}
|
||||
break;
|
||||
case R_CMPSD:
|
||||
{
|
||||
add_index<<=2;Bit32u val1,val2;
|
||||
for (;count>0;) {
|
||||
count--;CPU_Cycles--;
|
||||
val1=LoadMd(si_base+si_index);
|
||||
val2=LoadMd(di_base+di_index);
|
||||
si_index=(si_index+add_index) & add_mask;
|
||||
di_index=(di_index+add_index) & add_mask;
|
||||
if ((val1==val2)!=core.rep_zero) break;
|
||||
}
|
||||
CMPD(val1,val2,LoadD,0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Unhandled string op %d",type);
|
||||
}
|
||||
/* Clean up after certain amount of instructions */
|
||||
reg_esi&=(~add_mask);
|
||||
reg_esi|=(si_index & add_mask);
|
||||
reg_edi&=(~add_mask);
|
||||
reg_edi|=(di_index & add_mask);
|
||||
if (TEST_PREFIX_REP) {
|
||||
count+=count_left;
|
||||
reg_ecx&=(~add_mask);
|
||||
reg_ecx|=(count & add_mask);
|
||||
}
|
||||
}
|
138
src/cpu/core_normal/support.h
Normal file
138
src/cpu/core_normal/support.h
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
#define SETIP(_a_) (core.ip_lookup=SegBase(cs)+_a_)
|
||||
#define GETIP (Bit32u)(core.ip_lookup-SegBase(cs))
|
||||
#define SAVEIP {reg_eip=GETIP;}
|
||||
#define LOADIP {core.ip_lookup=(SegBase(cs)+reg_eip);}
|
||||
|
||||
#define LEAVECORE \
|
||||
SAVEIP; \
|
||||
FillFlags();
|
||||
|
||||
static INLINE void ADDIPw(Bits add) {
|
||||
SAVEIP;
|
||||
reg_eip=(Bit16u)(reg_eip+add);
|
||||
LOADIP;
|
||||
}
|
||||
|
||||
static INLINE void ADDIPd(Bits add) {
|
||||
SAVEIP;
|
||||
reg_eip=(reg_eip+add);
|
||||
LOADIP;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void ADDIPFAST(Bits blah) {
|
||||
core.ip_lookup+=blah;
|
||||
}
|
||||
|
||||
#define EXCEPTION(blah) \
|
||||
{ \
|
||||
Bit8u new_num=blah; \
|
||||
core.ip_lookup=core.op_start; \
|
||||
LEAVECORE; \
|
||||
if (Interrupt(new_num)) { \
|
||||
goto decode_start; \
|
||||
} else return CBRET_NONE; \
|
||||
}
|
||||
|
||||
static INLINE Bit8u Fetchb() {
|
||||
Bit8u temp=LoadMb(core.ip_lookup);
|
||||
core.ip_lookup+=1;
|
||||
return temp;
|
||||
}
|
||||
|
||||
static INLINE Bit16u Fetchw() {
|
||||
Bit16u temp=LoadMw(core.ip_lookup);
|
||||
core.ip_lookup+=2;
|
||||
return temp;
|
||||
}
|
||||
static INLINE Bit32u Fetchd() {
|
||||
Bit32u temp=LoadMd(core.ip_lookup);
|
||||
core.ip_lookup+=4;
|
||||
return temp;
|
||||
}
|
||||
|
||||
static INLINE Bit8s Fetchbs() {
|
||||
return Fetchb();
|
||||
}
|
||||
static INLINE Bit16s Fetchws() {
|
||||
return Fetchw();
|
||||
}
|
||||
|
||||
static INLINE Bit32s Fetchds() {
|
||||
return Fetchd();
|
||||
}
|
||||
|
||||
static INLINE void Push_16(Bit16u blah) {
|
||||
reg_esp-=2;
|
||||
SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
|
||||
};
|
||||
|
||||
static INLINE void Push_32(Bit32u blah) {
|
||||
reg_esp-=4;
|
||||
SaveMd(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
|
||||
};
|
||||
|
||||
static INLINE Bit16u Pop_16() {
|
||||
Bit16u temp=LoadMw(SegBase(ss)+(reg_esp & cpu.stack.mask));
|
||||
reg_esp+=2;
|
||||
return temp;
|
||||
};
|
||||
|
||||
static INLINE Bit32u Pop_32() {
|
||||
Bit32u temp=LoadMd(SegBase(ss)+(reg_esp & cpu.stack.mask));
|
||||
reg_esp+=4;
|
||||
return temp;
|
||||
};
|
||||
|
||||
#define JumpSIb(blah) \
|
||||
if (blah) { \
|
||||
ADDIPFAST(Fetchbs()); \
|
||||
} else { \
|
||||
ADDIPFAST(1); \
|
||||
}
|
||||
|
||||
#define JumpSIw(blah) \
|
||||
if (blah) { \
|
||||
ADDIPw(Fetchws()); \
|
||||
} else { \
|
||||
ADDIPFAST(2); \
|
||||
}
|
||||
|
||||
|
||||
#define JumpSId(blah) \
|
||||
if (blah) { \
|
||||
ADDIPd(Fetchds()); \
|
||||
} else { \
|
||||
ADDIPFAST(4); \
|
||||
}
|
||||
|
||||
#define SETcc(cc) \
|
||||
{ \
|
||||
GetRM; \
|
||||
if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \
|
||||
else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \
|
||||
}
|
||||
|
||||
#include "helpers.h"
|
||||
#include "table_ea.h"
|
||||
#include "../modrm.h"
|
||||
|
||||
|
356
src/cpu/core_normal/table_ea.h
Normal file
356
src/cpu/core_normal/table_ea.h
Normal file
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
typedef PhysPt (*GetEATable[256])(void);
|
||||
typedef PhysPt (*EA_LookupHandler)(void);
|
||||
|
||||
|
||||
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
|
||||
static PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
|
||||
static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); }
|
||||
static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); }
|
||||
static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); }
|
||||
static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
|
||||
static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
|
||||
static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
|
||||
static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
|
||||
|
||||
static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
|
||||
static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
|
||||
static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
|
||||
static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
|
||||
static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); }
|
||||
static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
|
||||
static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
|
||||
static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
|
||||
|
||||
static PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
|
||||
static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
|
||||
static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
|
||||
static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
|
||||
static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); }
|
||||
static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
|
||||
static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
|
||||
static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
|
||||
|
||||
static GetEATable GetEA_NONE={
|
||||
/* 00 */
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||
/* 01 */
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||
/* 10 */
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||
/* 11 These are illegal so make em 0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
static PhysPt EA_16_00_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si); }
|
||||
static PhysPt EA_16_01_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di); }
|
||||
static PhysPt EA_16_02_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si); }
|
||||
static PhysPt EA_16_03_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di); }
|
||||
static PhysPt EA_16_04_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si); }
|
||||
static PhysPt EA_16_05_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di); }
|
||||
static PhysPt EA_16_06_s(void) { return core.seg_prefix_base+(Bit16u)(Fetchw()); }
|
||||
static PhysPt EA_16_07_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx); }
|
||||
|
||||
static PhysPt EA_16_40_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
|
||||
static PhysPt EA_16_41_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
|
||||
static PhysPt EA_16_42_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
|
||||
static PhysPt EA_16_43_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
|
||||
static PhysPt EA_16_44_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchbs()); }
|
||||
static PhysPt EA_16_45_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchbs()); }
|
||||
static PhysPt EA_16_46_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchbs()); }
|
||||
static PhysPt EA_16_47_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchbs()); }
|
||||
|
||||
static PhysPt EA_16_80_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
|
||||
static PhysPt EA_16_81_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
|
||||
static PhysPt EA_16_82_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
|
||||
static PhysPt EA_16_83_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
|
||||
static PhysPt EA_16_84_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchws()); }
|
||||
static PhysPt EA_16_85_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchws()); }
|
||||
static PhysPt EA_16_86_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchws()); }
|
||||
static PhysPt EA_16_87_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchws()); }
|
||||
|
||||
static GetEATable GetEA_SEG={
|
||||
/* 00 */
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||
/* 01 */
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||
/* 10 */
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||
/* 11 These are illegal so make em 0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static Bit32u SIBZero=0;
|
||||
static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi };
|
||||
|
||||
INLINE PhysPt Sib(Bitu mode) {
|
||||
Bit8u sib=Fetchb();
|
||||
PhysPt base;
|
||||
switch (sib&7) {
|
||||
case 0: /* EAX Base */
|
||||
base=SegBase(ds)+reg_eax;break;
|
||||
case 1: /* ECX Base */
|
||||
base=SegBase(ds)+reg_ecx;break;
|
||||
case 2: /* EDX Base */
|
||||
base=SegBase(ds)+reg_edx;break;
|
||||
case 3: /* EBX Base */
|
||||
base=SegBase(ds)+reg_ebx;break;
|
||||
case 4: /* ESP Base */
|
||||
base=SegBase(ss)+reg_esp;break;
|
||||
case 5: /* #1 Base */
|
||||
if (!mode) {
|
||||
base=SegBase(ds)+Fetchd();break;
|
||||
} else {
|
||||
base=SegBase(ss)+reg_ebp;break;
|
||||
}
|
||||
case 6: /* ESI Base */
|
||||
base=SegBase(ds)+reg_esi;break;
|
||||
case 7: /* EDI Base */
|
||||
base=SegBase(ds)+reg_edi;break;
|
||||
}
|
||||
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
|
||||
return base;
|
||||
};
|
||||
|
||||
|
||||
static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
|
||||
static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
|
||||
static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
|
||||
static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
|
||||
static PhysPt EA_32_04_n(void) { return Sib(0);}
|
||||
static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
|
||||
static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; }
|
||||
static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
|
||||
|
||||
static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
|
||||
static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
|
||||
static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
|
||||
static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
|
||||
static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
|
||||
//static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();}
|
||||
static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
|
||||
static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
|
||||
static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
|
||||
|
||||
static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
|
||||
static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
|
||||
static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
|
||||
static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
|
||||
static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();}
|
||||
//static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();}
|
||||
static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
|
||||
static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
|
||||
static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
|
||||
|
||||
static GetEATable GetEA_ADDR={
|
||||
/* 00 */
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||
/* 01 */
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||
/* 10 */
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||
/* 11 These are illegal so make em 0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
INLINE PhysPt Sib_s(Bitu mode) {
|
||||
Bit8u sib=Fetchb();
|
||||
PhysPt base;
|
||||
switch (sib&7) {
|
||||
case 0: /* EAX Base */
|
||||
base=reg_eax;break;
|
||||
case 1: /* ECX Base */
|
||||
base=reg_ecx;break;
|
||||
case 2: /* EDX Base */
|
||||
base=reg_edx;break;
|
||||
case 3: /* EBX Base */
|
||||
base=reg_ebx;break;
|
||||
case 4: /* ESP Base */
|
||||
base=reg_esp;break;
|
||||
case 5: /* #1 Base */
|
||||
if (!mode) {
|
||||
base=Fetchd();break;
|
||||
} else {
|
||||
base=reg_ebp;break;
|
||||
}
|
||||
case 6: /* ESI Base */
|
||||
base=reg_esi;break;
|
||||
case 7: /* EDI Base */
|
||||
base=reg_edi;break;
|
||||
}
|
||||
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
|
||||
return base;
|
||||
};
|
||||
|
||||
|
||||
static PhysPt EA_32_00_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax); }
|
||||
static PhysPt EA_32_01_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx); }
|
||||
static PhysPt EA_32_02_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx); }
|
||||
static PhysPt EA_32_03_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx); }
|
||||
static PhysPt EA_32_04_s(void) { return core.seg_prefix_base+(Bit32u)(Sib_s(0));}
|
||||
static PhysPt EA_32_05_s(void) { return core.seg_prefix_base+(Bit32u)(Fetchd()); }
|
||||
static PhysPt EA_32_06_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi); }
|
||||
static PhysPt EA_32_07_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi); }
|
||||
|
||||
static PhysPt EA_32_40_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchbs()); }
|
||||
static PhysPt EA_32_41_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchbs()); }
|
||||
static PhysPt EA_32_42_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchbs()); }
|
||||
static PhysPt EA_32_43_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchbs()); }
|
||||
static PhysPt EA_32_44_s(void) { PhysPt temp=Sib_s(1);return core.seg_prefix_base+(Bit32u)(temp+Fetchbs());}
|
||||
static PhysPt EA_32_45_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchbs()); }
|
||||
static PhysPt EA_32_46_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchbs()); }
|
||||
static PhysPt EA_32_47_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchbs()); }
|
||||
|
||||
static PhysPt EA_32_80_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchds()); }
|
||||
static PhysPt EA_32_81_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchds()); }
|
||||
static PhysPt EA_32_82_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchds()); }
|
||||
static PhysPt EA_32_83_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchds()); }
|
||||
static PhysPt EA_32_84_s(void) { PhysPt temp=Sib_s(2);return core.seg_prefix_base+(Bit32u)(temp+Fetchds());}
|
||||
static PhysPt EA_32_85_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchds()); }
|
||||
static PhysPt EA_32_86_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchds()); }
|
||||
static PhysPt EA_32_87_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchds()); }
|
||||
|
||||
|
||||
static GetEATable GetEA_SEG_ADDR={
|
||||
/* 00 */
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
|
||||
/* 01 */
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
|
||||
/* 10 */
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
|
||||
/* 11 These are illegal so make em 0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#define GetEADirect \
|
||||
PhysPt eaa; \
|
||||
if (TEST_PREFIX_SEG) { \
|
||||
if (TEST_PREFIX_ADDR) { \
|
||||
eaa=core.seg_prefix_base+Fetchd(); \
|
||||
} else { \
|
||||
eaa=core.seg_prefix_base+Fetchw(); \
|
||||
} \
|
||||
} else { \
|
||||
if (TEST_PREFIX_ADDR) { \
|
||||
eaa=SegBase(ds)+Fetchd(); \
|
||||
} else { \
|
||||
eaa=SegBase(ds)+Fetchw(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
|
@ -44,14 +44,19 @@ CPU_Decoder * cpudecoder;
|
|||
|
||||
void CPU_Real_16_Slow_Start(bool big);
|
||||
void CPU_Core_Full_Start(bool big);
|
||||
void CPU_Core_Insane_Start(bool big);
|
||||
void CPU_Core_Normal_Start(bool big);
|
||||
|
||||
#if 1
|
||||
|
||||
typedef void DecoderStart(void);
|
||||
#define realcore_start CPU_Core_Normal_Start
|
||||
#define pmodecore_start CPU_Core_Normal_Start
|
||||
|
||||
#define realcore_start CPU_Real_16_Slow_Start
|
||||
//#define realcore_start CPU_Core_Insane_Start
|
||||
//#define realcore_start CPU_Core_Full_Start
|
||||
#else
|
||||
|
||||
#define realcore_start CPU_Core_Full_Start
|
||||
#define pmodecore_start CPU_Core_Full_Start
|
||||
|
||||
#endif
|
||||
|
||||
void CPU_Push16(Bitu value) {
|
||||
reg_esp-=2;
|
||||
|
@ -86,7 +91,7 @@ PhysPt SelBase(Bitu sel) {
|
|||
}
|
||||
|
||||
void CPU_SetFlags(Bitu word) {
|
||||
flags.word=(word|2)&~0x14;
|
||||
flags.word=(word|2)&~0x28;
|
||||
}
|
||||
|
||||
bool CPU_CheckCodeType(CODE_TYPE type) {
|
||||
|
@ -97,10 +102,10 @@ bool CPU_CheckCodeType(CODE_TYPE type) {
|
|||
realcore_start(false);
|
||||
break;
|
||||
case CODE_PMODE16:
|
||||
CPU_Core_Full_Start(false);
|
||||
pmodecore_start(false);
|
||||
break;
|
||||
case CODE_PMODE32:
|
||||
CPU_Core_Full_Start(true);
|
||||
pmodecore_start(true);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
@ -272,7 +277,7 @@ bool CPU_IRET(bool use32) {
|
|||
Segs.val[cs]=(selector & 0xfffc) | cpu.cpl;;
|
||||
reg_eip=offset;
|
||||
CPU_SetFlags(old_flags);
|
||||
LOG_MSG("IRET:Same level return to %X:%X",selector,offset);
|
||||
LOG_MSG("IRET:Same level return to %X:%X big %d",selector,offset,cpu.code.big);
|
||||
} else {
|
||||
/* Return to higher privilege */
|
||||
switch (desc.Type()) {
|
||||
|
@ -303,7 +308,7 @@ bool CPU_IRET(bool use32) {
|
|||
reg_esp=new_esp;
|
||||
CPU_SetSegGeneral(ss,new_ss);
|
||||
//TODO Maybe validate other segments, but why would anyone use them?
|
||||
LOG_MSG("IRET:Outer level return to %X:%X",selector,offset);
|
||||
LOG_MSG("IRET:Outer level return to %X:X big %d",selector,offset,cpu.code.big);
|
||||
}
|
||||
return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16);
|
||||
}
|
||||
|
@ -329,11 +334,11 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) {
|
|||
if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL");
|
||||
if (rpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL");
|
||||
cpu.cpl=desc.DPL();
|
||||
LOG_MSG("JMP:Code:NC to %X:%X",selector,offset);
|
||||
LOG_MSG("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big());
|
||||
goto CODE_jmp;
|
||||
case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA:
|
||||
case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA:
|
||||
LOG_MSG("JMP:Code:C to %X:%X",selector,offset);
|
||||
LOG_MSG("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big());
|
||||
CODE_jmp:
|
||||
/* Normal jump to another selector:offset */
|
||||
Segs.phys[cs]=desc.GetBase();
|
||||
|
@ -524,7 +529,6 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) {
|
|||
cpu.pmode=true;
|
||||
LOG_MSG("Protected mode");
|
||||
PAGING_Enable((value & CR0_PAGING)>0);
|
||||
CPU_Core_Full_Start(cpu.code.big);
|
||||
} else {
|
||||
cpu.pmode=false;
|
||||
PAGING_Enable(false);
|
||||
|
@ -578,6 +582,7 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) {
|
|||
|
||||
void CPU_LAR(Bitu selector,Bitu & ar) {
|
||||
Descriptor desc;Bitu rpl=selector & 3;
|
||||
ar=0;
|
||||
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
||||
SETFLAGBIT(ZF,false);
|
||||
return;
|
||||
|
@ -625,6 +630,7 @@ void CPU_LAR(Bitu selector,Bitu & ar) {
|
|||
|
||||
void CPU_LSL(Bitu selector,Bitu & limit) {
|
||||
Descriptor desc;Bitu rpl=selector & 3;
|
||||
limit=0;
|
||||
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
||||
SETFLAGBIT(ZF,false);
|
||||
return;
|
||||
|
|
Loading…
Add table
Reference in a new issue