First CVS upload.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@80
This commit is contained in:
parent
7d1ca9bdd4
commit
42e5d0b779
158 changed files with 42940 additions and 0 deletions
5
src/cpu/Makefile.am
Normal file
5
src/cpu/Makefile.am
Normal file
|
@ -0,0 +1,5 @@
|
|||
SUBDIRS = core_16
|
||||
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
|
171
src/cpu/callback.cpp
Normal file
171
src/cpu/callback.cpp
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "callback.h"
|
||||
#include "mem.h"
|
||||
#include "cpu.h"
|
||||
|
||||
|
||||
/* CallBack are located at 0xC800:0
|
||||
And they are 16 bytes each and you can define them to behave in certain ways like a
|
||||
far return or and IRET
|
||||
*/
|
||||
|
||||
|
||||
CallBack_Handler CallBack_Handlers[CB_MAX];
|
||||
static Bitu call_runint16,call_idle,call_default,call_runfar16;
|
||||
|
||||
static Bitu illegal_handler(void) {
|
||||
E_Exit("Illegal CallBack Called");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Bitu CALLBACK_Allocate(void) {
|
||||
for (Bitu i=0;(i<CB_MAX);i++) {
|
||||
if (CallBack_Handlers[i]==&illegal_handler) {
|
||||
CallBack_Handlers[i]=0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
E_Exit("CALLBACK:Can't allocate handler.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CALLBACK_Idle(void) {
|
||||
/* this makes the cpu execute instructions to handle irq's and then come back */
|
||||
Bit16u oldcs=Segs[cs].value;
|
||||
Bit32u oldeip=reg_eip;
|
||||
SetSegment_16(cs,CB_SEG);
|
||||
reg_eip=call_idle<<4;
|
||||
DOSBOX_RunMachine();
|
||||
reg_eip=oldeip;
|
||||
SetSegment_16(cs,oldcs);
|
||||
}
|
||||
|
||||
static Bitu default_handler(void) {
|
||||
LOG_WARN("Illegal Unhandled Interrupt Called %d",lastint);
|
||||
return CBRET_NONE;
|
||||
};
|
||||
|
||||
static Bitu stop_handler(void) {
|
||||
return CBRET_STOP;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
|
||||
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+1,off);
|
||||
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+3,seg);
|
||||
Bit32u oldeip=reg_eip;
|
||||
Bit16u oldcs=Segs[cs].value;
|
||||
reg_eip=call_runfar16<<4;
|
||||
SetSegment_16(cs,CB_SEG);
|
||||
DOSBOX_RunMachine();
|
||||
reg_eip=oldeip;
|
||||
SetSegment_16(cs,oldcs);
|
||||
}
|
||||
|
||||
void CALLBACK_RunRealInt(Bit8u intnum) {
|
||||
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+1,intnum);
|
||||
Bit32u oldeip=reg_eip;
|
||||
Bit16u oldcs=Segs[cs].value;
|
||||
reg_eip=call_runint16<<4;
|
||||
SetSegment_16(cs,CB_SEG);
|
||||
DOSBOX_RunMachine();
|
||||
reg_eip=oldeip;
|
||||
SetSegment_16(cs,oldcs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CALLBACK_SZF(bool val) {
|
||||
Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFBF;
|
||||
Bit16u newZF=(val==true) << 6;
|
||||
real_writew(Segs[ss].value,reg_sp+4,(tempf | newZF));
|
||||
};
|
||||
|
||||
void CALLBACK_SCF(bool val) {
|
||||
Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFFE;
|
||||
Bit16u newCF=(val==true);
|
||||
real_writew(Segs[ss].value,reg_sp+4,(tempf | newCF));
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) {
|
||||
if (callback>=CB_MAX) return false;
|
||||
switch (type) {
|
||||
case CB_RETF:
|
||||
real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4
|
||||
real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction
|
||||
real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word
|
||||
real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction
|
||||
break;
|
||||
case CB_IRET:
|
||||
real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4
|
||||
real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction
|
||||
real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word
|
||||
real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction
|
||||
break;
|
||||
default:
|
||||
E_Exit("CALLBACK:Setup:Illegal type %d",type);
|
||||
|
||||
}
|
||||
CallBack_Handlers[callback]=handler;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CALLBACK_Init(void) {
|
||||
Bitu i;
|
||||
for (i=0;i<CB_MAX;i++) {
|
||||
CallBack_Handlers[i]=&illegal_handler;
|
||||
}
|
||||
/* Setup the Software interrupt handler */
|
||||
call_runint16=CALLBACK_Allocate();
|
||||
CallBack_Handlers[call_runint16]=stop_handler;
|
||||
real_writeb((Bit16u)CB_SEG,(call_runint16<<4),0xCD);
|
||||
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+2,0xFE);
|
||||
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+3,0x38);
|
||||
real_writew((Bit16u)CB_SEG,(call_runint16<<4)+4,call_runint16);
|
||||
/* Setup the Far Call handler */
|
||||
call_runfar16=CALLBACK_Allocate();
|
||||
CallBack_Handlers[call_runfar16]=stop_handler;
|
||||
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4),0x9A);
|
||||
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4)+5,0xFE);
|
||||
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4)+6,0x38);
|
||||
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+7,call_runfar16);
|
||||
/* Setup the idle handler */
|
||||
call_idle=CALLBACK_Allocate();
|
||||
CallBack_Handlers[call_idle]=stop_handler;
|
||||
for (i=0;i<=11;i++) real_writeb((Bit16u)CB_SEG,(call_idle<<4)+i,0x90);
|
||||
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+12,0xFE);
|
||||
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38);
|
||||
real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle);
|
||||
/* Setup all Interrupt to point to the default handler */
|
||||
call_default=CALLBACK_Allocate();
|
||||
CALLBACK_Setup(call_default,&default_handler,CB_IRET);
|
||||
for (i=0;i<256;i++) {
|
||||
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
|
||||
}
|
||||
}
|
||||
|
||||
|
3
src/cpu/core_16/Makefile.am
Normal file
3
src/cpu/core_16/Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
noinst_HEADERS = helpers.h instructions.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
|
||||
prefix_66_of.h
|
76
src/cpu/core_16/helpers.h
Normal file
76
src/cpu/core_16/helpers.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 \
|
||||
EAPoint eaa=(*lookupEATable)[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 RMEwGw(inst) \
|
||||
{ \
|
||||
GetRMrw; \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \
|
||||
}
|
||||
|
||||
#define RMGwEw(inst) \
|
||||
{ \
|
||||
GetRMrw; \
|
||||
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \
|
||||
else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \
|
||||
}
|
||||
|
||||
#define RMEdGd(inst) \
|
||||
{ \
|
||||
GetRMrd; \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \
|
||||
}
|
||||
|
||||
#define RMGdEd(inst) \
|
||||
{ \
|
||||
GetRMrd; \
|
||||
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \
|
||||
else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \
|
||||
}
|
||||
|
||||
#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);}
|
593
src/cpu/core_16/instructions.h
Normal file
593
src/cpu/core_16/instructions.h
Normal file
|
@ -0,0 +1,593 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Jumps */
|
||||
|
||||
/*
|
||||
Could perhaps do some things with 8 and 16 bit operations like shifts, doing them in 32 bit regs
|
||||
*/
|
||||
|
||||
#define JumpSIb(blah) \
|
||||
if (blah) { \
|
||||
ADDIPFAST(Fetchbs()); \
|
||||
} else { \
|
||||
ADDIPFAST(1); \
|
||||
}
|
||||
|
||||
#define JumpSIw(blah) \
|
||||
if (blah) { \
|
||||
ADDIPFAST(Fetchws()); \
|
||||
} else { \
|
||||
ADDIPFAST(2); \
|
||||
}
|
||||
|
||||
#define INTERRUPT(blah) \
|
||||
{ \
|
||||
Bit8u new_num=blah; \
|
||||
SAVEIP; \
|
||||
Interrupt(new_num); \
|
||||
LOADIP; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* All Byte genereal instructions */
|
||||
#define ADDB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b+flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_ADDb;
|
||||
|
||||
#define ADCB(op1,op2,load,save) \
|
||||
flags.oldcf=get_CF(); \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b+flags.var2.b+flags.oldcf; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_ADCb;
|
||||
|
||||
#define SBBB(op1,op2,load,save) \
|
||||
flags.oldcf=get_CF(); \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b-(flags.var2.b+flags.oldcf); \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_SBBb;
|
||||
|
||||
#define SUBB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b-flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_SUBb;
|
||||
|
||||
#define ORB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b | flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_ORb;
|
||||
|
||||
#define XORB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b ^ flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_XORb;
|
||||
|
||||
#define ANDB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b & flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_ANDb;
|
||||
|
||||
#define CMPB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b-flags.var2.b; \
|
||||
flags.type=t_CMPb;
|
||||
|
||||
#define TESTB(op1,op2,load,save) \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b & flags.var2.b; \
|
||||
flags.type=t_TESTb;
|
||||
|
||||
/* All Word General instructions */
|
||||
|
||||
#define ADDW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w+flags.var2.w; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_ADDw;
|
||||
|
||||
#define ADCW(op1,op2,load,save) \
|
||||
flags.oldcf=get_CF(); \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w+flags.var2.w+flags.oldcf; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_ADCw;
|
||||
|
||||
#define SBBW(op1,op2,load,save) \
|
||||
flags.oldcf=get_CF(); \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w-(flags.var2.w+flags.oldcf); \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_SBBw;
|
||||
|
||||
#define SUBW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w-flags.var2.w; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_SUBw;
|
||||
|
||||
#define ORW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w | flags.var2.w; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_ORw;
|
||||
|
||||
#define XORW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w ^ flags.var2.w; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_XORw;
|
||||
|
||||
#define ANDW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w & flags.var2.w; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_ANDw;
|
||||
|
||||
#define CMPW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w-flags.var2.w; \
|
||||
flags.type=t_CMPw;
|
||||
|
||||
#define TESTW(op1,op2,load,save) \
|
||||
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||
flags.result.w=flags.var1.w & flags.var2.w; \
|
||||
flags.type=t_TESTw;
|
||||
|
||||
/* All DWORD General Instructions */
|
||||
|
||||
#define ADDD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d+flags.var2.d; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_ADDd;
|
||||
|
||||
#define ADCD(op1,op2,load,save) \
|
||||
flags.oldcf=get_CF(); \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d+flags.var2.d+flags.oldcf; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_ADCd;
|
||||
|
||||
#define SBBD(op1,op2,load,save) \
|
||||
flags.oldcf=get_CF(); \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d-(flags.var2.d+flags.oldcf); \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_SBBd;
|
||||
|
||||
#define SUBD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d-flags.var2.d; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_SUBd;
|
||||
|
||||
#define ORD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d | flags.var2.d; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_ORd;
|
||||
|
||||
#define XORD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d ^ flags.var2.d; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_XORd;
|
||||
|
||||
#define ANDD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d & flags.var2.d; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_ANDd;
|
||||
|
||||
#define CMPD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d-flags.var2.d; \
|
||||
flags.type=t_CMPd;
|
||||
|
||||
|
||||
#define TESTD(op1,op2,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||
flags.result.d=flags.var1.d & flags.var2.d; \
|
||||
flags.type=t_TESTd;
|
||||
|
||||
|
||||
|
||||
|
||||
#define INCB(op1,load,save) \
|
||||
LoadCF;flags.result.b=load(op1)+1; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_INCb; \
|
||||
|
||||
#define INCW(op1,load,save) \
|
||||
LoadCF;flags.result.w=load(op1)+1; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_INCw;
|
||||
|
||||
#define INCD(op1,load,save) \
|
||||
LoadCF;flags.result.d=load(op1)+1; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_INCd;
|
||||
|
||||
#define DECB(op1,load,save) \
|
||||
LoadCF;flags.result.b=load(op1)-1; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_DECb;
|
||||
|
||||
#define DECW(op1,load,save) \
|
||||
LoadCF;flags.result.w=load(op1)-1; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_DECw;
|
||||
|
||||
#define DECD(op1,load,save) \
|
||||
LoadCF;flags.result.d=load(op1)-1; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_DECd;
|
||||
|
||||
#define NOTDONE \
|
||||
SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb());
|
||||
|
||||
#define NOTDONE66 \
|
||||
SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb());
|
||||
|
||||
|
||||
//TODO Maybe make this into a bigger split up because of the rm >=0xc0 this seems make it a bit slower
|
||||
//TODO set Zero and Sign flag in one run
|
||||
#define ROLB(op1,op2,load,save) \
|
||||
if (!(op2&0x07)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2&0x07; \
|
||||
flags.result.b=(flags.var1.b << flags.var2.b) | \
|
||||
(flags.var1.b >> (8-flags.var2.b)); \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_ROLb;
|
||||
|
||||
#define ROLW(op1,op2,load,save) \
|
||||
if (!(op2&0x0F)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2&0x0F; \
|
||||
flags.result.w=(flags.var1.w << flags.var2.b) | \
|
||||
(flags.var1.w >> (16-flags.var2.b)); \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_ROLw;
|
||||
|
||||
|
||||
#define ROLD(op1,op2,load,save) \
|
||||
if (!(op2&0x0F)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \
|
||||
flags.result.d=(flags.var1.d << flags.var2.b) | \
|
||||
(flags.var1.d >> (32-flags.var2.b)); \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_ROLd;
|
||||
|
||||
|
||||
#define RORB(op1,op2,load,save) \
|
||||
if (!(op2&0x07)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2&0x07; \
|
||||
flags.result.b=(flags.var1.b >> flags.var2.b) | \
|
||||
(flags.var1.b << (8-flags.var2.b)); \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_RORb;
|
||||
|
||||
|
||||
#define RORW(op1,op2,load,save) \
|
||||
if (!(op2&0x0F)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2&0x0F; \
|
||||
flags.result.w=(flags.var1.w >> flags.var2.b) | \
|
||||
(flags.var1.w << (16-flags.var2.b)); \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_RORw;
|
||||
|
||||
#define RORD(op1,op2,load,save) \
|
||||
if (!(op2&0x0F)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \
|
||||
flags.result.d=(flags.var1.d >> flags.var2.b) | \
|
||||
(flags.var1.d << (32-flags.var2.b)); \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_RORd;
|
||||
|
||||
#define RCLB(op1,op2,load,save) \
|
||||
if (!(op2%9)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.cf=get_CF();flags.type=t_RCLb; \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2%9; \
|
||||
flags.result.b=(flags.var1.b << flags.var2.b) | \
|
||||
(flags.cf << (flags.var2.b-1)) | \
|
||||
(flags.var1.b >> (9-flags.var2.b)); \
|
||||
save(op1,flags.result.b);
|
||||
|
||||
#define RCLW(op1,op2,load,save) \
|
||||
if (!(op2%17)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.cf=get_CF();flags.type=t_RCLw; \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2%17; \
|
||||
flags.result.w=(flags.var1.w << flags.var2.b) | \
|
||||
(flags.cf << (flags.var2.b-1)) | \
|
||||
(flags.var1.w >> (17-flags.var2.b)); \
|
||||
save(op1,flags.result.w);
|
||||
|
||||
#define RCLD(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.cf=get_CF();flags.type=t_RCLd; \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||
if (flags.var2.b==1) { \
|
||||
flags.result.d=flags.var1.d << 1 | flags.cf; \
|
||||
} else { \
|
||||
flags.result.d=(flags.var1.d << flags.var2.b) | \
|
||||
(flags.cf << (flags.var2.b-1)) | \
|
||||
(flags.var1.d >> (33-flags.var2.b)); \
|
||||
} \
|
||||
save(op1,flags.result.d);
|
||||
|
||||
#define RCRB(op1,op2,load,save) \
|
||||
if (!(op2%9)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.cf=get_CF();flags.type=t_RCRb; \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2%9; \
|
||||
flags.result.b=(flags.var1.b >> flags.var2.b) | \
|
||||
(flags.cf << (8-flags.var2.b)) | \
|
||||
(flags.var1.b << (9-flags.var2.b)); \
|
||||
save(op1,flags.result.b);
|
||||
|
||||
#define RCRW(op1,op2,load,save) \
|
||||
if (!(op2%17)) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.cf=get_CF();flags.type=t_RCRw; \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2%17; \
|
||||
flags.result.w=(flags.var1.w >> flags.var2.b) | \
|
||||
(flags.cf << (16-flags.var2.b)) | \
|
||||
(flags.var1.w << (17-flags.var2.b)); \
|
||||
save(op1,flags.result.w);
|
||||
|
||||
|
||||
#define RCRD(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||
flags.cf=get_CF();flags.type=t_RCRd; \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||
if (flags.var2.b==1) { \
|
||||
flags.result.d=flags.var1.d >> 1 | flags.cf << 31; \
|
||||
} else { \
|
||||
flags.result.d=(flags.var1.d >> flags.var2.b) | \
|
||||
(flags.cf << (32-flags.var2.b)) | \
|
||||
(flags.var1.d << (33-flags.var2.b)); \
|
||||
} \
|
||||
save(op1,flags.result.d);
|
||||
|
||||
#define SHLB(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b << flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_SHLb;
|
||||
|
||||
#define SHLW(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2; \
|
||||
flags.result.w=flags.var1.w << flags.var2.b; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_SHLw;
|
||||
|
||||
#define SHLD(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||
flags.result.d=flags.var1.d << flags.var2.b; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_SHLd;
|
||||
|
||||
#define SHRB(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
flags.result.b=flags.var1.b >> flags.var2.b; \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_SHRb;
|
||||
|
||||
#define SHRW(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2; \
|
||||
flags.result.w=flags.var1.w >> flags.var2.b; \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_SHRw;
|
||||
|
||||
#define SHRD(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||
flags.result.d=flags.var1.d >> flags.var2.b; \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_SHRd;
|
||||
|
||||
#define SARB(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||
if (flags.var2.b>8) flags.var2.b=8; \
|
||||
if (flags.var1.b & 0x80) { \
|
||||
flags.result.b=(flags.var1.b >> flags.var2.b)| \
|
||||
(0xff << (8 - flags.var2.b)); \
|
||||
} else { \
|
||||
flags.result.b=flags.var1.b >> flags.var2.b; \
|
||||
} \
|
||||
save(op1,flags.result.b); \
|
||||
flags.type=t_SARb;
|
||||
|
||||
#define SARW(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.w=load(op1);flags.var2.b=op2; \
|
||||
if (flags.var2.b>16) flags.var2.b=16; \
|
||||
if (flags.var1.w & 0x8000) { \
|
||||
flags.result.w=(flags.var1.w >> flags.var2.b)| \
|
||||
(0xffff << (16 - flags.var2.b)); \
|
||||
} else { \
|
||||
flags.result.w=flags.var1.w >> flags.var2.b; \
|
||||
} \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_SARw;
|
||||
|
||||
#define SARD(op1,op2,load,save) \
|
||||
if (!op2) break; \
|
||||
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||
if (flags.var1.d & 0x80000000) { \
|
||||
flags.result.d=(flags.var1.d >> flags.var2.b)| \
|
||||
(0xffffffff << (32 - flags.var2.b)); \
|
||||
} else { \
|
||||
flags.result.d=flags.var1.d >> flags.var2.b; \
|
||||
} \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_SARd;
|
||||
|
||||
|
||||
|
||||
#define GRP2B(blah) \
|
||||
{ \
|
||||
GetRM; \
|
||||
if (rm >= 0xc0) { \
|
||||
GetEArb; \
|
||||
Bit8u val=blah & 0x1f; \
|
||||
switch (rm&0x38) { \
|
||||
case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \
|
||||
case 0x08:RORB(*earb,val,LoadRb,SaveRb);break; \
|
||||
case 0x10:RCLB(*earb,val,LoadRb,SaveRb);break; \
|
||||
case 0x18:RCRB(*earb,val,LoadRb,SaveRb);break; \
|
||||
case 0x20:/* SHL and SAL are the same */ \
|
||||
case 0x30:SHLB(*earb,val,LoadRb,SaveRb);break; \
|
||||
case 0x28:SHRB(*earb,val,LoadRb,SaveRb);break; \
|
||||
case 0x38:SARB(*earb,val,LoadRb,SaveRb);break; \
|
||||
} \
|
||||
} else { \
|
||||
GetEAa; \
|
||||
Bit8u val=blah & 0x1f; \
|
||||
switch (rm & 0x38) { \
|
||||
case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \
|
||||
case 0x08:RORB(eaa,val,LoadMb,SaveMb);break; \
|
||||
case 0x10:RCLB(eaa,val,LoadMb,SaveMb);break; \
|
||||
case 0x18:RCRB(eaa,val,LoadMb,SaveMb);break; \
|
||||
case 0x20:/* SHL and SAL are the same */ \
|
||||
case 0x30:SHLB(eaa,val,LoadMb,SaveMb);break; \
|
||||
case 0x28:SHRB(eaa,val,LoadMb,SaveMb);break; \
|
||||
case 0x38:SARB(eaa,val,LoadMb,SaveMb);break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define GRP2W(blah) \
|
||||
{ \
|
||||
GetRM; \
|
||||
if (rm >= 0xc0) { \
|
||||
GetEArw; \
|
||||
Bit8u val=blah & 0x1f; \
|
||||
switch (rm&0x38) { \
|
||||
case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \
|
||||
case 0x08:RORW(*earw,val,LoadRw,SaveRw);break; \
|
||||
case 0x10:RCLW(*earw,val,LoadRw,SaveRw);break; \
|
||||
case 0x18:RCRW(*earw,val,LoadRw,SaveRw);break; \
|
||||
case 0x20:/* SHL and SAL are the same */ \
|
||||
case 0x30:SHLW(*earw,val,LoadRw,SaveRw);break; \
|
||||
case 0x28:SHRW(*earw,val,LoadRw,SaveRw);break; \
|
||||
case 0x38:SARW(*earw,val,LoadRw,SaveRw);break; \
|
||||
} \
|
||||
} else { \
|
||||
GetEAa; \
|
||||
Bit8u val=blah & 0x1f; \
|
||||
switch (rm & 0x38) { \
|
||||
case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \
|
||||
case 0x08:RORW(eaa,val,LoadMw,SaveMw);break; \
|
||||
case 0x10:RCLW(eaa,val,LoadMw,SaveMw);break; \
|
||||
case 0x18:RCRW(eaa,val,LoadMw,SaveMw);break; \
|
||||
case 0x20:/* SHL and SAL are the same */ \
|
||||
case 0x30:SHLW(eaa,val,LoadMw,SaveMw);break; \
|
||||
case 0x28:SHRW(eaa,val,LoadMw,SaveMw);break; \
|
||||
case 0x38:SARW(eaa,val,LoadMw,SaveMw);break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define GRP2D(blah) \
|
||||
{ \
|
||||
GetRM; \
|
||||
if (rm >= 0xc0) { \
|
||||
GetEArd; \
|
||||
Bit8u val=blah & 0x1f; \
|
||||
switch (rm&0x38) { \
|
||||
case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \
|
||||
case 0x08:RORD(*eard,val,LoadRd,SaveRd);break; \
|
||||
case 0x10:RCLD(*eard,val,LoadRd,SaveRd);break; \
|
||||
case 0x18:RCRD(*eard,val,LoadRd,SaveRd);break; \
|
||||
case 0x20:/* SHL and SAL are the same */ \
|
||||
case 0x30:SHLD(*eard,val,LoadRd,SaveRd);break; \
|
||||
case 0x28:SHRD(*eard,val,LoadRd,SaveRd);break; \
|
||||
case 0x38:SARD(*eard,val,LoadRd,SaveRd);break; \
|
||||
} \
|
||||
} else { \
|
||||
GetEAa; \
|
||||
Bit8u val=blah & 0x1f; \
|
||||
switch (rm & 0x38) { \
|
||||
case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \
|
||||
case 0x08:RORD(eaa,val,LoadMd,SaveMd);break; \
|
||||
case 0x10:RCLD(eaa,val,LoadMd,SaveMd);break; \
|
||||
case 0x18:RCRD(eaa,val,LoadMd,SaveMd);break; \
|
||||
case 0x20:/* SHL and SAL are the same */ \
|
||||
case 0x30:SHLD(eaa,val,LoadMd,SaveMd);break; \
|
||||
case 0x28:SHRD(eaa,val,LoadMd,SaveMd);break; \
|
||||
case 0x38:SARD(eaa,val,LoadMd,SaveMd);break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* let's hope bochs has it correct with the higher than 16 shifts */
|
||||
#define DSHLW(op1,op2,op3,load,save) \
|
||||
flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \
|
||||
Bit32u tempd=flags.var1.d << flags.var2.b; \
|
||||
if (flags.var2.b>16) tempd |= (op2 << (flags.var2.b - 16)); \
|
||||
flags.result.w=(Bit16u)(tempd >> 16); \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_DSHLw;
|
||||
|
||||
#define DSHLD(op1,op2,op3,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.b=op3; \
|
||||
flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_DSHLd;
|
||||
|
||||
#define DSHRW(op1,op2,op3,load,save) \
|
||||
flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \
|
||||
Bit32u tempd=flags.var1.d >> flags.var2.b; \
|
||||
if (flags.var2.b>16) tempd |= (op2 << (32-flags.var2.b )); \
|
||||
flags.result.w=(Bit16u)(tempd); \
|
||||
save(op1,flags.result.w); \
|
||||
flags.type=t_DSHRw;
|
||||
|
||||
#define DSHRD(op1,op2,op3,load,save) \
|
||||
flags.var1.d=load(op1);flags.var2.b=op3; \
|
||||
flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \
|
||||
save(op1,flags.result.d); \
|
||||
flags.type=t_DSHRd;
|
1488
src/cpu/core_16/main.h
Normal file
1488
src/cpu/core_16/main.h
Normal file
File diff suppressed because it is too large
Load diff
469
src/cpu/core_16/prefix_66.h
Normal file
469
src/cpu/core_16/prefix_66.h
Normal file
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
restart_66:
|
||||
switch(Fetchb()) {
|
||||
case 0x01: /* ADD Ed,Gd */
|
||||
RMEdGd(ADDD);break;
|
||||
case 0x03: /* ADD Gd,Ed */
|
||||
RMGdEd(ADDD);break;
|
||||
case 0x05: /* ADD EAX,Id */
|
||||
EAXId(ADDD);break;
|
||||
case 0x09: /* OR Ew,Gw */
|
||||
RMEdGd(ORD);break;
|
||||
case 0x0b: /* OR Gd,Ed */
|
||||
RMGdEd(ORD);break;
|
||||
case 0x0d: /* OR EAX,Id */
|
||||
EAXId(ORD);break;
|
||||
case 0x0f: /* 2 Byte opcodes */
|
||||
#include "prefix_66_of.h"
|
||||
break;
|
||||
case 0x11: /* ADC Ed,Gd */
|
||||
RMEdGd(ADCD);break;
|
||||
case 0x13: /* ADC Gd,Ed */
|
||||
RMGdEd(ADCD);break;
|
||||
case 0x15: /* ADC EAX,Id */
|
||||
EAXId(ADCD);break;
|
||||
case 0x19: /* SBB Ed,Gd */
|
||||
RMEdGd(SBBD);break;
|
||||
case 0x1b: /* SBB Gd,Ed */
|
||||
RMGdEd(SBBD);break;
|
||||
case 0x1d: /* SBB EAX,Id */
|
||||
EAXId(SBBD);break;
|
||||
case 0x21: /* AND Ed,Gd */
|
||||
RMEdGd(ANDD);break;
|
||||
case 0x23: /* AND Gd,Ed */
|
||||
RMGdEd(ANDD);break;
|
||||
case 0x25: /* AND EAX,Id */
|
||||
EAXId(ANDD);break;
|
||||
case 0x29: /* SUB Ed,Gd */
|
||||
RMEdGd(SUBD);break;
|
||||
case 0x2b: /* SUB Gd,Ed */
|
||||
RMGdEd(SUBD);break;
|
||||
case 0x2d: /* SUB EAX,Id */
|
||||
EAXId(SUBD);break;
|
||||
case 0x31: /* XOR Ed,Gd */
|
||||
RMEdGd(XORD);break;
|
||||
case 0x33: /* XOR Gd,Ed */
|
||||
RMGdEd(XORD);break;
|
||||
case 0x35: /* XOR EAX,Id */
|
||||
EAXId(XORD);break;
|
||||
case 0x39: /* CMP Ed,Gd */
|
||||
RMEdGd(CMPD);break;
|
||||
case 0x3b: /* CMP Gd,Ed */
|
||||
RMGdEd(CMPD);break;
|
||||
case 0x3d: /* CMP EAX,Id */
|
||||
EAXId(CMPD);break;
|
||||
|
||||
|
||||
case 0x26: /* SEG ES: */
|
||||
SegPrefix_66(es);break;
|
||||
case 0x2e: /* SEG CS: */
|
||||
SegPrefix_66(cs);break;
|
||||
case 0x36: /* SEG SS: */
|
||||
SegPrefix_66(ss);break;
|
||||
case 0x3e: /* SEG DS: */
|
||||
SegPrefix_66(ds);break;
|
||||
case 0x40: /* INC EAX */
|
||||
INCD(reg_eax,LoadRd,SaveRd);break;
|
||||
case 0x41: /* INC ECX */
|
||||
INCD(reg_ecx,LoadRd,SaveRd);break;
|
||||
case 0x42: /* INC EDX */
|
||||
INCD(reg_edx,LoadRd,SaveRd);break;
|
||||
case 0x43: /* INC EBX */
|
||||
INCD(reg_ebx,LoadRd,SaveRd);break;
|
||||
case 0x44: /* INC ESP */
|
||||
INCD(reg_esp,LoadRd,SaveRd);break;
|
||||
case 0x45: /* INC EBP */
|
||||
INCD(reg_ebp,LoadRd,SaveRd);break;
|
||||
case 0x46: /* INC ESI */
|
||||
INCD(reg_esi,LoadRd,SaveRd);break;
|
||||
case 0x47: /* INC EDI */
|
||||
INCD(reg_edi,LoadRd,SaveRd);break;
|
||||
case 0x48: /* DEC EAX */
|
||||
DECD(reg_eax,LoadRd,SaveRd);break;
|
||||
case 0x49: /* DEC ECX */
|
||||
DECD(reg_ecx,LoadRd,SaveRd);break;
|
||||
case 0x4a: /* DEC EDX */
|
||||
DECD(reg_edx,LoadRd,SaveRd);break;
|
||||
case 0x4b: /* DEC EBX */
|
||||
DECD(reg_ebx,LoadRd,SaveRd);break;
|
||||
case 0x4c: /* DEC ESP */
|
||||
DECD(reg_esp,LoadRd,SaveRd);break;
|
||||
case 0x4d: /* DEC EBP */
|
||||
DECD(reg_ebp,LoadRd,SaveRd);break;
|
||||
case 0x4e: /* DEC ESI */
|
||||
DECD(reg_esi,LoadRd,SaveRd);break;
|
||||
case 0x4f: /* DEC EDI */
|
||||
DECD(reg_edi,LoadRd,SaveRd);break;
|
||||
case 0x50: /* PUSH EAX */
|
||||
Push_32(reg_eax);break;
|
||||
case 0x51: /* PUSH ECX */
|
||||
Push_32(reg_ecx);break;
|
||||
case 0x52: /* PUSH EDX */
|
||||
Push_32(reg_edx);break;
|
||||
case 0x53: /* PUSH EBX */
|
||||
Push_32(reg_ebx);break;
|
||||
case 0x54: /* PUSH ESP */
|
||||
Push_32(reg_esp);break;
|
||||
case 0x55: /* PUSH EBP */
|
||||
Push_32(reg_ebp);break;
|
||||
case 0x56: /* PUSH ESI */
|
||||
Push_32(reg_esi);break;
|
||||
case 0x57: /* PUSH EDI */
|
||||
Push_32(reg_edi);break;
|
||||
case 0x58: /* POP EAX */
|
||||
reg_eax=Pop_32();break;
|
||||
case 0x59: /* POP ECX */
|
||||
reg_ecx=Pop_32();break;
|
||||
case 0x5a: /* POP EDX */
|
||||
reg_edx=Pop_32();break;
|
||||
case 0x5b: /* POP EBX */
|
||||
reg_ebx=Pop_32();break;
|
||||
case 0x5c: /* POP ESP */
|
||||
reg_esp=Pop_32();break;
|
||||
case 0x5d: /* POP EBP */
|
||||
reg_ebp=Pop_32();break;
|
||||
case 0x5e: /* POP ESI */
|
||||
reg_esi=Pop_32();break;
|
||||
case 0x5f: /* POP EDI */
|
||||
reg_edi=Pop_32();break;
|
||||
case 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 0x61: /* POPAD */
|
||||
reg_edi=Pop_32();reg_edi=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 0x68: /* PUSH Id */
|
||||
Push_32(Fetchd());break;
|
||||
case 0x69: /* IMUL Gd,Ed,Id */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit64s res;
|
||||
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchds();}
|
||||
else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchds();}
|
||||
*rmrd=(Bit32s)(res);
|
||||
flags.type=t_MUL;
|
||||
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
|
||||
case 0x6a: /* PUSH Ib */
|
||||
Push_32(Fetchbs());break;
|
||||
case 0x81: /* Grpl Ed,Id */
|
||||
{
|
||||
GetRM;
|
||||
if (rm>= 0xc0) {
|
||||
GetEArd;Bit32u id=Fetchd();
|
||||
switch (rm & 0x38) {
|
||||
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit32u id=Fetchb();
|
||||
switch (rm & 0x38) {
|
||||
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x83: /* Grpl Ed,Ix */
|
||||
{
|
||||
GetRM;
|
||||
if (rm>= 0xc0) {
|
||||
GetEArd;Bit32u id=(Bit32s)Fetchbs();
|
||||
switch (rm & 0x38) {
|
||||
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
|
||||
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit32u id=(Bit32s)Fetchbs();
|
||||
switch (rm & 0x38) {
|
||||
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
|
||||
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x8f: /* POP Ed */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
|
||||
else {GetEAa;SaveMd(eaa,Pop_32());}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x89: /* MOV Ed,Gd */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
|
||||
else {GetEAa;SaveMd(eaa,*rmrd);}
|
||||
break;
|
||||
}
|
||||
case 0x99: /* CDQ */
|
||||
if (reg_eax & 0x80000000) reg_edx=0xffffffff;
|
||||
else reg_edx=0;
|
||||
break;
|
||||
case 0x8b: /* MOV Gd,Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
|
||||
else {GetEAa;*rmrd=LoadMd(eaa);}
|
||||
break;
|
||||
}
|
||||
case 0x8c:
|
||||
LOG_WARN("CPU:66:8c looped back");
|
||||
break;
|
||||
case 0x9c: /* PUSHFD */
|
||||
{
|
||||
Bit32u pflags=
|
||||
(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) |
|
||||
(get_ZF() << 6) | (get_SF() << 7) | (flags.tf << 8) |
|
||||
(flags.intf << 9) |(flags.df << 10) | (get_OF() << 11) |
|
||||
(flags.io << 12) | (flags.nt <<14);
|
||||
Push_32(pflags);
|
||||
break;
|
||||
}
|
||||
case 0x9d: /* POPFD */
|
||||
{
|
||||
Save_Flagsw((Bit16u)(Pop_32()&0xffff));
|
||||
break;
|
||||
}
|
||||
case 0xa1: /* MOV EAX,Ow */
|
||||
if (segprefix_on) {
|
||||
reg_eax=LoadMd(segprefix_base+Fetchw());
|
||||
SegPrefixReset;
|
||||
} else {
|
||||
reg_eax=LoadMd(SegBase(ds)+Fetchw());
|
||||
}
|
||||
break;
|
||||
case 0xa3: /* MOV Ow,EAX */
|
||||
if (segprefix_on) {
|
||||
SaveMd((segprefix_base+Fetchw()),reg_eax);
|
||||
SegPrefixReset;
|
||||
} else {
|
||||
SaveMd((SegBase(ds)+Fetchw()),reg_eax);
|
||||
}
|
||||
break;
|
||||
case 0xa5: /* MOVSD */
|
||||
{
|
||||
stringSI;stringDI;SaveMd(to,LoadMd(from));
|
||||
if (flags.df) { reg_si-=4;reg_di-=4; }
|
||||
else { reg_si+=4;reg_di+=4;}
|
||||
}
|
||||
break;
|
||||
case 0xab: /* STOSD */
|
||||
{
|
||||
stringDI;
|
||||
SaveMd(to,reg_eax);
|
||||
if (flags.df) { reg_di-=4; }
|
||||
else {reg_di+=4;}
|
||||
break;
|
||||
}
|
||||
case 0xad: /* LODSD */
|
||||
{
|
||||
stringSI;
|
||||
reg_eax=LoadMd(from);
|
||||
if (flags.df) { reg_si-=4;}
|
||||
else {reg_si+=4;}
|
||||
break;
|
||||
}
|
||||
case 0xaf: /* SCASD */
|
||||
{
|
||||
stringDI;
|
||||
CMPD(reg_eax,LoadMd(to),LoadRd,0);
|
||||
if (flags.df) { reg_di-=4; }
|
||||
else {reg_di+=4;}
|
||||
break;
|
||||
}
|
||||
case 0xb8: /* MOV EAX,Id */
|
||||
reg_eax=Fetchd();break;
|
||||
case 0xb9: /* MOV ECX,Id */
|
||||
reg_ecx=Fetchd();break;
|
||||
case 0xba: /* MOV EDX,Iw */
|
||||
reg_edx=Fetchd();break;
|
||||
case 0xbb: /* MOV EBX,Id */
|
||||
reg_ebx=Fetchd();break;
|
||||
case 0xbc: /* MOV ESP,Id */
|
||||
reg_esp=Fetchd();break;
|
||||
case 0xbd: /* MOV EBP.Id */
|
||||
reg_ebp=Fetchd();break;
|
||||
case 0xbe: /* MOV ESI,Id */
|
||||
reg_esi=Fetchd();break;
|
||||
case 0xbf: /* MOV EDI,Id */
|
||||
reg_edi=Fetchd();break;
|
||||
case 0xc1: /* GRP2 Ed,Ib */
|
||||
GRP2D(Fetchb());break;
|
||||
case 0xc7: /* MOV Ed,Id */
|
||||
{
|
||||
GetRM;
|
||||
if (rm>0xc0) {GetEArd;*eard=Fetchd();}
|
||||
else {GetEAa;SaveMd(eaa,Fetchd());}
|
||||
break;
|
||||
}
|
||||
case 0xd1: /* GRP2 Ed,1 */
|
||||
GRP2D(1);break;
|
||||
case 0xd3: /* GRP2 Ed,CL */
|
||||
GRP2D(reg_cl);break;
|
||||
case 0xf7: /* GRP3 Ed(,Id) */
|
||||
{
|
||||
union { Bit64u u;Bit64s s;} temp;
|
||||
union {Bit64u u;Bit64s s;} quotient;
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
case 0x00: /* TEST Ed,Id */
|
||||
case 0x08: /* TEST Ed,Id Undocumented*/
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
|
||||
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
|
||||
break;
|
||||
}
|
||||
case 0x10: /* NOT Ed */
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
|
||||
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
|
||||
break;
|
||||
}
|
||||
case 0x18: /* 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 0x20: /* MUL EAX,Ed */
|
||||
{
|
||||
flags.type=t_MUL;
|
||||
if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64s)reg_eax * (Bit64u)(*eard);}
|
||||
else {GetEAa;temp.u=(Bit64u)reg_eax * (Bit64u)LoadMd(eaa);}
|
||||
reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_eax=(Bit32u)(temp.u >> 32);
|
||||
flags.cf=flags.of=(reg_edx !=0);
|
||||
break;
|
||||
}
|
||||
case 0x28: /* IMUL EAX,Ed */
|
||||
{
|
||||
flags.type=t_MUL;
|
||||
if (rm >= 0xc0 ) {GetEArd;temp.s=(Bit64s)reg_eax * (Bit64s)(*eards);}
|
||||
else {GetEAa;temp.s=(Bit64s)reg_eax * (Bit64s)LoadMds(eaa);}
|
||||
reg_eax=Bit32u(temp.u & 0xffffffff);reg_edx=(Bit32u)(temp.u >> 32);
|
||||
if ( (reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) {
|
||||
flags.cf=flags.of=false;
|
||||
} else if ( (reg_edx==0x00000000) && (reg_eax<0x80000000) ) {
|
||||
flags.cf=flags.of=false;
|
||||
} else {
|
||||
flags.cf=flags.of=true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x30: /* DIV Ed */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit32u val;
|
||||
if (rm >= 0xc0 ) {GetEArd;val=*eard;}
|
||||
else {GetEAa;val=LoadMd(eaa);}
|
||||
if (val==0) {Interrupt(0);break;}
|
||||
temp.u=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||
quotient.u=temp.u/val;
|
||||
reg_edx=(Bit32u)(temp.u % val);
|
||||
reg_eax=(Bit32u)(quotient.u & 0xffffffff);
|
||||
if (quotient.u>0xffffffff)
|
||||
Interrupt(0);
|
||||
break;
|
||||
}
|
||||
case 0x38: /* IDIV Ed */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit32s val;
|
||||
if (rm >= 0xc0 ) {GetEArd;val=*eards;}
|
||||
else {GetEAa;val=LoadMds(eaa);}
|
||||
if (val==0) {Interrupt(0);break;}
|
||||
temp.s=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||
quotient.s=(temp.s/val);
|
||||
reg_edx=(Bit32s)(temp.s % val);
|
||||
reg_eax=(Bit32s)(quotient.s);
|
||||
if (quotient.s!=(Bit32s)reg_eax)
|
||||
Interrupt(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xff: /* Group 5 */
|
||||
{
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
case 0x00: /* INC Ew */
|
||||
flags.cf=get_CF();flags.type=t_INCd;
|
||||
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard+=1;}
|
||||
else {GetEAa;flags.result.d=LoadMd(eaa)+1;SaveMd(eaa,flags.result.d);}
|
||||
break;
|
||||
case 0x08: /* DEC Ew */
|
||||
flags.cf=get_CF();flags.type=t_DECd;
|
||||
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard-=1;}
|
||||
else {GetEAa;flags.result.d=LoadMd(eaa)-1;SaveMd(eaa,flags.result.d);}
|
||||
break;
|
||||
case 0x30: /* 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",rm & 0x38);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NOTDONE66;
|
||||
}
|
||||
|
||||
|
124
src/cpu/core_16/prefix_66_of.h
Normal file
124
src/cpu/core_16/prefix_66_of.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
switch (Fetchb()) {
|
||||
|
||||
|
||||
case 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 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 0xb6: /* MOVZX Gd,Eb */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
|
||||
else {GetEAa;*rmrd=LoadMb(eaa);}
|
||||
break;
|
||||
}
|
||||
case 0xaf: /* IMUL Gd,Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit64s res;
|
||||
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*rmrd) * (Bit64s)(*eards);}
|
||||
else {GetEAa;res=(Bit64s)(*rmrd) * (Bit64s)LoadMds(eaa);}
|
||||
*rmrd=(Bit32s)(res);
|
||||
flags.type=t_MUL;
|
||||
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
};
|
||||
case 0xb7: /* MOVXZ Gd,Ew */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;}
|
||||
else {GetEAa;*rmrd=LoadMw(eaa);}
|
||||
break;
|
||||
}
|
||||
case 0xba: /* GRP8 Ed,Ib */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
Bit32u mask=1 << (Fetchb() & 31);
|
||||
flags.cf=(*eard & mask)>0;
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
case 0x28: /* BTS */
|
||||
*eard|=mask;
|
||||
break;
|
||||
case 0x30: /* BTR */
|
||||
*eard&=~mask;
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
if (flags.cf) *eard&=~mask;
|
||||
else *eard|=mask;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
Bit32u mask=1 << (Fetchb() & 31);
|
||||
flags.cf=(old & mask)>0;
|
||||
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 (flags.cf) old&=~mask;
|
||||
else old|=mask;
|
||||
SaveMd(eaa,old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||
flags.type=t_CF;
|
||||
break;
|
||||
}
|
||||
case 0xbe: /* MOVSX Gd,Eb */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earbs;}
|
||||
else {GetEAa;*rmrd=LoadMbs(eaa);}
|
||||
break;
|
||||
}
|
||||
case 0xbf: /* MOVSX Gd,Ew */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earws;}
|
||||
else {GetEAa;*rmrd=LoadMws(eaa);}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SUBIP(1);
|
||||
E_Exit("CPU:Opcode 66:0F:%2X Unhandled",Fetchb());
|
||||
}
|
188
src/cpu/core_16/prefix_of.h
Normal file
188
src/cpu/core_16/prefix_of.h
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
switch(Fetchb()) {
|
||||
case 0x01: /* GRP 7 */
|
||||
{
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* SMSW */
|
||||
/* Let's seriously fake this call */
|
||||
if (rm>0xc0) {GetEArw;*earw=0;}
|
||||
else {GetEAa;SaveMw(eaa,0);}
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:GRP7:Illegal call %2X",rm);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x80: /* JO */
|
||||
JumpSIw(get_OF());break;
|
||||
case 0x81: /* JNO */
|
||||
JumpSIw(!get_OF());break;
|
||||
case 0x82: /* JB */
|
||||
JumpSIw(get_CF());break;
|
||||
case 0x83: /* JNB */
|
||||
JumpSIw(!get_CF());break;
|
||||
case 0x84: /* JZ */
|
||||
JumpSIw(get_ZF());break;
|
||||
case 0x85: /* JNZ */
|
||||
JumpSIw(!get_ZF()); break;
|
||||
case 0x86: /* JBE */
|
||||
JumpSIw(get_CF() || get_ZF());break;
|
||||
case 0x87: /* JNBE */
|
||||
JumpSIw(!get_CF() && !get_ZF());break;
|
||||
case 0x88: /* JS */
|
||||
JumpSIw(get_SF());break;
|
||||
case 0x89: /* JNS */
|
||||
JumpSIw(!get_SF());break;
|
||||
case 0x8a: /* JP */
|
||||
JumpSIw(get_PF());break;
|
||||
case 0x8b: /* JNP */
|
||||
JumpSIw(!get_PF());break;
|
||||
case 0x8c: /* JL */
|
||||
JumpSIw(get_SF() != get_OF());break;
|
||||
case 0x8d: /* JNL */
|
||||
JumpSIw(get_SF() == get_OF());break;
|
||||
case 0x8e: /* JLE */
|
||||
JumpSIw(get_ZF() || (get_SF() != get_OF()));break;
|
||||
case 0x8f: /* JNLE */
|
||||
JumpSIw((get_SF() == get_OF()) && !get_ZF());break;
|
||||
case 0xa0: /* PUSH FS */
|
||||
Push_16(Segs[fs].value);break;
|
||||
case 0xa1: /* POP FS */
|
||||
SetSegment_16(fs,Pop_16());break;
|
||||
case 0xa4: /* SHLD Ew,Gw,Ib */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHLW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
case 0xa5: /* SHLD Ew,Gw,CL */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHLW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
case 0xa8: /* PUSH GS */
|
||||
Push_16(Segs[gs].value);break;
|
||||
case 0xa9: /* POP GS */
|
||||
SetSegment_16(gs,Pop_16());break;
|
||||
case 0xac: /* SHRD Ew,Gw,Ib */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHRW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
case 0xad: /* SHRD Ew,Gw,CL */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHRW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
case 0xaf: /* IMUL Gw,Ew */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit32s res;
|
||||
if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*rmrw) * (Bit32s)(*earws);}
|
||||
else {GetEAa;res=(Bit32s)(*rmrw) *(Bit32s)LoadMws(eaa);}
|
||||
*rmrw=res & 0xFFFF;
|
||||
flags.type=t_MUL;
|
||||
if ((res> -32768) && (res<32767)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
}
|
||||
case 0xb4: /* LFS */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);SetSegment_16(fs,LoadMw(eaa+2));
|
||||
break;
|
||||
}
|
||||
case 0xb5: /* LGS */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);SetSegment_16(gs,LoadMw(eaa+2));
|
||||
break;
|
||||
}
|
||||
case 0xb6: /* MOVZX Gw,Eb */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
|
||||
else {GetEAa;*rmrw=LoadMb(eaa);}
|
||||
break;
|
||||
}
|
||||
case 0xba: /* GRP8 Ew,Ib */
|
||||
{
|
||||
GetRM;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
Bit16u mask=1 << (Fetchb() & 15);
|
||||
flags.cf=(*earw & mask)>0;
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
case 0x28: /* BTS */
|
||||
*earw|=mask;
|
||||
break;
|
||||
case 0x30: /* BTR */
|
||||
*earw&=~mask;
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
if (flags.cf) *earw&=~mask;
|
||||
else *earw|=mask;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
Bit16u mask=1 << (Fetchb() & 15);
|
||||
flags.cf=(old & mask)>0;
|
||||
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 */
|
||||
if (flags.cf) old&=~mask;
|
||||
else old|=mask;
|
||||
SaveMw(eaa,old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||
flags.type=t_CF;
|
||||
break;
|
||||
}
|
||||
case 0xbe: /* MOVSX Gw,Eb */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earbs;}
|
||||
else {GetEAa;*rmrw=LoadMbs(eaa);}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SUBIP(1);
|
||||
E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb());
|
||||
}
|
20
src/cpu/core_16/start.h
Normal file
20
src/cpu/core_16/start.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Setup the CS:IP and SS:SP Pointers */
|
||||
LOADIP;
|
19
src/cpu/core_16/stop.h
Normal file
19
src/cpu/core_16/stop.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
SAVEIP;
|
191
src/cpu/core_16/support.h
Normal file
191
src/cpu/core_16/support.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
EAPoint IPPoint;
|
||||
|
||||
|
||||
#define SUBIP(a) IPPoint-=a
|
||||
#define SETIP(a) IPPoint=SegBase(cs)+a
|
||||
#define GETIP (Bit16u)(IPPoint-SegBase(cs))
|
||||
#define SAVEIP reg_ip=GETIP
|
||||
#define LOADIP IPPoint=SegBase(cs)+reg_ip
|
||||
/*
|
||||
#define ADDIP(a) { \
|
||||
Bit16u add_ip=(Bit16u)(IPPoint-SegBase(cs)); \
|
||||
add_ip+=a; \
|
||||
IPPoint=SegBase(cs)+add_ip; \
|
||||
}
|
||||
*/
|
||||
|
||||
static INLINE void ADDIP(Bit16u add) {
|
||||
|
||||
// Bit16u oldip=(IPPoint-SegBase(cs));
|
||||
// oldip+=add;
|
||||
// IPPoint=SegBase(cs)+oldip;
|
||||
IPPoint=SegBase(cs)+((Bit16u)(((Bit16u)(IPPoint-SegBase(cs)))+(Bit16u)add));
|
||||
}
|
||||
|
||||
static INLINE void ADDIPFAST(Bit16s blah) {
|
||||
IPPoint+=blah;
|
||||
}
|
||||
|
||||
#define ERRORRETURN(a) { error_ret=a;goto errorreturn; }
|
||||
|
||||
|
||||
static INLINE Bit8u Fetchb() {
|
||||
Bit8u temp=LoadMb(IPPoint);
|
||||
IPPoint+=1;
|
||||
return temp;
|
||||
}
|
||||
|
||||
static INLINE Bit16u Fetchw() {
|
||||
Bit16u temp=LoadMw(IPPoint);
|
||||
IPPoint+=2;
|
||||
return temp;
|
||||
}
|
||||
static INLINE Bit32u Fetchd() {
|
||||
Bit32u temp=LoadMd(IPPoint);
|
||||
IPPoint+=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_sp-=2;
|
||||
SaveMw(SegBase(ss)+reg_sp,blah);
|
||||
};
|
||||
|
||||
static INLINE void Push_32(Bit32u blah) {
|
||||
reg_sp-=4;
|
||||
SaveMd(SegBase(ss)+reg_sp,blah);
|
||||
};
|
||||
|
||||
static INLINE Bit16u Pop_16() {
|
||||
Bit16u temp=LoadMw(SegBase(ss)+reg_sp);
|
||||
reg_sp+=2;
|
||||
return temp;
|
||||
};
|
||||
|
||||
static INLINE Bit32u Pop_32() {
|
||||
Bit32u temp=LoadMd(SegBase(ss)+reg_sp);
|
||||
reg_sp+=4;
|
||||
return temp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define stringDI \
|
||||
EAPoint to; \
|
||||
to=SegBase(es)+reg_di
|
||||
|
||||
#define stringSI \
|
||||
EAPoint from; \
|
||||
if (segprefix_on) { \
|
||||
from=(segprefix_base+reg_si); \
|
||||
SegPrefixReset; \
|
||||
} else { \
|
||||
from=SegBase(ds)+reg_si; \
|
||||
}
|
||||
|
||||
|
||||
#include "helpers.h"
|
||||
#include "table_ea.h"
|
||||
#include "../modrm.h"
|
||||
#include "instructions.h"
|
||||
|
||||
|
||||
static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) {
|
||||
bool again;
|
||||
do {
|
||||
again=false;
|
||||
Bit8u repcode=Fetchb();
|
||||
switch (repcode) {
|
||||
case 0x26: /* ES Prefix */
|
||||
again=true;
|
||||
from=SegBase(es);
|
||||
break;
|
||||
case 0x2e: /* CS Prefix */
|
||||
again=true;
|
||||
from=SegBase(cs);
|
||||
break;
|
||||
case 0x36: /* SS Prefix */
|
||||
again=true;
|
||||
from=SegBase(ss);
|
||||
break;
|
||||
case 0x3e: /* DS Prefix */
|
||||
again=true;
|
||||
from=SegBase(ds);
|
||||
break;
|
||||
case 0xa5: /* REP MOVSD */
|
||||
for (;reg_cx>0;reg_cx--) {
|
||||
SaveMd(to+reg_di,LoadMd(from+reg_si));
|
||||
reg_di+=direct*4;
|
||||
reg_si+=direct*4;
|
||||
}
|
||||
break;
|
||||
case 0xab: /* REP STOSW */
|
||||
for (;reg_cx>0;reg_cx--) {
|
||||
SaveMd(to+reg_di,reg_eax);
|
||||
reg_di+=direct*4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:Opcode 66:Illegal REP prefix %2X",repcode);
|
||||
}
|
||||
} while (again);
|
||||
}
|
||||
|
||||
//flags.io and nt shouldn't be compiled for 386
|
||||
#define Save_Flagsw(FLAGW) \
|
||||
{ \
|
||||
flags.type=t_UNKNOWN; \
|
||||
flags.cf =(FLAGW & 0x001)>0;flags.pf =(FLAGW & 0x004)>0; \
|
||||
flags.af =(FLAGW & 0x010)>0;flags.zf =(FLAGW & 0x040)>0; \
|
||||
flags.sf =(FLAGW & 0x080)>0;flags.tf =(FLAGW & 0x100)>0; \
|
||||
flags.intf =(FLAGW & 0x200)>0; \
|
||||
flags.df =(FLAGW & 0x400)>0;flags.of =(FLAGW & 0x800)>0; \
|
||||
flags.io =(FLAGW >> 12) & 0x03; \
|
||||
flags.nt =(FLAGW & 0x4000)>0; \
|
||||
if (flags.intf && PIC_IRQCheck) { \
|
||||
SAVEIP; \
|
||||
PIC_runIRQs(); \
|
||||
LOADIP; \
|
||||
} \
|
||||
if (flags.tf) E_Exit("CPU:Trap Flag not supported"); \
|
||||
}
|
||||
|
||||
|
||||
// if (flags.tf) { \
|
||||
// cpudecoder=CPU_Real_16_Slow_Decode_Special; \
|
||||
// return CBRET_NONE; \
|
||||
// } \
|
283
src/cpu/core_16/table_ea.h
Normal file
283
src/cpu/core_16/table_ea.h
Normal file
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Some variables for EA Loolkup */
|
||||
|
||||
typedef EAPoint (*GetEATable[256])(void);
|
||||
static GetEATable * lookupEATable;
|
||||
|
||||
static EAPoint segprefix_base;
|
||||
static bool segprefix_on=false;
|
||||
|
||||
#define SegPrefix(blah) \
|
||||
segprefix_base=SegBase(blah); \
|
||||
segprefix_on=true; \
|
||||
lookupEATable=&GetEA_16_s; \
|
||||
goto restart; \
|
||||
|
||||
#define SegPrefix_66(blah) \
|
||||
segprefix_base=SegBase(blah); \
|
||||
segprefix_on=true; \
|
||||
lookupEATable=&GetEA_16_s; \
|
||||
goto restart_66; \
|
||||
|
||||
|
||||
|
||||
#define SegPrefixReset \
|
||||
segprefix_on=false;lookupEATable=&GetEA_16_n;
|
||||
|
||||
|
||||
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
|
||||
static EAPoint EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
|
||||
static EAPoint EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); }
|
||||
static EAPoint EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); }
|
||||
static EAPoint EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); }
|
||||
static EAPoint EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
|
||||
static EAPoint EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
|
||||
static EAPoint EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
|
||||
static EAPoint EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
|
||||
|
||||
static EAPoint EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
|
||||
static EAPoint EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
|
||||
static EAPoint EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
|
||||
static EAPoint EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
|
||||
static EAPoint EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); }
|
||||
static EAPoint EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
|
||||
static EAPoint EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
|
||||
static EAPoint EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
|
||||
|
||||
static EAPoint EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
|
||||
static EAPoint EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
|
||||
static EAPoint EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
|
||||
static EAPoint EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
|
||||
static EAPoint EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); }
|
||||
static EAPoint EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
|
||||
static EAPoint EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
|
||||
static EAPoint EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
|
||||
|
||||
static GetEATable GetEA_16_n={
|
||||
/* 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
|
||||
};
|
||||
|
||||
|
||||
#define prefixed(val) EAPoint ret=segprefix_base+val;SegPrefixReset;return ret;
|
||||
|
||||
static EAPoint EA_16_00_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) }
|
||||
static EAPoint EA_16_01_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) }
|
||||
static EAPoint EA_16_02_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) }
|
||||
static EAPoint EA_16_03_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) }
|
||||
static EAPoint EA_16_04_s(void) { prefixed((Bit16u)(reg_si)) }
|
||||
static EAPoint EA_16_05_s(void) { prefixed((Bit16u)(reg_di)) }
|
||||
static EAPoint EA_16_06_s(void) { prefixed((Bit16u)(Fetchw())) }
|
||||
static EAPoint EA_16_07_s(void) { prefixed((Bit16u)(reg_bx)) }
|
||||
|
||||
static EAPoint EA_16_40_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) }
|
||||
static EAPoint EA_16_41_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) }
|
||||
static EAPoint EA_16_42_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) }
|
||||
static EAPoint EA_16_43_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) }
|
||||
static EAPoint EA_16_44_s(void) { prefixed((Bit16u)(reg_si+Fetchbs())) }
|
||||
static EAPoint EA_16_45_s(void) { prefixed((Bit16u)(reg_di+Fetchbs())) }
|
||||
static EAPoint EA_16_46_s(void) { prefixed((Bit16u)(reg_bp+Fetchbs())) }
|
||||
static EAPoint EA_16_47_s(void) { prefixed((Bit16u)(reg_bx+Fetchbs())) }
|
||||
|
||||
static EAPoint EA_16_80_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) }
|
||||
static EAPoint EA_16_81_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) }
|
||||
static EAPoint EA_16_82_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) }
|
||||
static EAPoint EA_16_83_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) }
|
||||
static EAPoint EA_16_84_s(void) { prefixed((Bit16u)(reg_si+Fetchws())) }
|
||||
static EAPoint EA_16_85_s(void) { prefixed((Bit16u)(reg_di+Fetchws())) }
|
||||
static EAPoint EA_16_86_s(void) { prefixed((Bit16u)(reg_bp+Fetchws())) }
|
||||
static EAPoint EA_16_87_s(void) { prefixed((Bit16u)(reg_bx+Fetchws())) }
|
||||
|
||||
static GetEATable GetEA_16_s={
|
||||
/* 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
|
||||
};
|
||||
|
||||
|
||||
INLINE EAPoint Sib(Bitu mode) {
|
||||
Bit8u sib=Fetchb();
|
||||
EAPoint 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(ds)+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;
|
||||
}
|
||||
Bitu shift=sib >> 6;
|
||||
switch ((sib >>3) &7) {
|
||||
case 0: /* EAX Index */
|
||||
base+=(Bit32s)reg_eax<<shift;break;
|
||||
case 1: /* ECX Index */
|
||||
base+=(Bit32s)reg_ecx<<shift;break;
|
||||
case 2: /* EDX Index */
|
||||
base+=(Bit32s)reg_edx<<shift;break;
|
||||
case 3: /* EBX Index */
|
||||
base+=(Bit32s)reg_ebx<<shift;break;
|
||||
case 4: /* None */
|
||||
break;
|
||||
case 5: /* EBP Index */
|
||||
base+=(Bit32s)reg_ebp<<shift;break;
|
||||
case 6: /* ESI Index */
|
||||
base+=(Bit32s)reg_esi<<shift;break;
|
||||
case 7: /* EDI Index */
|
||||
base+=(Bit32s)reg_edi<<shift;break;
|
||||
};
|
||||
return base;
|
||||
};
|
||||
|
||||
|
||||
static EAPoint EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
|
||||
static EAPoint EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
|
||||
static EAPoint EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
|
||||
static EAPoint EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
|
||||
static EAPoint EA_32_04_n(void) { return Sib(0);}
|
||||
static EAPoint EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
|
||||
static EAPoint EA_32_06_n(void) { return SegBase(ss)+reg_esi; }
|
||||
static EAPoint EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
|
||||
|
||||
static EAPoint EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
|
||||
static EAPoint EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
|
||||
static EAPoint EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
|
||||
static EAPoint EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
|
||||
static EAPoint EA_32_44_n(void) { return Sib(1)+Fetchbs();}
|
||||
static EAPoint EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
|
||||
static EAPoint EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
|
||||
static EAPoint EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
|
||||
|
||||
static EAPoint EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
|
||||
static EAPoint EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
|
||||
static EAPoint EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
|
||||
static EAPoint EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
|
||||
static EAPoint EA_32_84_n(void) { return Sib(2)+Fetchds();}
|
||||
static EAPoint EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
|
||||
static EAPoint EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
|
||||
static EAPoint EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
|
||||
|
||||
static GetEATable GetEA_32_n={
|
||||
/* 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
|
||||
};
|
||||
|
185
src/cpu/cpu.cpp
Normal file
185
src/cpu/cpu.cpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
#include "debug.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
//Regs regs;
|
||||
|
||||
Flag_Info flags;
|
||||
|
||||
CPU_Regs cpu_regs;
|
||||
|
||||
|
||||
|
||||
Segment Segs[6];
|
||||
Bit32u cpu_cycles;
|
||||
|
||||
CPU_Decoder * cpudecoder;
|
||||
|
||||
|
||||
static void CPU_CycleIncrease(void) {
|
||||
Bit32u old_cycles=cpu_cycles;
|
||||
cpu_cycles=(Bit32u)(cpu_cycles*1.2);
|
||||
if (cpu_cycles==old_cycles) cpu_cycles++;
|
||||
LOG_MSG("CPU:%d cycles",cpu_cycles);
|
||||
|
||||
}
|
||||
|
||||
static void CPU_CycleDecrease(void) {
|
||||
cpu_cycles=(Bit32u)(cpu_cycles/1.2);
|
||||
if (!cpu_cycles) cpu_cycles=1;
|
||||
LOG_MSG("CPU:%d cycles",cpu_cycles);
|
||||
|
||||
}
|
||||
|
||||
Bit8u lastint;
|
||||
void Interrupt(Bit8u num) {
|
||||
lastint=num;
|
||||
//DEBUG THINGIE to check fucked ints
|
||||
|
||||
switch (num) {
|
||||
case 0x00:
|
||||
LOG_WARN("Divide Error");
|
||||
break;
|
||||
case 0x06:
|
||||
break;
|
||||
case 0x07:
|
||||
LOG_WARN("Co Processor Exception");
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x16:
|
||||
case 0x15:
|
||||
case 0x1A:
|
||||
case 0x17:
|
||||
case 0x1C:
|
||||
case 0x21:
|
||||
case 0x2a:
|
||||
case 0x2f:
|
||||
case 0x33:
|
||||
case 0x67:
|
||||
case 0x74:
|
||||
break;
|
||||
case 0xcd:
|
||||
E_Exit("Call to interrupt 0xCD this is BAD");
|
||||
case 0x03:
|
||||
#ifdef C_DEBUG
|
||||
if (DEBUG_BreakPoint()) return;
|
||||
#endif
|
||||
break;
|
||||
case 0x05:
|
||||
LOG_MSG("CPU:Out Of Bounds interrupt");
|
||||
break;
|
||||
default:
|
||||
// LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah);
|
||||
|
||||
break;
|
||||
};
|
||||
/* Check for 16-bit or 32-bit and then setup everything for the interrupt to start */
|
||||
Bit16u pflags;
|
||||
pflags=
|
||||
(get_CF() << 0) |
|
||||
(get_PF() << 2) |
|
||||
(get_AF() << 4) |
|
||||
(get_ZF() << 6) |
|
||||
(get_SF() << 7) |
|
||||
(flags.tf << 8) |
|
||||
(flags.intf << 9) |
|
||||
(flags.df << 10) |
|
||||
(get_OF() << 11) |
|
||||
(flags.io << 12) |
|
||||
(flags.nt <<14);
|
||||
|
||||
flags.intf=false;
|
||||
flags.tf=false;
|
||||
/* Save everything on a 16-bit stack */
|
||||
reg_sp-=2;
|
||||
mem_writew(Segs[ss].phys+reg_sp,pflags);
|
||||
reg_sp-=2;
|
||||
mem_writew(Segs[ss].phys+reg_sp,Segs[cs].value);
|
||||
reg_sp-=2;
|
||||
mem_writew(Segs[ss].phys+reg_sp,reg_ip);
|
||||
/* Get the new CS:IP from vector table */
|
||||
Bit16u newip=mem_readw(num << 2);
|
||||
Bit16u newcs=mem_readw((num <<2)+2);
|
||||
SetSegment_16(cs,newcs);
|
||||
reg_ip=newip;
|
||||
}
|
||||
|
||||
void CPU_Real_16_Slow_Start(void);
|
||||
|
||||
void SetCPU16bit()
|
||||
{
|
||||
CPU_Real_16_Slow_Start();
|
||||
}
|
||||
|
||||
void SetSegment_16(Bit32u seg,Bit16u val) {
|
||||
Segs[seg].value=val;
|
||||
Bit32u off=(val << 4);
|
||||
Segs[seg].host=memory+off;
|
||||
Segs[seg].phys=off;
|
||||
//TODO Maybe use this feature one day :)
|
||||
// Segs[seg].special=MEMORY_TestSpecial(off);
|
||||
};
|
||||
|
||||
|
||||
void CPU_Init(void) {
|
||||
reg_eax=0;
|
||||
reg_ebx=0;
|
||||
reg_ecx=0;
|
||||
reg_edx=0;
|
||||
reg_edi=0;
|
||||
reg_esi=0;
|
||||
reg_ebp=0;
|
||||
reg_esp=0;
|
||||
|
||||
SetSegment_16(cs,0);
|
||||
SetSegment_16(ds,0);
|
||||
SetSegment_16(es,0);
|
||||
SetSegment_16(fs,0);
|
||||
SetSegment_16(gs,0);
|
||||
SetSegment_16(ss,0);
|
||||
|
||||
reg_eip=0;
|
||||
flags.type=t_UNKNOWN;
|
||||
flags.af=0;
|
||||
flags.cf=0;
|
||||
flags.cf=0;
|
||||
flags.sf=0;
|
||||
flags.zf=0;
|
||||
flags.intf=true;
|
||||
flags.nt=0;
|
||||
flags.io=0;
|
||||
|
||||
SetCPU16bit();
|
||||
cpu_cycles=2000;
|
||||
KEYBOARD_AddEvent(KBD_f11,CTRL_PRESSED,CPU_CycleDecrease);
|
||||
KEYBOARD_AddEvent(KBD_f12,CTRL_PRESSED,CPU_CycleIncrease);
|
||||
|
||||
reg_al=0;
|
||||
reg_ah=0;
|
||||
}
|
||||
|
582
src/cpu/flags.cpp
Normal file
582
src/cpu/flags.cpp
Normal file
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Lazy flag system was designed after the same kind of system used in Bochs.
|
||||
Probably still some bugs left in here.
|
||||
*/
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "cpu.h"
|
||||
#include "pic.h"
|
||||
|
||||
|
||||
/* CF Carry Flag -- Set on high-order bit carry or borrow; cleared
|
||||
otherwise.
|
||||
*/
|
||||
bool get_CF(void) {
|
||||
|
||||
switch (flags.type) {
|
||||
case t_UNKNOWN:
|
||||
case t_CF:
|
||||
case t_INCb:
|
||||
case t_INCw:
|
||||
case t_INCd:
|
||||
case t_DECb:
|
||||
case t_DECw:
|
||||
case t_DECd:
|
||||
case t_MUL:
|
||||
return flags.cf;
|
||||
break;
|
||||
|
||||
case t_ADDb:
|
||||
return (flags.result.b<flags.var1.b);
|
||||
case t_ADDw:
|
||||
return (flags.result.w<flags.var1.w);
|
||||
case t_ADDd:
|
||||
return (flags.result.d<flags.var1.d);
|
||||
case t_ADCb:
|
||||
return (flags.result.b < flags.var1.b) || (flags.oldcf && (flags.result.b == flags.var1.b));
|
||||
case t_ADCw:
|
||||
return (flags.result.w < flags.var1.w) || (flags.oldcf && (flags.result.w == flags.var1.w));
|
||||
case t_ADCd:
|
||||
return (flags.result.d < flags.var1.d) || (flags.oldcf && (flags.result.d == flags.var1.d));
|
||||
case t_SBBb:
|
||||
return (flags.var1.b < flags.result.b) || (flags.oldcf && (flags.var2.b==0xff));
|
||||
case t_SBBw:
|
||||
return (flags.var1.w < flags.result.w) || (flags.oldcf && (flags.var2.w==0xffff));
|
||||
case t_SBBd:
|
||||
return (flags.var1.d < flags.result.d) || (flags.oldcf && (flags.var2.d==0xffffffff));
|
||||
case t_SUBb:
|
||||
case t_CMPb:
|
||||
return (flags.var1.b<flags.var2.b);
|
||||
case t_SUBw:
|
||||
case t_CMPw:
|
||||
return (flags.var1.w<flags.var2.w);
|
||||
case t_SUBd:
|
||||
case t_CMPd:
|
||||
return (flags.var1.d<flags.var2.d);
|
||||
case t_SHLb:
|
||||
if (flags.var2.b>=8) return false;
|
||||
else return (flags.var1.b >> (8-flags.var2.b)) & 1;
|
||||
case t_SHLw:
|
||||
if (flags.var2.b>=16) return false;
|
||||
else return (flags.var1.w >> (16-flags.var2.b)) & 1;
|
||||
case t_SHLd:
|
||||
return (flags.var1.d >> (32 - flags.var2.b)) & 0x01;
|
||||
case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */
|
||||
return (flags.var1.d >> (32 - flags.var2.b)) & 0x01;
|
||||
case t_DSHLd:
|
||||
return (flags.var1.d >> (32 - flags.var2.b)) & 0x01;
|
||||
|
||||
case t_SHRb:
|
||||
return (flags.var1.b >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_SHRw:
|
||||
return (flags.var1.w >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_SHRd:
|
||||
return (flags.var1.d >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_SARb:
|
||||
return (flags.var1.b >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_SARw:
|
||||
return (flags.var1.w >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_SARd:
|
||||
return (flags.var1.d >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */
|
||||
return (flags.var1.d >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_DSHRd:
|
||||
return (flags.var1.d >> (flags.var2.b - 1)) & 0x01;
|
||||
case t_NEGb:
|
||||
return (flags.var1.b!=0);
|
||||
case t_NEGw:
|
||||
return (flags.var1.w!=0);
|
||||
case t_NEGd:
|
||||
return (flags.var1.d!=0);
|
||||
case t_ROLb:
|
||||
return (flags.result.b & 1)>0;
|
||||
case t_ROLw:
|
||||
return (flags.result.w & 1)>0;
|
||||
case t_ROLd:
|
||||
return (flags.result.d & 1)>0;
|
||||
case t_RORb:
|
||||
return (flags.result.b & 0x80)>0;
|
||||
case t_RORw:
|
||||
return (flags.result.w & 0x8000)>0;
|
||||
case t_RORd:
|
||||
return (flags.result.d & 0x80000000)>0;
|
||||
case t_RCLb:
|
||||
return ((flags.var1.b >> (8-flags.var2.b))&1)>0;
|
||||
case t_RCLw:
|
||||
return ((flags.var1.w >> (16-flags.var2.b))&1)>0;
|
||||
case t_RCLd:
|
||||
return ((flags.var1.d >> (32-flags.var2.b))&1)>0;
|
||||
case t_RCRb:
|
||||
return ((flags.var1.b >> (flags.var2.b-1))&1)>0;
|
||||
case t_RCRw:
|
||||
return ((flags.var1.w >> (flags.var2.b-1))&1)>0;
|
||||
case t_RCRd:
|
||||
return ((flags.var1.d >> (flags.var2.b-1))&1)>0;
|
||||
case t_ORb:
|
||||
case t_ORw:
|
||||
case t_ORd:
|
||||
case t_ANDb:
|
||||
case t_ANDw:
|
||||
case t_ANDd:
|
||||
case t_XORb:
|
||||
case t_XORw:
|
||||
case t_XORd:
|
||||
case t_TESTb:
|
||||
case t_TESTw:
|
||||
case t_TESTd:
|
||||
case t_DIV:
|
||||
return false;
|
||||
|
||||
|
||||
default:
|
||||
E_Exit("get_CF Unknown %d",flags.type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* AF Adjust flag -- Set on carry from or borrow to the low order
|
||||
four bits of AL; cleared otherwise. Used for decimal
|
||||
arithmetic.
|
||||
*/
|
||||
bool get_AF(void) {
|
||||
Bitu type=flags.type;
|
||||
again:
|
||||
switch (type) {
|
||||
case t_UNKNOWN:
|
||||
case t_ROLb:
|
||||
case t_RORb:
|
||||
case t_RCLb:
|
||||
case t_RCRb:
|
||||
case t_ROLw:
|
||||
case t_RORw:
|
||||
case t_RCLw:
|
||||
case t_RCRw:
|
||||
case t_ROLd:
|
||||
case t_RORd:
|
||||
case t_RCLd:
|
||||
case t_RCRd:
|
||||
return flags.af;
|
||||
case t_CF:
|
||||
type=flags.prev_type;
|
||||
goto again;
|
||||
|
||||
case t_ADDb:
|
||||
case t_ADCb:
|
||||
case t_SBBb:
|
||||
case t_SUBb:
|
||||
case t_CMPb:
|
||||
return (((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0;
|
||||
case t_ADDw:
|
||||
case t_ADCw:
|
||||
case t_SBBw:
|
||||
case t_SUBw:
|
||||
case t_CMPw:
|
||||
return (((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0;
|
||||
case t_ADCd:
|
||||
case t_ADDd:
|
||||
case t_SBBd:
|
||||
case t_SUBd:
|
||||
case t_CMPd:
|
||||
return (((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0;
|
||||
case t_INCb:
|
||||
return (flags.result.b & 0x0f) == 0;
|
||||
case t_INCw:
|
||||
return (flags.result.w & 0x0f) == 0;
|
||||
case t_INCd:
|
||||
return (flags.result.d & 0x0f) == 0;
|
||||
case t_DECb:
|
||||
return (flags.result.b & 0x0f) == 0x0f;
|
||||
case t_DECw:
|
||||
return (flags.result.w & 0x0f) == 0x0f;
|
||||
case t_DECd:
|
||||
return (flags.result.d & 0x0f) == 0x0f;
|
||||
case t_NEGb:
|
||||
return (flags.var1.b & 0x0f) > 0;
|
||||
case t_NEGw:
|
||||
return (flags.var1.w & 0x0f) > 0;
|
||||
case t_NEGd:
|
||||
return (flags.var1.d & 0x0f) > 0;
|
||||
case t_ORb:
|
||||
case t_ORw:
|
||||
case t_ORd:
|
||||
case t_ANDb:
|
||||
case t_ANDw:
|
||||
case t_ANDd:
|
||||
case t_XORb:
|
||||
case t_XORw:
|
||||
case t_XORd:
|
||||
case t_TESTb:
|
||||
case t_TESTw:
|
||||
case t_TESTd:
|
||||
case t_SHLb:
|
||||
case t_SHLw:
|
||||
case t_SHLd:
|
||||
case t_SHRb:
|
||||
case t_SHRw:
|
||||
case t_SHRd:
|
||||
case t_SARb:
|
||||
case t_SARw:
|
||||
case t_DSHLw:
|
||||
case t_DSHLd:
|
||||
case t_DSHRw:
|
||||
case t_DSHRd:
|
||||
case t_DIV:
|
||||
case t_MUL:
|
||||
return false; /* undefined */
|
||||
default:
|
||||
E_Exit("get_AF Unknown %d",flags.type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ZF Zero Flag -- Set if result is zero; cleared otherwise.
|
||||
*/
|
||||
|
||||
bool get_ZF(void) {
|
||||
Bitu type=flags.type;
|
||||
again:
|
||||
switch (type) {
|
||||
case t_UNKNOWN:
|
||||
case t_ROLb:
|
||||
case t_RORb:
|
||||
case t_RCLb:
|
||||
case t_RCRb:
|
||||
case t_ROLw:
|
||||
case t_RORw:
|
||||
case t_RCLw:
|
||||
case t_RCRw:
|
||||
case t_ROLd:
|
||||
case t_RORd:
|
||||
case t_RCLd:
|
||||
case t_RCRd:
|
||||
return flags.zf;
|
||||
case t_CF:
|
||||
type=flags.prev_type;
|
||||
goto again;
|
||||
case t_ADDb:
|
||||
case t_ORb:
|
||||
case t_ADCb:
|
||||
case t_SBBb:
|
||||
case t_ANDb:
|
||||
case t_XORb:
|
||||
case t_SUBb:
|
||||
case t_CMPb:
|
||||
case t_INCb:
|
||||
case t_DECb:
|
||||
case t_TESTb:
|
||||
case t_SHLb:
|
||||
case t_SHRb:
|
||||
case t_SARb:
|
||||
case t_NEGb:
|
||||
return (flags.result.b==0);
|
||||
case t_ADDw:
|
||||
case t_ORw:
|
||||
case t_ADCw:
|
||||
case t_SBBw:
|
||||
case t_ANDw:
|
||||
case t_XORw:
|
||||
case t_SUBw:
|
||||
case t_CMPw:
|
||||
case t_INCw:
|
||||
case t_DECw:
|
||||
case t_TESTw:
|
||||
case t_SHLw:
|
||||
case t_SHRw:
|
||||
case t_SARw:
|
||||
case t_DSHLw:
|
||||
case t_DSHRw:
|
||||
case t_NEGw:
|
||||
return (flags.result.w==0);
|
||||
case t_ADDd:
|
||||
case t_ORd:
|
||||
case t_ADCd:
|
||||
case t_SBBd:
|
||||
case t_ANDd:
|
||||
case t_XORd:
|
||||
case t_SUBd:
|
||||
case t_CMPd:
|
||||
case t_INCd:
|
||||
case t_DECd:
|
||||
case t_TESTd:
|
||||
case t_SHLd:
|
||||
case t_SHRd:
|
||||
case t_SARd:
|
||||
case t_DSHLd:
|
||||
case t_DSHRd:
|
||||
case t_NEGd:
|
||||
return (flags.result.d==0);
|
||||
case t_DIV:
|
||||
case t_MUL:
|
||||
return false;
|
||||
default:
|
||||
E_Exit("get_ZF Unknown %d",flags.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* SF Sign Flag -- Set equal to high-order bit of result (0 is
|
||||
positive, 1 if negative).
|
||||
*/
|
||||
bool get_SF(void) {
|
||||
Bitu type=flags.type;
|
||||
again:
|
||||
switch (type) {
|
||||
case t_UNKNOWN:
|
||||
case t_ROLb:
|
||||
case t_RORb:
|
||||
case t_RCLb:
|
||||
case t_RCRb:
|
||||
case t_ROLw:
|
||||
case t_RORw:
|
||||
case t_RCLw:
|
||||
case t_RCRw:
|
||||
case t_ROLd:
|
||||
case t_RORd:
|
||||
case t_RCLd:
|
||||
case t_RCRd:
|
||||
return flags.sf;
|
||||
case t_CF:
|
||||
type=flags.prev_type;
|
||||
goto again;
|
||||
|
||||
case t_ADDb:
|
||||
case t_ORb:
|
||||
case t_ADCb:
|
||||
case t_SBBb:
|
||||
case t_ANDb:
|
||||
case t_XORb:
|
||||
case t_SUBb:
|
||||
case t_CMPb:
|
||||
case t_INCb:
|
||||
case t_DECb:
|
||||
case t_TESTb:
|
||||
case t_SHLb:
|
||||
case t_SHRb:
|
||||
case t_SARb:
|
||||
case t_NEGb:
|
||||
return (flags.result.b>=0x80);
|
||||
case t_ADDw:
|
||||
case t_ORw:
|
||||
case t_ADCw:
|
||||
case t_SBBw:
|
||||
case t_ANDw:
|
||||
case t_XORw:
|
||||
case t_SUBw:
|
||||
case t_CMPw:
|
||||
case t_INCw:
|
||||
case t_DECw:
|
||||
case t_TESTw:
|
||||
case t_SHLw:
|
||||
case t_SHRw:
|
||||
case t_SARw:
|
||||
case t_DSHLw:
|
||||
case t_DSHRw:
|
||||
case t_NEGw:
|
||||
return (flags.result.w>=0x8000);
|
||||
case t_ADDd:
|
||||
case t_ORd:
|
||||
case t_ADCd:
|
||||
case t_SBBd:
|
||||
case t_ANDd:
|
||||
case t_XORd:
|
||||
case t_SUBd:
|
||||
case t_CMPd:
|
||||
case t_INCd:
|
||||
case t_DECd:
|
||||
case t_TESTd:
|
||||
case t_SHLd:
|
||||
case t_SHRd:
|
||||
case t_SARd:
|
||||
case t_DSHLd:
|
||||
case t_DSHRd:
|
||||
case t_NEGd:
|
||||
return (flags.result.d>=0x80000000);
|
||||
case t_DIV:
|
||||
case t_MUL:
|
||||
return false;
|
||||
default:
|
||||
E_Exit("get_SF Unkown %d",flags.type);
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
bool get_OF(void) {
|
||||
Bit8u var1b7, var2b7, resultb7;
|
||||
Bit16u var1w15, var2w15, resultw15;
|
||||
Bit32u var1d31, var2d31, resultd31;
|
||||
|
||||
Bitu type=flags.type;
|
||||
again:
|
||||
switch (type) {
|
||||
case t_UNKNOWN:
|
||||
case t_MUL:
|
||||
return flags.of;
|
||||
case t_CF:
|
||||
type=flags.prev_type;
|
||||
goto again;
|
||||
case t_ADDb:
|
||||
case t_ADCb:
|
||||
// return (((flags.result.b) ^ (flags.var2.b)) & ((flags.result.b) ^ (flags.var1.b)) & 0x80)>0;
|
||||
var1b7 = flags.var1.b & 0x80;
|
||||
var2b7 = flags.var2.b & 0x80;
|
||||
resultb7 = flags.result.b & 0x80;
|
||||
return (var1b7 == var2b7) && (resultb7 ^ var2b7);
|
||||
case t_ADDw:
|
||||
case t_ADCw:
|
||||
// return (((flags.result.w) ^ (flags.var2.w)) & ((flags.result.w) ^ (flags.var1.w)) & 0x8000)>0;
|
||||
var1w15 = flags.var1.w & 0x8000;
|
||||
var2w15 = flags.var2.w & 0x8000;
|
||||
resultw15 = flags.result.w & 0x8000;
|
||||
return (var1w15 == var2w15) && (resultw15 ^ var2w15);
|
||||
case t_ADDd:
|
||||
case t_ADCd:
|
||||
//TODO fix dword Overflow
|
||||
var1d31 = flags.var1.d & 0x8000;
|
||||
var2d31 = flags.var2.d & 0x8000;
|
||||
resultd31 = flags.result.d & 0x8000;
|
||||
return (var1d31 == var2d31) && (resultd31 ^ var2d31);
|
||||
case t_SBBb:
|
||||
case t_SUBb:
|
||||
case t_CMPb:
|
||||
// return (((flags.var1.b) ^ (flags.var2.b)) & ((flags.var1.b) ^ (flags.result.b)) & 0x80)>0;
|
||||
var1b7 = flags.var1.b & 0x80;
|
||||
var2b7 = flags.var2.b & 0x80;
|
||||
resultb7 = flags.result.b & 0x80;
|
||||
return (var1b7 ^ var2b7) && (var1b7 ^ resultb7);
|
||||
case t_SBBw:
|
||||
case t_SUBw:
|
||||
case t_CMPw:
|
||||
// return (((flags.var1.w) ^ (flags.var2.w)) & ((flags.var1.w) ^ (flags.result.w)) & 0x8000)>0;
|
||||
var1w15 = flags.var1.w & 0x8000;
|
||||
var2w15 = flags.var2.w & 0x8000;
|
||||
resultw15 = flags.result.w & 0x8000;
|
||||
return (var1w15 ^ var2w15) && (var1w15 ^ resultw15);
|
||||
case t_SBBd:
|
||||
case t_SUBd:
|
||||
case t_CMPd:
|
||||
var1d31 = flags.var1.d & 0x8000;
|
||||
var2d31 = flags.var2.d & 0x8000;
|
||||
resultd31 = flags.result.d & 0x8000;
|
||||
return (var1d31 ^ var2d31) && (var1d31 ^ resultd31);
|
||||
case t_INCb:
|
||||
return (flags.result.b == 0x80);
|
||||
case t_INCw:
|
||||
return (flags.result.w == 0x8000);
|
||||
case t_INCd:
|
||||
return (flags.result.d == 0x80000000);
|
||||
case t_DECb:
|
||||
return (flags.result.b == 0x7f);
|
||||
case t_DECw:
|
||||
return (flags.result.w == 0x7fff);
|
||||
case t_DECd:
|
||||
return (flags.result.d == 0x7fffffff);
|
||||
case t_NEGb:
|
||||
return (flags.var1.b == 0x80);
|
||||
case t_NEGw:
|
||||
return (flags.var1.w == 0x8000);
|
||||
case t_NEGd:
|
||||
return (flags.var1.d == 0x80000000);
|
||||
case t_ROLb:
|
||||
case t_RORb:
|
||||
case t_RCLb:
|
||||
case t_RCRb:
|
||||
case t_SHLb:
|
||||
if (flags.var2.b==1) return ((flags.var1.b ^ flags.result.b) & 0x80) >0;
|
||||
break;
|
||||
case t_ROLw:
|
||||
case t_RORw:
|
||||
case t_RCLw:
|
||||
case t_RCRw:
|
||||
case t_SHLw:
|
||||
case t_DSHLw: //TODO This is euhm inccorect i think but let's keep it for now
|
||||
if (flags.var2.b==1) return ((flags.var1.w ^ flags.result.w) & 0x8000) >0;
|
||||
break;
|
||||
case t_ROLd:
|
||||
case t_RORd:
|
||||
case t_RCLd:
|
||||
case t_RCRd:
|
||||
case t_SHLd:
|
||||
case t_DSHLd:
|
||||
if (flags.var2.b==1) return ((flags.var1.d ^ flags.result.d) & 0x80000000) >0;
|
||||
break;
|
||||
case t_SHRb:
|
||||
if (flags.var2.b==1) return (flags.var1.b >= 0x80);
|
||||
break;
|
||||
case t_SHRw:
|
||||
case t_DSHRw: //TODO
|
||||
if (flags.var2.b==1) return (flags.var1.w >= 0x8000);
|
||||
break;
|
||||
case t_SHRd:
|
||||
case t_DSHRd: //TODO
|
||||
if (flags.var2.b==1) return (flags.var1.d >= 0x80000000);
|
||||
break;
|
||||
case t_SARb:
|
||||
case t_SARw:
|
||||
case t_SARd:
|
||||
case t_ORb:
|
||||
case t_ORw:
|
||||
case t_ORd:
|
||||
case t_ANDb:
|
||||
case t_ANDw:
|
||||
case t_ANDd:
|
||||
case t_XORb:
|
||||
case t_XORw:
|
||||
case t_XORd:
|
||||
case t_TESTb:
|
||||
case t_TESTw:
|
||||
case t_TESTd:
|
||||
case t_DIV:
|
||||
return false;
|
||||
default:
|
||||
E_Exit("get_OF Unkown %d",flags.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool parity_lookup[256] = {
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
||||
};
|
||||
|
||||
bool get_PF(void) {
|
||||
switch (flags.type) {
|
||||
case t_UNKNOWN:
|
||||
return flags.pf;
|
||||
default:
|
||||
return (parity_lookup[flags.result.b]);;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
|
210
src/cpu/modrm.cpp
Normal file
210
src/cpu/modrm.cpp
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
|
||||
Bit8u * lookupRMregb[]=
|
||||
{
|
||||
®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al,
|
||||
®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,
|
||||
®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,
|
||||
®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,
|
||||
®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,
|
||||
®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,
|
||||
®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,
|
||||
®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,
|
||||
|
||||
®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al,
|
||||
®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,
|
||||
®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,
|
||||
®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,
|
||||
®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,
|
||||
®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,
|
||||
®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,
|
||||
®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,
|
||||
|
||||
®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al,
|
||||
®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,
|
||||
®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,
|
||||
®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,
|
||||
®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,
|
||||
®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,
|
||||
®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,
|
||||
®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,
|
||||
|
||||
®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al,
|
||||
®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,
|
||||
®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,
|
||||
®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,
|
||||
®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,
|
||||
®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,
|
||||
®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,
|
||||
®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh
|
||||
};
|
||||
|
||||
Bit16u * lookupRMregw[]={
|
||||
®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,
|
||||
®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,
|
||||
®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,
|
||||
®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,
|
||||
®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,
|
||||
®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,
|
||||
®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si,
|
||||
®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di,
|
||||
|
||||
®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,
|
||||
®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,
|
||||
®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,
|
||||
®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,
|
||||
®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,
|
||||
®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,
|
||||
®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si,
|
||||
®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di,
|
||||
|
||||
®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,
|
||||
®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,
|
||||
®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,
|
||||
®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,
|
||||
®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,
|
||||
®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,
|
||||
®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si,
|
||||
®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di,
|
||||
|
||||
®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,
|
||||
®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,
|
||||
®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,
|
||||
®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,
|
||||
®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,
|
||||
®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,
|
||||
®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si,
|
||||
®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di
|
||||
};
|
||||
|
||||
Bit32u * lookupRMregd[256]={
|
||||
®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,
|
||||
®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,
|
||||
®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,
|
||||
®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,
|
||||
®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,
|
||||
®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,
|
||||
®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,
|
||||
®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,
|
||||
|
||||
®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,
|
||||
®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,
|
||||
®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,
|
||||
®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,
|
||||
®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,
|
||||
®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,
|
||||
®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,
|
||||
®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,
|
||||
|
||||
®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,
|
||||
®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,
|
||||
®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,
|
||||
®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,
|
||||
®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,
|
||||
®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,
|
||||
®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,
|
||||
®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,
|
||||
|
||||
®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,
|
||||
®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,
|
||||
®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,
|
||||
®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,
|
||||
®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,
|
||||
®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,
|
||||
®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,
|
||||
®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi
|
||||
};
|
||||
|
||||
|
||||
Bit8u * lookupRMEAregb[256]={
|
||||
/* 12 lines of 16*0 should give nice errors when used */
|
||||
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, 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, 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,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh,
|
||||
®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh
|
||||
};
|
||||
|
||||
Bit16u * lookupRMEAregw[256]={
|
||||
/* 12 lines of 16*0 should give nice errors when used */
|
||||
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, 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, 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,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di,
|
||||
®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di
|
||||
};
|
||||
|
||||
Bit32u * lookupRMEAregd[256]={
|
||||
/* 12 lines of 16*0 should give nice errors when used */
|
||||
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, 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, 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,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi,
|
||||
®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi
|
||||
};
|
||||
|
||||
|
76
src/cpu/modrm.h
Normal file
76
src/cpu/modrm.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern Bit8u * lookupRMregb[];
|
||||
extern Bit16u * lookupRMregw[];
|
||||
extern Bit32u * lookupRMregd[];
|
||||
extern Bit8u * lookupRMEAregb[256];
|
||||
extern Bit16u * lookupRMEAregw[256];
|
||||
extern Bit32u * lookupRMEAregd[256];
|
||||
|
||||
#define GetRM \
|
||||
Bit8u rm=Fetchb();
|
||||
|
||||
#define Getrb \
|
||||
Bit8u * rmrb; \
|
||||
rmrb=lookupRMregb[rm];
|
||||
|
||||
#define Getrw \
|
||||
Bit16u * rmrw; \
|
||||
rmrw=lookupRMregw[rm];
|
||||
|
||||
#define Getrd \
|
||||
Bit32u * rmrd; \
|
||||
rmrd=lookupRMregd[rm];
|
||||
|
||||
|
||||
#define GetRMrb \
|
||||
GetRM; \
|
||||
Getrb;
|
||||
|
||||
#define GetRMrw \
|
||||
GetRM; \
|
||||
Getrw;
|
||||
|
||||
#define GetRMrd \
|
||||
GetRM; \
|
||||
Getrd;
|
||||
|
||||
|
||||
#define GetEArb \
|
||||
union { \
|
||||
Bit8u * earb; \
|
||||
Bit8s * earbs; \
|
||||
}; \
|
||||
earb=lookupRMEAregb[rm];
|
||||
|
||||
#define GetEArw \
|
||||
union { \
|
||||
Bit16u * earw; \
|
||||
Bit16s * earws; \
|
||||
}; \
|
||||
earw=lookupRMEAregw[rm];
|
||||
|
||||
#define GetEArd \
|
||||
union { \
|
||||
Bit32u * eard; \
|
||||
Bit32s * eards; \
|
||||
}; \
|
||||
eard=lookupRMEAregd[rm];
|
||||
|
||||
|
120
src/cpu/slow_16.cpp
Normal file
120
src/cpu/slow_16.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "mem.h"
|
||||
#include "cpu.h"
|
||||
#include "inout.h"
|
||||
#include "callback.h"
|
||||
#include "pic.h"
|
||||
#include "fpu.h"
|
||||
|
||||
|
||||
typedef PhysPt EAPoint;
|
||||
|
||||
#define SegBase(seg) Segs[seg].phys
|
||||
|
||||
#define LoadMb(off) mem_readb(off)
|
||||
#define LoadMw(off) mem_readw(off)
|
||||
#define LoadMd(off) mem_readd(off)
|
||||
|
||||
#define LoadMbs(off) (Bit8s)(LoadMb(off))
|
||||
#define LoadMws(off) (Bit16s)(LoadMw(off))
|
||||
#define LoadMds(off) (Bit32s)(LoadMd(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)
|
||||
|
||||
|
||||
/*
|
||||
typedef HostOff EAPoint;
|
||||
|
||||
#define SegBase(seg) Segs[seg].host
|
||||
|
||||
#define LoadMb(off) readb(off)
|
||||
#define LoadMw(off) readw(off)
|
||||
#define LoadMd(off) readd(off)
|
||||
|
||||
#define LoadMbs(off) (Bit8s)(LoadMb(off))
|
||||
#define LoadMws(off) (Bit16s)(LoadMw(off))
|
||||
#define LoadMds(off) (Bit32s)(LoadMd(off))
|
||||
|
||||
#define SaveMb(off,val) writeb(off,val)
|
||||
#define SaveMw(off,val) writew(off,val)
|
||||
#define SaveMd(off,val) writed(off,val)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
#define CPU_386
|
||||
//TODO Change name
|
||||
#define FULLFLAGS
|
||||
|
||||
|
||||
#include "core_16/support.h"
|
||||
static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count);
|
||||
static Bitu CPU_Real_16_Slow_Decode(Bitu count) {
|
||||
#include "core_16/start.h"
|
||||
while (count) {
|
||||
#ifdef C_DEBUG
|
||||
cycle_count++;
|
||||
#endif
|
||||
count--;
|
||||
#include "core_16/main.h"
|
||||
}
|
||||
#include "core_16/stop.h"
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count) {
|
||||
while (count>0) {
|
||||
if (flags.tf) {
|
||||
Interrupt(3);
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
CPU_Real_16_Slow_Decode(1);
|
||||
if (!flags.tf) {
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode;
|
||||
return CBRET_NONE;
|
||||
};
|
||||
count--;
|
||||
}
|
||||
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
void CPU_Real_16_Slow_Start(void) {
|
||||
|
||||
lookupEATable=&GetEA_16_n;
|
||||
segprefix_base=0;
|
||||
segprefix_on=false;
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode;
|
||||
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue