1
0
Fork 0

First CVS upload.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@80
This commit is contained in:
Sjoerd van der Berg 2002-07-27 13:08:48 +00:00
parent 7d1ca9bdd4
commit 42e5d0b779
158 changed files with 42940 additions and 0 deletions

5
src/cpu/Makefile.am Normal file
View 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
View 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));
}
}

View 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
View 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);}

View 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

File diff suppressed because it is too large Load diff

469
src/cpu/core_16/prefix_66.h Normal file
View 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;
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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[]=
{
&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,
&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,
&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,
&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,
&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,
&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,
&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,
&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,
&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,
&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,
&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,
&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,
&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,
&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,
&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,
&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,
&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,
&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,
&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,
&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,
&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,
&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,
&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,
&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,
&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,&reg_al,
&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,&reg_cl,
&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,&reg_dl,
&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,&reg_bl,
&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,&reg_ah,
&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,&reg_ch,
&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,&reg_dh,
&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh,&reg_bh
};
Bit16u * lookupRMregw[]={
&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,
&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,
&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,
&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,
&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,
&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,
&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,
&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,
&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,
&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,
&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,
&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,
&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,
&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,
&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,
&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,
&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,
&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,
&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,
&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,
&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,
&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,
&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,
&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,
&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,&reg_ax,
&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,&reg_cx,
&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,&reg_dx,
&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,&reg_bx,
&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,&reg_sp,
&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,&reg_bp,
&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,&reg_si,
&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di,&reg_di
};
Bit32u * lookupRMregd[256]={
&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,
&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,
&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,
&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,
&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,
&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,
&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,
&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,
&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,
&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,
&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,
&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,
&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,
&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,
&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,
&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,
&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,
&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,
&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,
&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,
&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,
&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,
&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,
&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,
&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,&reg_eax,
&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,&reg_ecx,
&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,&reg_edx,
&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,&reg_ebx,
&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,&reg_esp,
&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,&reg_ebp,
&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,&reg_esi,
&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_edi,&reg_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,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_bh,
&reg_al,&reg_cl,&reg_dl,&reg_bl,&reg_ah,&reg_ch,&reg_dh,&reg_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,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_di,
&reg_ax,&reg_cx,&reg_dx,&reg_bx,&reg_sp,&reg_bp,&reg_si,&reg_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,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi,
&reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&reg_esp,&reg_ebp,&reg_esi,&reg_edi
};

76
src/cpu/modrm.h Normal file
View 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
View 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;
};