1
0
Fork 0

New lazy flag header file and endian fixes for flags

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1378
This commit is contained in:
Sjoerd van der Berg 2003-10-26 19:00:47 +00:00
parent e92e17addd
commit 66df37b533
21 changed files with 614 additions and 3833 deletions

View file

@ -1,4 +1,4 @@
SUBDIRS = core_16 core_full core_normal
SUBDIRS = core_full core_normal
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a

View file

@ -1,3 +0,0 @@
noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h support.h table_ea.h \
prefix_66_of.h

View file

@ -1,143 +0,0 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define GetEAa \
PhysPt eaa=(*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 RMEb(inst) \
{ \
if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \
else {GetEAa;inst(eaa,LoadMb,SaveMb);} \
}
#define RMEwGw(inst) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \
}
#define RMEwGwOp3(inst,op3) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \
}
#define RMGwEw(inst) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \
}
#define RMGwEwOp3(inst,op3) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \
else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \
}
#define RMEw(inst) \
{ \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,LoadMw,SaveMw);} \
}
#define RMEdGd(inst) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \
}
#define RMEdGdOp3(inst,op3) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \
}
#define RMGdEd(inst) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \
else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \
}
#define RMGdEdOp3(inst,op3) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \
else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \
}
#define RMEw(inst) \
{ \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,LoadMw,SaveMw);} \
}
#define RMEd(inst) \
{ \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,LoadMd,SaveMd);} \
}
#define ALIb(inst) \
{ inst(reg_al,Fetchb(),LoadRb,SaveRb)}
#define AXIw(inst) \
{ inst(reg_ax,Fetchw(),LoadRw,SaveRw);}
#define EAXId(inst) \
{ inst(reg_eax,Fetchd(),LoadRd,SaveRd);}
#define FPU_ESC(code) { \
Bit8u rm=Fetchb(); \
if (rm>=0xc0) { \
FPU_ESC ## code ## _Normal(rm); \
} else { \
GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \
} \
}

File diff suppressed because it is too large Load diff

View file

@ -1,490 +0,0 @@
/*
* 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 Ed,Gd */
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_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
break;
case 0x64: /* SEG FS: */
SegPrefix_66(fs);break;
case 0x65: /* SEG GS: */
SegPrefix_66(gs);break;
case 0x67: /* Address Size Prefix */
#ifdef CPU_PREFIX_67
core_16.prefixes^=PREFIX_ADDR;
lookupEATable=EAPrefixTable[core_16.prefixes];
goto restart_66;
#else
NOTDONE;
#endif
case 0x68: /* PUSH Id */
Push_32(Fetchd());break;
case 0x69: /* IMUL Gd,Ed,Id */
RMGdEdOp3(DIMULD,Fetchds());
break;
case 0x6a: /* PUSH Ib */
Push_32(Fetchbs());break;
case 0x6b: /* IMUL Gd,Ed,Ib */
RMGdEdOp3(DIMULD,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=Fetchd();
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 0x85: /* TEST Ed,Gd */
RMEdGd(TESTD);break;
case 0x87: /* XCHG Ev,Gv */
{
GetRMrd;Bit32u oldrmrd=*rmrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;}
else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);}
break;
}
case 0x89: /* MOV Ed,Gd */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
else {GetEAa;SaveMd(eaa,*rmrd);}
break;
}
case 0x8b: /* MOV Gd,Ed */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
else {GetEAa;*rmrd=LoadMd(eaa);}
break;
}
case 0x8c:
LOG(LOG_CPU,LOG_NORMAL)("CPU:66:8c looped back");
break;
case 0x8d: /* LEA */
{
core_16.segbase=0;
core_16.prefixes|=PREFIX_SEG;
lookupEATable=EAPrefixTable[core_16.prefixes];
GetRMrd;GetEAa;
*rmrd=(Bit32u)eaa;
break;
}
case 0x8f: /* POP Ed */
{
GetRM;
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
else {GetEAa;SaveMd(eaa,Pop_32());}
break;
}
case 0x90: /* NOP */
break;
case 0x91: /* XCHG ECX,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp; }
break;
case 0x92: /* XCHG EDX,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp; }
break;
case 0x93: /* XCHG EBX,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp; }
break;
case 0x94: /* XCHG ESP,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp; }
break;
case 0x95: /* XCHG EBP,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp; }
break;
case 0x96: /* XCHG ESI,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp; }
break;
case 0x97: /* XCHG EDI,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp; }
break;
case 0x98: /* CWD */
reg_eax=(Bit16s)reg_ax;break;
case 0x99: /* CDQ */
if (reg_eax & 0x80000000) reg_edx=0xffffffff;
else reg_edx=0;
break;
case 0x9c: /* PUSHFD */
FillFlags();
Push_32(flags.word);
break;
case 0x9d: /* POPFD */
SETFLAGSd(Pop_32())
CheckTF();
#ifdef CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
#endif
break;
case 0xa1: /* MOV EAX,Ow */
reg_eax=LoadMd(GetEADirect[core_16.prefixes]());
break;
case 0xa3: /* MOV Ow,EAX */
SaveMd(GetEADirect[core_16.prefixes](),reg_eax);
break;
case 0xa5: /* MOVSD */
{
stringSI;stringDI;SaveMd(to,LoadMd(from));
if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; }
else { reg_si+=4;reg_di+=4;}
}
break;
case 0xa7: /* CMPSD */
{
stringSI;stringDI; CMPD(to,LoadMd(from),LoadMd,0);
if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; }
else { reg_si+=4;reg_di+=4;}
}
break;
case 0xa9: /* TEST EAX,Id */
EAXId(TESTD);
break;
case 0xab: /* STOSD */
{
stringDI;
SaveMd(to,reg_eax);
if (GETFLAG(DF)) { reg_di-=4; }
else {reg_di+=4;}
break;
}
case 0xad: /* LODSD */
{
stringSI;
reg_eax=LoadMd(from);
if (GETFLAG(DF)) { reg_si-=4;}
else {reg_si+=4;}
break;
}
case 0xaf: /* SCASD */
{
stringDI;
CMPD(reg_eax,LoadMd(to),LoadRd,0);
if (GETFLAG(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 0xc4: /* LES */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);SegSet16(es,LoadMw(eaa+4));
break;
}
case 0xc5: /* LDS */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);SegSet16(ds,LoadMw(eaa+4));
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 0xed: /* IN EAX,DX */
reg_eax=IO_Read(reg_dx) |
(IO_Read(reg_dx+1) << 8) |
(IO_Read(reg_dx+2) << 16) |
(IO_Read(reg_dx+3) << 24);
break;
case 0xef: /* OUT DX,EAX */
IO_Write(reg_dx,(Bit8u)(reg_eax>>0));
IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8));
IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16));
IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24));
break;
case 0xf2: /* REPNZ */
Repeat_Normal(false,true);
continue;
case 0xf3: /* REPZ */
Repeat_Normal(true,true);
continue;
case 0xf7: /* GRP3 Ed(,Id) */
{
GetRM;
switch ((rm & 0x38)>>3) {
case 0x00: /* TEST Ed,Id */
case 0x01: /* TEST Ed,Id Undocumented*/
{
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
break;
}
case 0x02: /* NOT Ed */
{
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
break;
}
case 0x03: /* NEG Ed */
{
flags.type=t_NEGd;
if (rm >= 0xc0 ) {
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
*eard=flags.result.d;
} else {
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
SaveMd(eaa,flags.result.d);
}
break;
}
case 0x04: /* MUL EAX,Ed */
RMEd(MULD);
break;
case 0x05: /* IMUL EAX,Ed */
RMEd(IMULD);
break;
case 0x06: /* DIV Ed */
RMEd(DIVD);
break;
case 0x07: /* IDIV Ed */
RMEd(IDIVD);
break;
}
break;
}
case 0xff: /* Group 5 */
{
GetRM;
switch (rm & 0x38) {
case 0x00: /* INC Ed */
RMEd(INCD);
break;
case 0x08: /* DEC Ed */
RMEd(DECD);
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

@ -1,226 +0,0 @@
/*
* 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: /* Group 7 Ed */
{
GetRM;Bitu which=(rm>>3)&7;
if (rm < 0xc0) { //First ones all use EA
GetEAa;Bitu limit,base;
switch (which) {
case 0x00: /* SGDT */
CPU_SGDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x01: /* SIDT */
CPU_SIDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x02: /* LGDT */
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2));
break;
case 0x03: /* LIDT */
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2));
break;
case 0x04: /* SMSW */
CPU_SMSW(limit);
SaveMw(eaa,limit);
break;
case 0x06: /* LMSW */
limit=LoadMw(eaa);
if (!CPU_LMSW(limit)) goto decode_end;
break;
}
} else {
GetEArw;Bitu limit;
switch (which) {
case 0x04: /* SMSW */
CPU_SMSW(limit);
*earw=limit;
break;
case 0x06: /* LMSW */
if (!CPU_LMSW(*earw)) goto decode_end;
break;
default:
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
break;
}
}
}
break;
case 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 0xad: /* SHRD Ed,Gd,Cl */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);}
else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);}
break;
}
case 0xb6: /* MOVZX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
else {GetEAa;*rmrd=LoadMb(eaa);}
break;
}
case 0xaf: /* IMUL Gd,Ed */
{
RMGdEdOp3(DIMULD,*rmrd);
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);
SETFLAGBIT(CF,(*eard & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
*eard|=mask;
break;
case 0x30: /* BTR */
*eard&=~mask;
break;
case 0x38: /* BTC */
if (GETFLAG(CF)) *eard&=~mask;
else *eard|=mask;
break;
default:
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
}
} else {
GetEAa;Bit32u old=LoadMd(eaa);
Bit32u mask=1 << (Fetchb() & 31);
SETFLAGBIT(CF,(old & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
SaveMd(eaa,old|mask);
break;
case 0x30: /* BTR */
SaveMd(eaa,old & ~mask);
break;
case 0x38: /* BTC */
if (GETFLAG(CF)) old&=~mask;
else old|=mask;
SaveMd(eaa,old);
break;
default:
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
}
case 0xbb: /* BTC Ed,Gd */
{
GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
SETFLAGBIT(CF,(*eard & mask));
*eard^=mask;
} else {
GetEAa;Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbc: /* BSF Gd,Ed */
{
GetRMrd;
Bit32u result,value;
if (rm >= 0xc0) { GetEArd; value=*eard; }
else { GetEAa; value=LoadMd(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 0;
while ((value & 0x01)==0) { result++; value>>=1; }
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbd: /* BSR Gd,Ed */
{
GetRMrd;
Bit32u result,value;
if (rm >= 0xc0) { GetEArd; value=*eard; }
else { GetEAa; value=LoadMd(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 35; // Operandsize-1
while ((value & 0x80000000)==0) { result--; value<<=1; }
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbe: /* MOVSX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;}
else {GetEAa;*rmrd=LoadMbs(eaa);}
break;
}
case 0xbf: /* MOVSX Gd,Ew */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;}
else {GetEAa;*rmrd=LoadMws(eaa);}
break;
}
default:
SUBIP(1);
E_Exit("CPU:Opcode 66:0F:%2X Unhandled",Fetchb());
}

View file

@ -1,425 +0,0 @@
/*
* 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 0x00: /* GRP 6 */
{
GetRM;Bitu which=(rm>>3)&7;
switch (which) {
case 0x00: /* SLDT */
case 0x01: /* STR */
{
Bitu saveval;
if (!which) CPU_SLDT(saveval);
else CPU_STR(saveval);
if (rm>0xc0) {GetEArw;*earw=saveval;}
else {GetEAa;SaveMw(eaa,saveval);}
}
break;
case 0x02:case 0x03:case 0x04:case 0x05:
{
Bitu loadval;
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
else {GetEAa;loadval=LoadMw(eaa);}
break;
switch (which) {
case 0x02:CPU_LLDT(loadval);break;
case 0x03:CPU_LTR(loadval);break;
case 0x04:CPU_VERR(loadval);break;
case 0x05:CPU_VERW(loadval);break;
}
}
default:
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
}
}
break;
case 0x01: /* Group 7 Ew */
{
GetRM;Bitu which=(rm>>3)&7;
if (rm < 0xc0) { //First ones all use EA
GetEAa;Bitu limit,base;
switch (which) {
case 0x00: /* SGDT */
CPU_SGDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x01: /* SIDT */
CPU_SIDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x02: /* LGDT */
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
break;
case 0x03: /* LIDT */
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
break;
case 0x04: /* SMSW */
CPU_SMSW(limit);
SaveMw(eaa,limit);
break;
case 0x06: /* LMSW */
limit=LoadMw(eaa);
if (!CPU_LMSW(limit)) goto decode_end;
break;
}
} else {
GetEArw;Bitu limit;
switch (which) {
case 0x04: /* SMSW */
CPU_SMSW(limit);
*earw=limit;
break;
case 0x06: /* LMSW */
if (!CPU_LMSW(*earw)) goto decode_end;
break;
default:
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
break;
}
}
}
break;
case 0x20: /* MOV Rd.CRx */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
*eard=CPU_GET_CRX(which);
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which);
}
}
break;
case 0x22: /* MOV CRx,Rd */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
if (!CPU_SET_CRX(which,*eard)) goto decode_end;
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which);
}
}
break;
case 0x23: /* MOV DRx,Rd */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which);
}
}
break;
case 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 0x90: /* SETO */
SETcc(get_OF());break;
case 0x91: /* SETNO */
SETcc(!get_OF());break;
case 0x92: /* SETB */
SETcc(get_CF());break;
case 0x93: /* SETNB */
SETcc(!get_CF());break;
case 0x94: /* SETZ */
SETcc(get_ZF());break;
case 0x95: /* SETNZ */
SETcc(!get_ZF()); break;
case 0x96: /* SETBE */
SETcc(get_CF() || get_ZF());break;
case 0x97: /* SETNBE */
SETcc(!get_CF() && !get_ZF());break;
case 0x98: /* SETS */
SETcc(get_SF());break;
case 0x99: /* SETNS */
SETcc(!get_SF());break;
case 0x9a: /* SETP */
SETcc(get_PF());break;
case 0x9b: /* SETNP */
SETcc(!get_PF());break;
case 0x9c: /* SETL */
SETcc(get_SF() != get_OF());break;
case 0x9d: /* SETNL */
SETcc(get_SF() == get_OF());break;
case 0x9e: /* SETLE */
SETcc(get_ZF() || (get_SF() != get_OF()));break;
case 0x9f: /* SETNLE */
SETcc((get_SF() == get_OF()) && !get_ZF());break;
case 0xa0: /* PUSH FS */
Push_16(SegValue(fs));break;
case 0xa1: /* POP FS */
SegSet16(fs,Pop_16());break;
case 0xa2:
CPU_CPUID();
break;
case 0xa3: /* BT Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xa4: /* SHLD Ew,Gw,Ib */
RMEwGwOp3(DSHLW,Fetchb());
break;
case 0xa5: /* SHLD Ew,Gw,CL */
RMEwGwOp3(DSHLW,reg_cl);
break;
case 0xa8: /* PUSH GS */
Push_16(SegValue(gs));break;
case 0xa9: /* POP GS */
SegSet16(gs,Pop_16());break;
case 0xab: /* BTS Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw|=mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old | mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xac: /* SHRD Ew,Gw,Ib */
RMEwGwOp3(DSHRW,Fetchb());
break;
case 0xad: /* SHRD Ew,Gw,CL */
RMEwGwOp3(DSHRW,reg_cl);
break;
case 0xaf: /* IMUL Gw,Ew */
RMGwEwOp3(DIMULW,*rmrw);
break;
case 0xb2: /* LSS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SegSet16(ss,LoadMw(eaa+2));
CPU_Cycles++;//Be sure we run another instruction
break;
}
case 0xb3: /* BTR Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw&= ~mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old & ~mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xb4: /* LFS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SegSet16(fs,LoadMw(eaa+2));
break;
}
case 0xb5: /* LGS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SegSet16(gs,LoadMw(eaa+2));
break;
}
case 0xb6: /* MOVZX Gw,Eb */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
else {GetEAa;*rmrw=LoadMb(eaa);}
break;
}
case 0xb7: /* MOVZX Gw,Ew */
case 0xbf: /* MOVSX Gw,Ew */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;}
else {GetEAa;*rmrw=LoadMw(eaa);}
break;
}
case 0xba: /* GRP8 Ew,Ib */
{
GetRM;
if (rm >= 0xc0 ) {
GetEArw;
Bit16u mask=1 << (Fetchb() & 15);
SETFLAGBIT(CF,(*earw & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
*earw|=mask;
break;
case 0x30: /* BTR */
*earw&= ~mask;
break;
case 0x38: /* BTC */
*earw^=mask;
break;
default:
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
}
} else {
GetEAa;Bit16u old=LoadMw(eaa);
Bit16u mask=1 << (Fetchb() & 15);
SETFLAGBIT(CF,(old & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
SaveMw(eaa,old|mask);
break;
case 0x30: /* BTR */
SaveMw(eaa,old & ~mask);
break;
case 0x38: /* BTC */
SaveMw(eaa,old ^ mask);
break;
default:
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbb: /* BTC Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw^=mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbc: /* 0xbc BSF Gw,Ew */
{
GetRMrw;
Bit16u result,value;
if (rm >= 0xc0) { GetEArw; value=*earw; }
else { GetEAa; value=LoadMw(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 0;
while ((value & 0x01)==0) { result++; value>>=1; }
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbd: /* 0xbd BSR Gw,Ew */
{
GetRMrw;
Bit16u result,value;
if (rm >= 0xc0) { GetEArw; value=*earw; }
else { GetEAa; value=LoadMw(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 15; // Operandsize-1
while ((value & 0x8000)==0) { result--; value<<=1; }
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbe: /* MOVSX Gw,Eb */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;}
else {GetEAa;*rmrw=LoadMbs(eaa);}
break;
}
case 0xc8: BSWAP(reg_eax); break;
case 0xc9: BSWAP(reg_ecx); break;
case 0xca: BSWAP(reg_edx); break;
case 0xcb: BSWAP(reg_ebx); break;
case 0xcc: BSWAP(reg_esp); break;
case 0xcd: BSWAP(reg_ebp); break;
case 0xce: BSWAP(reg_esi); break;
case 0xcf: BSWAP(reg_edi); break;
default:
SUBIP(1);
E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb());
}

View file

@ -1,401 +0,0 @@
/*
* 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 SUBIP(a) core_16.ip_lookup-=a
#define SETIP(a) core_16.ip_lookup=SegBase(cs)+a
#define GETIP (Bit16u)(core_16.ip_lookup-SegBase(cs))
#define SAVEIP reg_ip=GETIP
#define LOADIP core_16.ip_lookup=SegBase(cs)+reg_ip
#define LEAVECORE \
SAVEIP; \
FillFlags();
static INLINE void ADDIP(Bit16u add) {
core_16.ip_lookup=SegBase(cs)+((Bit16u)(((Bit16u)(core_16.ip_lookup-SegBase(cs)))+(Bit16u)add));
}
static INLINE void ADDIPFAST(Bit16s blah) {
core_16.ip_lookup+=blah;
}
#define CheckTF() \
if (GETFLAG(TF)) { \
cpudecoder=CPU_Real_16_Slow_Decode_Trap; \
goto decode_end; \
}
#define EXCEPTION(blah) \
{ \
Bit8u new_num=blah; \
core_16.ip_lookup=core_16.ip_start; \
LEAVECORE; \
if (Interrupt(new_num)) { \
if (GETFLAG(TF)) { \
cpudecoder=CPU_Real_16_Slow_Decode_Trap; \
return CBRET_NONE; \
} \
goto decode_start; \
} else return CBRET_NONE; \
}
static INLINE Bit8u Fetchb() {
Bit8u temp=LoadMb(core_16.ip_lookup);
core_16.ip_lookup+=1;
return temp;
}
static INLINE Bit16u Fetchw() {
Bit16u temp=LoadMw(core_16.ip_lookup);
core_16.ip_lookup+=2;
return temp;
}
static INLINE Bit32u Fetchd() {
Bit32u temp=LoadMd(core_16.ip_lookup);
core_16.ip_lookup+=4;
return temp;
}
static INLINE Bit8s Fetchbs() {
return Fetchb();
}
static INLINE Bit16s Fetchws() {
return Fetchw();
}
static INLINE Bit32s Fetchds() {
return Fetchd();
}
static INLINE void Push_16(Bit16u blah) {
reg_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 JumpSIb(blah) \
if (blah) { \
ADDIPFAST(Fetchbs()); \
} else { \
ADDIPFAST(1); \
}
#define JumpSIw(blah) \
if (blah) { \
ADDIPFAST(Fetchws()); \
} else { \
ADDIPFAST(2); \
}
#define SETcc(cc) \
{ \
GetRM; \
if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \
else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \
}
#define NOTDONE \
SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb());
#define NOTDONE66 \
SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb());
#define stringDI \
PhysPt to; \
to=SegBase(es)+reg_di
#define stringSI \
PhysPt from; \
if (core_16.prefixes & PREFIX_SEG) { \
from=(core_16.segbase+reg_si); \
} else { \
from=SegBase(ds)+reg_si; \
}
#include "helpers.h"
#include "table_ea.h"
#include "../modrm.h"
static void Repeat_Normal(bool testz,bool prefix_66) {
PhysPt base_si,base_di;
Bit16s direct;
if (GETFLAG(DF)) direct=-1;
else direct=1;
base_di=SegBase(es);
if (core_16.prefixes & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op");
rep_again:
if (core_16.prefixes & PREFIX_SEG) {
base_si=(core_16.segbase);
} else {
base_si=SegBase(ds);
}
switch (Fetchb()) {
case 0x26: /* ES Prefix */
core_16.segbase=SegBase(es);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x2e: /* CS Prefix */
core_16.segbase=SegBase(cs);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x36: /* SS Prefix */
core_16.segbase=SegBase(ss);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x3e: /* DS Prefix */
core_16.segbase=SegBase(ds);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x64: /* FS Prefix */
core_16.segbase=SegBase(fs);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x65: /* GS Prefix */
core_16.segbase=SegBase(gs);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x66: /* Size Prefix */
prefix_66=!prefix_66;
goto rep_again;
case 0x6c: /* REP INSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di,IO_Read(reg_dx));
reg_di+=direct;
}
break;
case 0x6d: /* REP INSW/D */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0));
SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1));
SaveMb(base_di+reg_di+2,IO_Read(reg_dx+2));
SaveMb(base_di+reg_di+3,IO_Read(reg_dx+3));
reg_di+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0));
SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1));
reg_di+=direct;
}
}
break;
case 0x6e: /* REP OUTSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
IO_Write(reg_dx,LoadMb(base_si+reg_si));
reg_si+=direct;
}
break;
case 0x6f: /* REP OUTSW/D */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0));
IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1));
IO_Write(reg_dx+2,LoadMb(base_si+reg_si+2));
IO_Write(reg_dx+3,LoadMb(base_si+reg_si+3));
reg_si+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0));
IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1));
reg_si+=direct;
}
}
break;
case 0xa4: /* REP MOVSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di,LoadMb(base_si+reg_si));
reg_si+=direct;reg_di+=direct;
}
break;
case 0xa5: /* REP MOVSW/D */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMd(base_di+reg_di,LoadMd(base_si+reg_si));
reg_si+=direct;reg_di+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMw(base_di+reg_di,LoadMw(base_si+reg_si));
reg_si+=direct;reg_di+=direct;
}
}
break;
case 0xa6: /* REP CMPSB */
{
Bit8u op1,op2;
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
for (;CPU_Cycles>0;CPU_Cycles--) {
op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di);
reg_cx--;reg_si+=direct;reg_di+=direct;
if ((op1==op2)!=testz || !reg_cx) { CMPB(op1,op2,LoadRb,0);goto normalexit; }
}
CMPB(op1,op2,LoadRb,0);
}
break;
case 0xa7: /* REP CMPSW */
{
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
if (prefix_66) {
direct*=4;Bit32u op1,op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di);
reg_cx--;reg_si+=direct;reg_di+=direct;
if ((op1==op2)!=testz || !reg_cx) { CMPD(op1,op2,LoadRd,0);goto normalexit; }
}
CMPD(op1,op2,LoadRd,0);
} else {
direct*=2;Bit16u op1,op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di);
reg_cx--,reg_si+=direct;reg_di+=direct;
if ((op1==op2)!=testz || !reg_cx) { CMPW(op1,op2,LoadRw,0);goto normalexit; }
}
CMPW(op1,op2,LoadRw,0);
}
}
break;
case 0xaa: /* REP STOSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di,reg_al);
reg_di+=direct;
}
break;
case 0xab: /* REP STOSW */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMd(base_di+reg_di,reg_eax);
reg_di+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMw(base_di+reg_di,reg_ax);
reg_di+=direct;
}
}
break;
case 0xac: /* REP LODSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
reg_al=LoadMb(base_si+reg_si);
reg_si+=direct;
}
break;
case 0xad: /* REP LODSW */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
reg_eax=LoadMd(base_si+reg_si);
reg_si+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
reg_ax=LoadMw(base_si+reg_si);
reg_si+=direct;
}
}
break;
case 0xae: /* REP SCASB */
{
Bit8u op2;
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
for (;CPU_Cycles>0;CPU_Cycles--) {
op2=LoadMb(base_di+reg_di);
reg_cx--;reg_di+=direct;
if ((reg_al==op2)!=testz || !reg_cx) { CMPB(reg_al,op2,LoadRb,0);goto normalexit; }
}
CMPB(reg_al,op2,LoadRb,0);
}
break;
case 0xaf: /* REP SCASW */
{
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
if (prefix_66) {
direct*=4;Bit32u op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op2=LoadMd(base_di+reg_di);
reg_cx--;reg_di+=direct;
if ((reg_eax==op2)!=testz || !reg_cx) { CMPD(reg_eax,op2,LoadRd,0);goto normalexit; }
}
CMPD(reg_eax,op2,LoadRd,0);
} else {
direct*=2;Bit16u op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op2=LoadMw(base_di+reg_di);
reg_cx--;reg_di+=direct;
if ((reg_ax==op2)!=testz || !reg_cx) { CMPW(reg_ax,op2,LoadRw,0);goto normalexit; }
}
CMPW(reg_ax,op2,LoadRw,0);
}
}
break;
default:
core_16.ip_lookup--;
LOG(LOG_CPU,LOG_ERROR)("Unhandled REP Prefix %X",Fetchb());
goto normalexit;
}
/* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */
core_16.ip_lookup=core_16.ip_start;
normalexit:;
}

View file

@ -1,381 +0,0 @@
/*
* 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 PhysPt (*GetEATable[256])(void);
typedef PhysPt (*EA_LookupHandler)(void);
static GetEATable * lookupEATable;
#define PREFIX_NONE 0x0
#define PREFIX_SEG 0x1
#define PREFIX_ADDR 0x2
#define PREFIX_SEG_ADDR 0x3
/* Gets initialized at the bottem, can't seem to declare forward references */
static GetEATable * EAPrefixTable[4];
#define SegPrefix(blah) \
core_16.segbase=SegBase(blah); \
core_16.prefixes|=PREFIX_SEG; \
lookupEATable=EAPrefixTable[core_16.prefixes]; \
goto restart;
#define SegPrefix_66(blah) \
core_16.segbase=SegBase(blah); \
core_16.prefixes|=PREFIX_SEG; \
lookupEATable=EAPrefixTable[core_16.prefixes]; \
goto restart_66;
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
static PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); }
static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); }
static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); }
static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); }
static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
static PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); }
static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
static GetEATable GetEA_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
};
static PhysPt EA_16_00_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si); }
static PhysPt EA_16_01_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di); }
static PhysPt EA_16_02_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si); }
static PhysPt EA_16_03_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di); }
static PhysPt EA_16_04_s(void) { return core_16.segbase+(Bit16u)(reg_si); }
static PhysPt EA_16_05_s(void) { return core_16.segbase+(Bit16u)(reg_di); }
static PhysPt EA_16_06_s(void) { return core_16.segbase+(Bit16u)(Fetchw()); }
static PhysPt EA_16_07_s(void) { return core_16.segbase+(Bit16u)(reg_bx); }
static PhysPt EA_16_40_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_41_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_42_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_43_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_44_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchbs()); }
static PhysPt EA_16_45_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchbs()); }
static PhysPt EA_16_46_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchbs()); }
static PhysPt EA_16_47_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchbs()); }
static PhysPt EA_16_80_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_81_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_82_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_83_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_84_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchws()); }
static PhysPt EA_16_85_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchws()); }
static PhysPt EA_16_86_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchws()); }
static PhysPt EA_16_87_s(void) { return core_16.segbase+(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
};
static Bit32u SIBZero=0;
static Bit32u * SIBIndex[8]= { &reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&SIBZero,&reg_ebp,&reg_esi,&reg_edi };
INLINE PhysPt Sib(Bitu mode) {
Bit8u sib=Fetchb();
PhysPt base;
switch (sib&7) {
case 0: /* EAX Base */
base=SegBase(ds)+reg_eax;break;
case 1: /* ECX Base */
base=SegBase(ds)+reg_ecx;break;
case 2: /* EDX Base */
base=SegBase(ds)+reg_edx;break;
case 3: /* EBX Base */
base=SegBase(ds)+reg_ebx;break;
case 4: /* ESP Base */
base=SegBase(ss)+reg_esp;break;
case 5: /* #1 Base */
if (!mode) {
base=SegBase(ds)+Fetchd();break;
} else {
base=SegBase(ss)+reg_ebp;break;
}
case 6: /* ESI Base */
base=SegBase(ds)+reg_esi;break;
case 7: /* EDI Base */
base=SegBase(ds)+reg_edi;break;
}
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
return base;
};
static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
static PhysPt EA_32_04_n(void) { return Sib(0);}
static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; }
static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();}
static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
static GetEATable GetEA_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
};
INLINE PhysPt Sib_s(Bitu mode) {
Bit8u sib=Fetchb();
PhysPt base;
switch (sib&7) {
case 0: /* EAX Base */
base=reg_eax;break;
case 1: /* ECX Base */
base=reg_ecx;break;
case 2: /* EDX Base */
base=reg_edx;break;
case 3: /* EBX Base */
base=reg_ebx;break;
case 4: /* ESP Base */
base=reg_esp;break;
case 5: /* #1 Base */
if (!mode) {
base=Fetchd();break;
} else {
base=reg_ebp;break;
}
case 6: /* ESI Base */
base=reg_esi;break;
case 7: /* EDI Base */
base=reg_edi;break;
}
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
return base;
};
static PhysPt EA_32_00_s(void) { return core_16.segbase+(Bit32u)(reg_eax); }
static PhysPt EA_32_01_s(void) { return core_16.segbase+(Bit32u)(reg_ecx); }
static PhysPt EA_32_02_s(void) { return core_16.segbase+(Bit32u)(reg_edx); }
static PhysPt EA_32_03_s(void) { return core_16.segbase+(Bit32u)(reg_ebx); }
static PhysPt EA_32_04_s(void) { return core_16.segbase+(Bit32u)(Sib_s(0));}
static PhysPt EA_32_05_s(void) { return core_16.segbase+(Bit32u)(Fetchd()); }
static PhysPt EA_32_06_s(void) { return core_16.segbase+(Bit32u)(reg_esi); }
static PhysPt EA_32_07_s(void) { return core_16.segbase+(Bit32u)(reg_edi); }
static PhysPt EA_32_40_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchbs()); }
static PhysPt EA_32_41_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchbs()); }
static PhysPt EA_32_42_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchbs()); }
static PhysPt EA_32_43_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchbs()); }
static PhysPt EA_32_44_s(void) { return core_16.segbase+(Bit32u)(Sib_s(1)+Fetchbs());}
static PhysPt EA_32_45_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchbs()); }
static PhysPt EA_32_46_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchbs()); }
static PhysPt EA_32_47_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchbs()); }
static PhysPt EA_32_80_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchds()); }
static PhysPt EA_32_81_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchds()); }
static PhysPt EA_32_82_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchds()); }
static PhysPt EA_32_83_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchds()); }
static PhysPt EA_32_84_s(void) { return core_16.segbase+(Bit32u)(Sib_s(2)+Fetchds());}
static PhysPt EA_32_85_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchds()); }
static PhysPt EA_32_86_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchds()); }
static PhysPt EA_32_87_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchds()); }
static GetEATable GetEA_32_s={
/* 00 */
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
/* 01 */
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
/* 10 */
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static PhysPt GetEADirect_NONE(void) {
PhysPt result=SegBase(ds)+Fetchw();
return result;
}
static PhysPt GetEADirect_SEG(void) {
PhysPt result=core_16.segbase+Fetchw();
return result;
}
static PhysPt GetEADirect_ADDR(void) {
PhysPt result=SegBase(ds)+Fetchd();
return result;
}
static PhysPt GetEADirect_SEG_ADDR(void) {
PhysPt result=core_16.segbase+Fetchd();
return result;
}
static EA_LookupHandler GetEADirect[4]={GetEADirect_NONE,GetEADirect_SEG,GetEADirect_ADDR,GetEADirect_SEG_ADDR};

View file

@ -47,6 +47,8 @@ typedef PhysPt EAPoint;
#define LoadD(reg) reg
#define SaveD(reg,val) reg=val
#include "core_full/loadwrite.h"
#include "core_full/support.h"
#include "core_full/optable.h"
@ -77,7 +79,7 @@ Bits Full_DeCode(void) {
}
EAPoint IPPoint;
LoadIP();
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
while (CPU_Cycles>0) {
#if C_DEBUG
cycle_count++;

View file

@ -225,7 +225,7 @@ l_M_Ed:
break;
case L_FLG:
FillFlags();
inst.op1.d = flags.word;
inst.op1.d = reg_flags;
break;
case L_SEG:
inst.op1.d=SegValue((SegNames)inst.code.extra);
@ -273,7 +273,7 @@ l_M_Ed:
inst.op1.d=4;
break;
case D_IRETw:
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
if (!CPU_IRET(false)) return CBRET_NONE;
if (GETFLAG(IF) && PIC_IRQCheck) {
return CBRET_NONE;
@ -281,7 +281,7 @@ l_M_Ed:
LoadIP();
goto nextopcode;
case D_IRETd:
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
if (!CPU_IRET(true)) return CBRET_NONE;
if (GETFLAG(IF) && PIC_IRQCheck) {
return CBRET_NONE;
@ -379,18 +379,15 @@ l_M_Ed:
goto nextopcode;
case D_STC:
SETFLAGBIT(CF,true);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF();
goto nextopcode;
case D_CLC:
SETFLAGBIT(CF,false);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF();
goto nextopcode;
case D_CMC:
SETFLAGBIT(CF,!get_CF());
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF();
goto nextopcode;
case D_CLD:
SETFLAGBIT(DF,false);

View file

@ -1,60 +1,60 @@
/* Do the actual opcode */
switch (inst.code.op) {
case t_ADDb: case t_ADDw: case t_ADDd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d + lf_var2d;
lflags.type=inst.code.op;
break;
case t_CMPb: case t_CMPw: case t_CMPd:
case t_SUBb: case t_SUBw: case t_SUBd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d - lf_var2d;
lflags.type=inst.code.op;
break;
case t_ORb: case t_ORw: case t_ORd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d | flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d | lf_var2d;
lflags.type=inst.code.op;
break;
case t_XORb: case t_XORw: case t_XORd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d ^ flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d ^ lf_var2d;
lflags.type=inst.code.op;
break;
case t_TESTb: case t_TESTw: case t_TESTd:
case t_ANDb: case t_ANDw: case t_ANDd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d & flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d & lf_var2d;
lflags.type=inst.code.op;
break;
case t_ADCb: case t_ADCw: case t_ADCd:
flags.oldcf=get_CF();
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d + flags.oldcf;
flags.type=inst.code.op;
lflags.oldcf=get_CF();
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf;
lflags.type=inst.code.op;
break;
case t_SBBb: case t_SBBw: case t_SBBd:
flags.oldcf=get_CF();
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d - flags.oldcf;
flags.type=inst.code.op;
lflags.oldcf=get_CF();
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf;
lflags.type=inst.code.op;
break;
case t_INCb: case t_INCw: case t_INCd:
SETFLAGBIT(CF,get_CF());
inst.op1.d=flags.result.d=inst.op1.d+1;
flags.type=inst.code.op;
inst.op1.d=lf_resd=inst.op1.d+1;
lflags.type=inst.code.op;
break;
case t_DECb: case t_DECw: case t_DECd:
SETFLAGBIT(CF,get_CF());
inst.op1.d=flags.result.d=inst.op1.d-1;
flags.type=inst.code.op;
inst.op1.d=lf_resd=inst.op1.d-1;
lflags.type=inst.code.op;
break;
/* Using the instructions.h defines */
case t_ROLb:
@ -149,19 +149,19 @@ switch (inst.code.op) {
}
case t_NEGb:
flags.var1.b=inst.op1.b;
inst.op1.b=flags.result.b=0-inst.op1.b;
flags.type=t_NEGb;
lf_var1b=inst.op1.b;
inst.op1.b=lf_resb=0-inst.op1.b;
lflags.type=t_NEGb;
break;
case t_NEGw:
flags.var1.w=inst.op1.w;
inst.op1.w=flags.result.w=0-inst.op1.w;
flags.type=t_NEGw;
lf_var1w=inst.op1.w;
inst.op1.w=lf_resw=0-inst.op1.w;
lflags.type=t_NEGw;
break;
case t_NEGd:
flags.var1.d=inst.op1.d;
inst.op1.d=flags.result.d=0-inst.op1.d;
flags.type=t_NEGd;
lf_var1d=inst.op1.d;
inst.op1.d=lf_resd=0-inst.op1.d;
lflags.type=t_NEGd;
break;
case O_NOT:

View file

@ -154,7 +154,7 @@ static Bits CPU_Core_Normal_Decode_Trap(void);
static Bits CPU_Core_Normal_Decode(void) {
decode_start:
LOADIP;
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
while (CPU_Cycles>0) {
core.op_start=core.ip_lookup;
core.opcode_index=core.index_default;

View file

@ -245,7 +245,7 @@
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */
@ -271,7 +271,7 @@
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old | mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */
@ -302,7 +302,7 @@
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old & ~mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_W(0xb4) /* LFS Ew */
@ -374,7 +374,7 @@
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_W(0xbb) /* BTC Ew,Gw */
@ -390,7 +390,7 @@
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_W(0xbc) /* BSF Gw,Ew */
@ -407,7 +407,7 @@
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_W(0xbd) /* BSR Gw,Ew */
@ -424,7 +424,7 @@
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_W(0xbe) /* MOVSX Gw,Eb */

View file

@ -351,7 +351,7 @@
}
CASE_D(0x9c) /* PUSHFD */
FillFlags();
Push_32(flags.word);
Push_32(reg_flags);
break;
CASE_D(0x9d) /* POPFD */
SETFLAGSd(Pop_32())
@ -583,13 +583,13 @@
}
case 0x03: /* NEG Ed */
{
flags.type=t_NEGd;
lflags.type=t_NEGd;
if (rm >= 0xc0 ) {
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
*eard=flags.result.d;
GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d;
*eard=lf_resd;
} else {
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
SaveMd(eaa,flags.result.d);
GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d;
SaveMd(eaa,lf_resd);
}
break;
}

View file

@ -172,7 +172,7 @@
GetEAa;Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */
@ -198,7 +198,7 @@
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old | mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
@ -290,8 +290,7 @@
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF();
break;
}
CASE_0F_D(0xbb) /* BTC Ed,Gd */
@ -307,7 +306,7 @@
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
SetTypeCF();
break;
}
CASE_0F_D(0xbc) /* BSF Gd,Ed */
@ -324,7 +323,7 @@
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_D(0xbd) /* BSR Gd,Ed */
@ -341,7 +340,7 @@
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_D(0xbe) /* MOVSX Gd,Eb */

View file

@ -558,7 +558,7 @@
break; /* No waiting here */
CASE_W(0x9c) /* PUSHF */
FillFlags();
Push_16(flags.word);
Push_16(reg_flags);
break;
CASE_W(0x9d) /* POPF */
SETFLAGSw(Pop_16());
@ -577,7 +577,7 @@
break;
CASE_B(0x9f) /* LAHF */
FillFlags();
reg_ah=flags.word&0xff;
reg_ah=reg_flags&0xff;
break;
CASE_B(0xa0) /* MOV AL,Ob */
{
@ -974,8 +974,7 @@
return CBRET_NONE;
CASE_B(0xf5) /* CMC */
SETFLAGBIT(CF,!get_CF());
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF() ;
break;
CASE_B(0xf6) /* GRP3 Eb(,Ib) */
{
@ -996,13 +995,13 @@
}
case 0x03: /* NEG Eb */
{
flags.type=t_NEGb;
lflags.type=t_NEGb;
if (rm >= 0xc0 ) {
GetEArb;flags.var1.b=*earb;flags.result.b=0-flags.var1.b;
*earb=flags.result.b;
GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b;
*earb=lf_resb;
} else {
GetEAa;flags.var1.b=LoadMb(eaa);flags.result.b=0-flags.var1.b;
SaveMb(eaa,flags.result.b);
GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b;
SaveMb(eaa,lf_resb);
}
break;
}
@ -1040,13 +1039,13 @@
}
case 0x03: /* NEG Ew */
{
flags.type=t_NEGw;
lflags.type=t_NEGw;
if (rm >= 0xc0 ) {
GetEArw;flags.var1.w=*earw;flags.result.w=0-flags.var1.w;
*earw=flags.result.w;
GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w;
*earw=lf_resw;
} else {
GetEAa;flags.var1.w=LoadMw(eaa);flags.result.w=0-flags.var1.w;
SaveMw(eaa,flags.result.w);
GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w;
SaveMw(eaa,lf_resw);
}
break;
}
@ -1067,13 +1066,11 @@
}
CASE_B(0xf8) /* CLC */
SETFLAGBIT(CF,false);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF();
break;
CASE_B(0xf9) /* STC */
SETFLAGBIT(CF,true);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
SetTypeCF();
break;
CASE_B(0xfa) /* CLI */
SETFLAGBIT(IF,false);

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cpu.cpp,v 1.35 2003-10-14 23:31:51 harekiet Exp $ */
/* $Id: cpu.cpp,v 1.36 2003-10-26 19:00:38 harekiet Exp $ */
#include <assert.h>
#include "dosbox.h"
@ -32,7 +32,6 @@
#define LOG(X,Y)
#endif
Flag_Info flags;
CPU_Regs cpu_regs;
CPUBlock cpu;
Segments Segs;
@ -92,7 +91,7 @@ PhysPt SelBase(Bitu sel) {
}
void CPU_SetFlags(Bitu word) {
flags.word=(word|2)&~0x28;
reg_flags=(word|2)&~0x28;
}
bool CPU_CheckCodeType(CODE_TYPE type) {
@ -131,7 +130,7 @@ bool Interrupt(Bitu num) {
if (!cpu.pmode) {
/* Save everything on a 16-bit stack */
CPU_Push16(flags.word & 0xffff);
CPU_Push16(reg_flags & 0xffff);
CPU_Push16(SegValue(cs));
CPU_Push16(reg_ip);
SETFLAGBIT(IF,false);
@ -172,11 +171,11 @@ bool Interrupt(Bitu num) {
case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA:
/* Prepare stack for gate to same priviledge */
if (gate.Type() & 0x8) { /* 32-bit Gate */
CPU_Push32(flags.word);
CPU_Push32(reg_flags);
CPU_Push32(SegValue(cs));
CPU_Push32(reg_eip);
} else { /* 16-bit gate */
CPU_Push16(flags.word & 0xffff);
CPU_Push16(reg_flags & 0xffff);
CPU_Push16(SegValue(cs));
CPU_Push16(reg_ip);
}
@ -207,7 +206,7 @@ bool Interrupt(Bitu num) {
bool CPU_Exception(Bitu exception,Bit32u error_code) {
if (!cpu.pmode) { /* RealMode Interrupt */
/* Save everything on a 16-bit stack */
CPU_Push16(flags.word & 0xffff);
CPU_Push16(reg_flags & 0xffff);
CPU_Push16(SegValue(cs));
CPU_Push16(reg_ip);
SETFLAGBIT(IF,false);
@ -256,7 +255,7 @@ bool CPU_IRET(bool use32) {
} else {
offset=CPU_Pop16();
selector=CPU_Pop16();
old_flags=(flags.word & 0xffff0000) | CPU_Pop16();
old_flags=(reg_flags & 0xffff0000) | CPU_Pop16();
}
Bitu rpl=selector & 3;
Descriptor desc;

View file

@ -26,13 +26,14 @@
#include "lazyflags.h"
#include "pic.h"
LazyFlags lflags;
/* CF Carry Flag -- Set on high-order bit carry or borrow; cleared
otherwise.
*/
Bitu get_CF(void) {
switch (flags.type) {
switch (lflags.type) {
case t_UNKNOWN:
case t_CF:
case t_INCb:
@ -48,77 +49,77 @@ Bitu get_CF(void) {
return GETFLAG(CF);
break;
case t_ADDb:
return (flags.result.b<flags.var1.b);
return (lf_resb<lf_var1b);
case t_ADDw:
return (flags.result.w<flags.var1.w);
return (lf_resw<lf_var1w);
case t_ADDd:
return (flags.result.d<flags.var1.d);
return (lf_resd<lf_var1d);
case t_ADCb:
return (flags.result.b < flags.var1.b) || (flags.oldcf && (flags.result.b == flags.var1.b));
return (lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b));
case t_ADCw:
return (flags.result.w < flags.var1.w) || (flags.oldcf && (flags.result.w == flags.var1.w));
return (lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w));
case t_ADCd:
return (flags.result.d < flags.var1.d) || (flags.oldcf && (flags.result.d == flags.var1.d));
return (lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d));
case t_SBBb:
return (flags.var1.b < flags.result.b) || (flags.oldcf && (flags.var2.b==0xff));
return (lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff));
case t_SBBw:
return (flags.var1.w < flags.result.w) || (flags.oldcf && (flags.var2.w==0xffff));
return (lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff));
case t_SBBd:
return (flags.var1.d < flags.result.d) || (flags.oldcf && (flags.var2.d==0xffffffff));
return (lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff));
case t_SUBb:
case t_CMPb:
return (flags.var1.b<flags.var2.b);
return (lf_var1b<lf_var2b);
case t_SUBw:
case t_CMPw:
return (flags.var1.w<flags.var2.w);
return (lf_var1w<lf_var2w);
case t_SUBd:
case t_CMPd:
return (flags.var1.d<flags.var2.d);
return (lf_var1d<lf_var2d);
case t_SHLb:
if (flags.var2.b>8) return false;
else return (flags.var1.b >> (8-flags.var2.b)) & 1;
if (lf_var2b>8) return false;
else return (lf_var1b >> (8-lf_var2b)) & 1;
case t_SHLw:
if (flags.var2.b>16) return false;
else return (flags.var1.w >> (16-flags.var2.b)) & 1;
if (lf_var2b>16) return false;
else return (lf_var1w >> (16-lf_var2b)) & 1;
case t_SHLd:
case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */
case t_DSHLd:
return (flags.var1.d >> (32 - flags.var2.b)) & 1;
return (lf_var1d >> (32 - lf_var2b)) & 1;
case t_RCRb:
case t_SHRb:
return (flags.var1.b >> (flags.var2.b - 1)) & 1;
return (lf_var1b >> (lf_var2b - 1)) & 1;
case t_RCRw:
case t_SHRw:
return (flags.var1.w >> (flags.var2.b - 1)) & 1;
return (lf_var1w >> (lf_var2b - 1)) & 1;
case t_RCRd:
case t_SHRd:
case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */
case t_DSHRd:
return (flags.var1.d >> (flags.var2.b - 1)) & 1;
return (lf_var1d >> (lf_var2b - 1)) & 1;
case t_SARb:
return (((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1;
return (((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1;
case t_SARw:
return (((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1;
return (((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1;
case t_SARd:
return (((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1;
return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1;
case t_NEGb:
return (flags.var1.b!=0);
return (lf_var1b!=0);
case t_NEGw:
return (flags.var1.w!=0);
return (lf_var1w!=0);
case t_NEGd:
return (flags.var1.d!=0);
return (lf_var1d!=0);
case t_ROLb:
return flags.result.b & 1;
return lf_resb & 1;
case t_ROLw:
return flags.result.w & 1;
return lf_resw & 1;
case t_ROLd:
return flags.result.d & 1;
return lf_resd & 1;
case t_RORb:
return (flags.result.b & 0x80)>0;
return (lf_resb & 0x80)>0;
case t_RORw:
return (flags.result.w & 0x8000)>0;
return (lf_resw & 0x8000)>0;
case t_RORd:
return (flags.result.d & 0x80000000)>0;
return (lf_resd & 0x80000000)>0;
case t_ORb:
case t_ORw:
case t_ORd:
@ -135,7 +136,7 @@ Bitu get_CF(void) {
case t_DIV:
return false; /* Unkown */
default:
LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",flags.type);
LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",lflags.type);
}
return 0;
}
@ -145,7 +146,7 @@ Bitu get_CF(void) {
arithmetic.
*/
Bitu get_AF(void) {
Bitu type=flags.type;
Bitu type=lflags.type;
again:
switch (type) {
case t_UNKNOWN:
@ -163,44 +164,44 @@ again:
case t_RCRd:
return GETFLAG(AF);
case t_CF:
type=flags.prev_type;
type=lflags.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;
return (((lf_var1b ^ lf_var2b) ^ lf_resb) & 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;
return (((lf_var1w ^ lf_var2w) ^ lf_resw) & 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;
return (((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0;
case t_INCb:
return (flags.result.b & 0x0f) == 0;
return (lf_resb & 0x0f) == 0;
case t_INCw:
return (flags.result.w & 0x0f) == 0;
return (lf_resw & 0x0f) == 0;
case t_INCd:
return (flags.result.d & 0x0f) == 0;
return (lf_resd & 0x0f) == 0;
case t_DECb:
return (flags.result.b & 0x0f) == 0x0f;
return (lf_resb & 0x0f) == 0x0f;
case t_DECw:
return (flags.result.w & 0x0f) == 0x0f;
return (lf_resw & 0x0f) == 0x0f;
case t_DECd:
return (flags.result.d & 0x0f) == 0x0f;
return (lf_resd & 0x0f) == 0x0f;
case t_NEGb:
return (flags.var1.b & 0x0f) > 0;
return (lf_var1b & 0x0f) > 0;
case t_NEGw:
return (flags.var1.w & 0x0f) > 0;
return (lf_var1w & 0x0f) > 0;
case t_NEGd:
return (flags.var1.d & 0x0f) > 0;
return (lf_var1d & 0x0f) > 0;
case t_ORb:
case t_ORw:
case t_ORd:
@ -230,7 +231,7 @@ again:
case t_MUL:
return false; /* Unkown */
default:
LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",flags.type);
LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",lflags.type);
}
return 0;
}
@ -239,7 +240,7 @@ again:
*/
Bitu get_ZF(void) {
Bitu type=flags.type;
Bitu type=lflags.type;
again:
switch (type) {
case t_UNKNOWN:
@ -257,7 +258,7 @@ again:
case t_RCRd:
return GETFLAG(ZF);
case t_CF:
type=flags.prev_type;
type=lflags.prev_type;
goto again;
case t_ADDb:
case t_ORb:
@ -274,7 +275,7 @@ again:
case t_SHRb:
case t_SARb:
case t_NEGb:
return (flags.result.b==0);
return (lf_resb==0);
case t_ADDw:
case t_ORw:
case t_ADCw:
@ -292,7 +293,7 @@ again:
case t_DSHLw:
case t_DSHRw:
case t_NEGw:
return (flags.result.w==0);
return (lf_resw==0);
case t_ADDd:
case t_ORd:
case t_ADCd:
@ -310,12 +311,12 @@ again:
case t_DSHLd:
case t_DSHRd:
case t_NEGd:
return (flags.result.d==0);
return (lf_resd==0);
case t_DIV:
case t_MUL:
return false; /* Unkown */
default:
LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",flags.type);
LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",lflags.type);
}
return false;
}
@ -323,7 +324,7 @@ again:
positive, 1 if negative).
*/
Bitu get_SF(void) {
Bitu type=flags.type;
Bitu type=lflags.type;
again:
switch (type) {
case t_UNKNOWN:
@ -341,7 +342,7 @@ again:
case t_RCRd:
return GETFLAG(SF);
case t_CF:
type=flags.prev_type;
type=lflags.prev_type;
goto again;
case t_ADDb:
case t_ORb:
@ -358,7 +359,7 @@ again:
case t_SHRb:
case t_SARb:
case t_NEGb:
return (flags.result.b>=0x80);
return (lf_resb>=0x80);
case t_ADDw:
case t_ORw:
case t_ADCw:
@ -376,7 +377,7 @@ again:
case t_DSHLw:
case t_DSHRw:
case t_NEGw:
return (flags.result.w>=0x8000);
return (lf_resw>=0x8000);
case t_ADDd:
case t_ORd:
case t_ADCd:
@ -394,12 +395,12 @@ again:
case t_DSHLd:
case t_DSHRd:
case t_NEGd:
return (flags.result.d>=0x80000000);
return (lf_resd>=0x80000000);
case t_DIV:
case t_MUL:
return false; /* Unkown */
default:
LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",flags.type);
LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",lflags.type);
}
return false;
@ -409,7 +410,7 @@ Bitu get_OF(void) {
Bit16u var1w15, var2w15, resultw15;
Bit32u var1d31, var2d31, resultd31;
Bitu type=flags.type;
Bitu type=lflags.type;
again:
switch (type) {
case t_UNKNOWN:
@ -422,108 +423,108 @@ again:
case t_SARd:
return GETFLAG(OF);
case t_CF:
type=flags.prev_type;
type=lflags.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 (((lf_resb) ^ (lf_var2b)) & ((lf_resb) ^ (lf_var1b)) & 0x80)>0;
var1b7 = lf_var1b & 0x80;
var2b7 = lf_var2b & 0x80;
resultb7 = lf_resb & 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 (((lf_resw) ^ (lf_var2w)) & ((lf_resw) ^ (lf_var1w)) & 0x8000)>0;
var1w15 = lf_var1w & 0x8000;
var2w15 = lf_var2w & 0x8000;
resultw15 = lf_resw & 0x8000;
return (var1w15 == var2w15) && (resultw15 ^ var2w15);
case t_ADDd:
case t_ADCd:
//TODO fix dword Overflow
var1d31 = flags.var1.d & 0x80000000;
var2d31 = flags.var2.d & 0x80000000;
resultd31 = flags.result.d & 0x80000000;
var1d31 = lf_var1d & 0x80000000;
var2d31 = lf_var2d & 0x80000000;
resultd31 = lf_resd & 0x80000000;
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 (((lf_var1b) ^ (lf_var2b)) & ((lf_var1b) ^ (lf_resb)) & 0x80)>0;
var1b7 = lf_var1b & 0x80;
var2b7 = lf_var2b & 0x80;
resultb7 = lf_resb & 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 (((lf_var1w) ^ (lf_var2w)) & ((lf_var1w) ^ (lf_resw)) & 0x8000)>0;
var1w15 = lf_var1w & 0x8000;
var2w15 = lf_var2w & 0x8000;
resultw15 = lf_resw & 0x8000;
return (var1w15 ^ var2w15) && (var1w15 ^ resultw15);
case t_SBBd:
case t_SUBd:
case t_CMPd:
var1d31 = flags.var1.d & 0x80000000;
var2d31 = flags.var2.d & 0x80000000;
resultd31 = flags.result.d & 0x80000000;
var1d31 = lf_var1d & 0x80000000;
var2d31 = lf_var2d & 0x80000000;
resultd31 = lf_resd & 0x80000000;
return (var1d31 ^ var2d31) && (var1d31 ^ resultd31);
case t_INCb:
return (flags.result.b == 0x80);
return (lf_resb == 0x80);
case t_INCw:
return (flags.result.w == 0x8000);
return (lf_resw == 0x8000);
case t_INCd:
return (flags.result.d == 0x80000000);
return (lf_resd == 0x80000000);
case t_DECb:
return (flags.result.b == 0x7f);
return (lf_resb == 0x7f);
case t_DECw:
return (flags.result.w == 0x7fff);
return (lf_resw == 0x7fff);
case t_DECd:
return (flags.result.d == 0x7fffffff);
return (lf_resd == 0x7fffffff);
case t_NEGb:
return (flags.var1.b == 0x80);
return (lf_var1b == 0x80);
case t_NEGw:
return (flags.var1.w == 0x8000);
return (lf_var1w == 0x8000);
case t_NEGd:
return (flags.var1.d == 0x80000000);
return (lf_var1d == 0x80000000);
case t_ROLb:
return ((flags.result.b & 0x80) ^ (flags.result.b & 1 ? 0x80 : 0)) != 0;
return ((lf_resb & 0x80) ^ (lf_resb & 1 ? 0x80 : 0)) != 0;
case t_ROLw:
return ((flags.result.w & 0x8000) ^ (flags.result.w & 1 ? 0x8000 : 0)) != 0;
return ((lf_resw & 0x8000) ^ (lf_resw & 1 ? 0x8000 : 0)) != 0;
case t_ROLd:
return ((flags.result.d & 0x80000000) ^ (flags.result.d & 1 ? 0x80000000 : 0)) != 0;
return ((lf_resd & 0x80000000) ^ (lf_resd & 1 ? 0x80000000 : 0)) != 0;
case t_SHLb:
if (flags.var2.b>9) return false;
return ((flags.result.b & 0x80) ^
((flags.var1.b << (flags.var2.b - 1)) & 0x80)) != 0;
if (lf_var2b>9) return false;
return ((lf_resb & 0x80) ^
((lf_var1b << (lf_var2b - 1)) & 0x80)) != 0;
case t_SHLw:
if (flags.var2.b>17) return false;
return ((flags.result.w & 0x8000) ^
((flags.var1.w << (flags.var2.b - 1)) & 0x8000)) != 0;
if (lf_var2b>17) return false;
return ((lf_resw & 0x8000) ^
((lf_var1w << (lf_var2b - 1)) & 0x8000)) != 0;
case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */
return ((flags.result.w & 0x8000) ^
(((flags.var1.d << (flags.var2.b - 1)) >> 16) & 0x8000)) != 0;
return ((lf_resw & 0x8000) ^
(((lf_var1d << (lf_var2b - 1)) >> 16) & 0x8000)) != 0;
case t_SHLd:
case t_DSHLd:
return ((flags.result.d & 0x80000000) ^
((flags.var1.d << (flags.var2.b - 1)) & 0x80000000)) != 0;
return ((lf_resd & 0x80000000) ^
((lf_var1d << (lf_var2b - 1)) & 0x80000000)) != 0;
case t_RORb:
case t_RCRb:
return ((flags.result.b ^ (flags.result.b << 1)) & 0x80) > 0;
return ((lf_resb ^ (lf_resb << 1)) & 0x80) > 0;
case t_RORw:
case t_RCRw:
case t_DSHRw:
return ((flags.result.w ^ (flags.result.w << 1)) & 0x8000) > 0;
return ((lf_resw ^ (lf_resw << 1)) & 0x8000) > 0;
case t_RORd:
case t_RCRd:
case t_DSHRd:
return ((flags.result.d ^ (flags.result.d << 1)) & 0x80000000) > 0;
return ((lf_resd ^ (lf_resd << 1)) & 0x80000000) > 0;
case t_SHRb:
return (flags.result.b >= 0x40);
return (lf_resb >= 0x40);
case t_SHRw:
return (flags.result.w >= 0x4000);
return (lf_resw >= 0x4000);
case t_SHRd:
return (flags.result.d >= 0x40000000);
return (lf_resd >= 0x40000000);
case t_ORb:
case t_ORw:
case t_ORd:
@ -540,7 +541,7 @@ again:
case t_DIV:
return false; /* Unkown */
default:
LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",flags.type);
LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",lflags.type);
}
return false;
}
@ -565,89 +566,89 @@ bool parity_lookup[256] = {
};
Bitu get_PF(void) {
switch (flags.type) {
switch (lflags.type) {
case t_UNKNOWN:
return GETFLAG(PF);
default:
return (parity_lookup[flags.result.b]);;
return (parity_lookup[lf_resb]);;
};
return false;
}
void FillFlags(void) {
Bitu new_word=(flags.word & ~FLAG_MASK);
Bitu new_word=(reg_flags & ~FLAG_MASK);
if (get_CF()) new_word|=FLAG_CF;
if (get_PF()) new_word|=FLAG_PF;
if (get_AF()) new_word|=FLAG_AF;
if (get_ZF()) new_word|=FLAG_ZF;
if (get_SF()) new_word|=FLAG_SF;
if (get_OF()) new_word|=FLAG_OF;
flags.word=new_word;
flags.type=t_UNKNOWN;
reg_flags=new_word;
lflags.type=t_UNKNOWN;
}
#if 0
Bitu get_Flags(void) {
Bitu new_flags=0;
switch (flags.type) {
switch (lflags.type) {
case t_ADDb:
SET_FLAG(FLAG_CF,(flags.result.b<flags.var1.b));
SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_resb<lf_var1b));
SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0);
break;
case t_ADDw:
SET_FLAG(FLAG_CF,(flags.result.w<flags.var1.w));
SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_resw<lf_var1w));
SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0);
break;
case t_ADDd:
SET_FLAG(FLAG_CF,(flags.result.d<flags.var1.d));
SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_resd<lf_var1d));
SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0);
break;
case t_ADCb:
SET_FLAG(FLAG_CF,(flags.result.b < flags.var1.b) || (flags.oldcf && (flags.result.b == flags.var1.b)));
SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b)));
SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0);
break;
case t_ADCw:
SET_FLAG(FLAG_CF,(flags.result.w < flags.var1.w) || (flags.oldcf && (flags.result.w == flags.var1.w)));
SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w)));
SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0);
break;
case t_ADCd:
SET_FLAG(FLAG_CF,(flags.result.d < flags.var1.d) || (flags.oldcf && (flags.result.d == flags.var1.d)));
SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d)));
SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0);
break;
case t_SBBb:
SET_FLAG(FLAG_CF,(flags.var1.b < flags.result.b) || (flags.oldcf && (flags.var2.b==0xff)));
SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff)));
SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0);
break;
case t_SBBw:
SET_FLAG(FLAG_CF,(flags.var1.w < flags.result.w) || (flags.oldcf && (flags.var2.w==0xffff)));
SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff)));
SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0);
break;
case t_SBBd:
SET_FLAG(FLAG_CF,(flags.var1.d < flags.result.d) || (flags.oldcf && (flags.var2.d==0xffffffff)));
SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff)));
SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0);
break;
case t_SUBb:
case t_CMPb:
SET_FLAG(FLAG_CF,(flags.var1.b<flags.var2.b));
SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_var1b<lf_var2b));
SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0);
break;
case t_SUBw:
case t_CMPw:
SET_FLAG(FLAG_CF,(flags.var1.w<flags.var2.w));
SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_var1w<lf_var2w));
SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0);
break;
case t_SUBd:
case t_CMPd:
SET_FLAG(FLAG_CF,(flags.var1.d<flags.var2.d));
SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0);
SET_FLAG(FLAG_CF,(lf_var1d<lf_var2d));
SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0);
break;
@ -688,122 +689,122 @@ Bitu get_Flags(void) {
case t_SHLb:
if (flags.var2.b>8) SET_FLAG(FLAG_CF,false);
else SET_FLAG(FLAG_CF,(flags.var1.b >> (8-flags.var2.b)) & 1);
if (lf_var2b>8) SET_FLAG(FLAG_CF,false);
else SET_FLAG(FLAG_CF,(lf_var1b >> (8-lf_var2b)) & 1);
break;
case t_SHLw:
if (flags.var2.b>16) SET_FLAG(FLAG_CF,false);
else SET_FLAG(FLAG_CF,(flags.var1.w >> (16-flags.var2.b)) & 1);
if (lf_var2b>16) SET_FLAG(FLAG_CF,false);
else SET_FLAG(FLAG_CF,(lf_var1w >> (16-lf_var2b)) & 1);
break;
case t_SHLd:
SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1);
break;
case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */
SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1);
break;
case t_DSHLd:
SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1);
break;
case t_SHRb:
SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1);
break;
case t_SHRw:
SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1);
break;
case t_SHRd:
SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1);
break;
case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */
SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1);
break;
case t_DSHRd:
SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1);
break;
case t_SARb:
SET_FLAG(FLAG_CF,(((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1);
break;
case t_SARw:
SET_FLAG(FLAG_CF,(((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1);
break;
case t_SARd:
SET_FLAG(FLAG_CF,(((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1);
break;
case t_ROLb:
SET_FLAG(FLAG_CF,flags.result.b & 1);
SET_FLAG(FLAG_CF,lf_resb & 1);
break;
case t_ROLw:
SET_FLAG(FLAG_CF,flags.result.w & 1);
SET_FLAG(FLAG_CF,lf_resw & 1);
break;
case t_ROLd:
SET_FLAG(FLAG_CF,flags.result.d & 1);
SET_FLAG(FLAG_CF,lf_resd & 1);
break;
case t_RORb:
SET_FLAG(FLAG_CF,(flags.result.b & 0x80)>0);
SET_FLAG(FLAG_CF,(lf_resb & 0x80)>0);
break;
case t_RORw:
SET_FLAG(FLAG_CF,(flags.result.w & 0x8000)>0);
SET_FLAG(FLAG_CF,(lf_resw & 0x8000)>0);
break;
case t_RORd:
SET_FLAG(FLAG_CF,(flags.result.d & 0x80000000)>0);
SET_FLAG(FLAG_CF,(lf_resd & 0x80000000)>0);
break;
case t_RCRb:
SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1);
break;
case t_RCRw:
SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1);
break;
case t_RCRd:
SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1);
SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1);
break;
case t_INCb:
SET_FLAG(FLAG_OF,(flags.result.b == 0x80));
SET_FLAG(FLAG_AF,((flags.result.b & 0x0f) == 0));
SET_FLAG(FLAG_OF,(lf_resb == 0x80));
SET_FLAG(FLAG_AF,((lf_resb & 0x0f) == 0));
break;
case t_INCw:
SET_FLAG(FLAG_OF,(flags.result.w == 0x8000));
SET_FLAG(FLAG_AF,((flags.result.w & 0x0f) == 0));
SET_FLAG(FLAG_OF,(lf_resw == 0x8000));
SET_FLAG(FLAG_AF,((lf_resw & 0x0f) == 0));
break;
case t_INCd:
SET_FLAG(FLAG_OF,(flags.result.d == 0x80000000));
SET_FLAG(FLAG_AF,((flags.result.d & 0x0f) == 0));
SET_FLAG(FLAG_OF,(lf_resd == 0x80000000));
SET_FLAG(FLAG_AF,((lf_resd & 0x0f) == 0));
break;
case t_DECb:
SET_FLAG(FLAG_OF,(flags.result.b == 0x7f));
SET_FLAG(FLAG_OF,(lf_resb == 0x7f));
break;
case t_DECw:
SET_FLAG(FLAG_OF,(flags.result.w == 0x7fff));
SET_FLAG(FLAG_OF,(lf_resw == 0x7fff));
break;
case t_DECd:
SET_FLAG(FLAG_OF,(flags.result.d == 0x7fffffff));
SET_FLAG(FLAG_OF,(lf_resd == 0x7fffffff));
break;
case t_NEGb:
SET_FLAG(FLAG_CF,(flags.var1.b!=0));
SET_FLAG(FLAG_CF,(lf_var1b!=0));
break;
case t_NEGw:
SET_FLAG(FLAG_CF,(flags.var1.w!=0));
SET_FLAG(FLAG_CF,(lf_var1w!=0));
break;
case t_NEGd:
SET_FLAG(FLAG_CF,(flags.var1.d!=0));
SET_FLAG(FLAG_CF,(lf_var1d!=0));
break;
@ -811,10 +812,10 @@ Bitu get_Flags(void) {
SET_FLAG(FLAG_CF,false); /* Unkown */
break;
default:
LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",flags.type);
LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type);
return 0;
}
flags.word=new_flags;
lflags.word=new_flags;
return 0;
}

View file

@ -20,265 +20,265 @@
/* 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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b+lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lflags.oldcf=get_CF(); \
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b+lf_var2b+lflags.oldcf; \
save(op1,lf_resb); \
lflags.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;
lflags.oldcf=get_CF(); \
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \
save(op1,lf_resb); \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b-lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b | lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b ^ lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b & lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b-lf_var2b; \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b & lf_var2b; \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w+lf_var2w; \
save(op1,lf_resw); \
lflags.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;
lflags.oldcf=get_CF(); \
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \
save(op1,lf_resw); \
lflags.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;
lflags.oldcf=get_CF(); \
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \
save(op1,lf_resw); \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w-lf_var2w; \
save(op1,lf_resw); \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w | lf_var2w; \
save(op1,lf_resw); \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w ^ lf_var2w; \
save(op1,lf_resw); \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w & lf_var2w; \
save(op1,lf_resw); \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w-lf_var2w; \
lflags.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;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w & lf_var2w; \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d+lf_var2d; \
save(op1,lf_resd); \
lflags.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;
lflags.oldcf=get_CF(); \
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \
save(op1,lf_resd); \
lflags.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;
lflags.oldcf=get_CF(); \
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \
save(op1,lf_resd); \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d-lf_var2d; \
save(op1,lf_resd); \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d | lf_var2d; \
save(op1,lf_resd); \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d ^ lf_var2d; \
save(op1,lf_resd); \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d & lf_var2d; \
save(op1,lf_resd); \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d-lf_var2d; \
lflags.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;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d & lf_var2d; \
lflags.type=t_TESTd;
#define INCB(op1,load,save) \
LoadCF;flags.result.b=load(op1)+1; \
save(op1,flags.result.b); \
flags.type=t_INCb; \
LoadCF;lf_resb=load(op1)+1; \
save(op1,lf_resb); \
lflags.type=t_INCb; \
#define INCW(op1,load,save) \
LoadCF;flags.result.w=load(op1)+1; \
save(op1,flags.result.w); \
flags.type=t_INCw;
LoadCF;lf_resw=load(op1)+1; \
save(op1,lf_resw); \
lflags.type=t_INCw;
#define INCD(op1,load,save) \
LoadCF;flags.result.d=load(op1)+1; \
save(op1,flags.result.d); \
flags.type=t_INCd;
LoadCF;lf_resd=load(op1)+1; \
save(op1,lf_resd); \
lflags.type=t_INCd;
#define DECB(op1,load,save) \
LoadCF;flags.result.b=load(op1)-1; \
save(op1,flags.result.b); \
flags.type=t_DECb;
LoadCF;lf_resb=load(op1)-1; \
save(op1,lf_resb); \
lflags.type=t_DECb;
#define DECW(op1,load,save) \
LoadCF;flags.result.w=load(op1)-1; \
save(op1,flags.result.w); \
flags.type=t_DECw;
LoadCF;lf_resw=load(op1)-1; \
save(op1,lf_resw); \
lflags.type=t_DECw;
#define DECD(op1,load,save) \
LoadCF;flags.result.d=load(op1)-1; \
save(op1,flags.result.d); \
flags.type=t_DECd;
LoadCF;lf_resd=load(op1)-1; \
save(op1,lf_resd); \
lflags.type=t_DECd;
#define ROLB(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
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; \
lf_var1b=load(op1); \
lf_var2b=op2&0x07; \
lf_resb=(lf_var1b << lf_var2b) | \
(lf_var1b >> (8-lf_var2b)); \
save(op1,lf_resb); \
lflags.type=t_ROLb; \
#define ROLW(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
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; \
lf_var1w=load(op1); \
lf_var2b=op2&0x0F; \
lf_resw=(lf_var1w << lf_var2b) | \
(lf_var1w >> (16-lf_var2b)); \
save(op1,lf_resw); \
lflags.type=t_ROLw; \
#define ROLD(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
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; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lf_resd=(lf_var1d << lf_var2b) | \
(lf_var1d >> (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_ROLd; \
#define RORB(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
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; \
lf_var1b=load(op1); \
lf_var2b=op2&0x07; \
lf_resb=(lf_var1b >> lf_var2b) | \
(lf_var1b << (8-lf_var2b)); \
save(op1,lf_resb); \
lflags.type=t_RORb; \
#define RORW(op1,op2,load,save) \
if (op2&0x0F) { \
LoadZF;LoadSF;LoadAF; \
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; \
lf_var1w=load(op1); \
lf_var2b=op2&0x0F; \
lf_resw=(lf_var1w >> lf_var2b) | \
(lf_var1w << (16-lf_var2b)); \
save(op1,lf_resw); \
lflags.type=t_RORw; \
}
#define RORD(op1,op2,load,save) \
if (op2) { \
LoadZF;LoadSF;LoadAF; \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
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; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lf_resd=(lf_var1d >> lf_var2b) | \
(lf_var1d << (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_RORd; \
}
@ -286,176 +286,176 @@
if (op2%9) { \
LoadZF;LoadSF;LoadAF; \
Bit8u cf=get_CF(); \
flags.var1.b=load(op1); \
flags.var2.b=op2%9; \
flags.type=t_RCLb; \
flags.result.b=(flags.var1.b << flags.var2.b) | \
(cf << (flags.var2.b-1)) | \
(flags.var1.b >> (9-flags.var2.b)); \
SETFLAGBIT(CF,((flags.var1.b >> (8-flags.var2.b)) & 1)); \
SETFLAGBIT(OF,(flags.var1.b ^ flags.result.b) & 0x80); \
save(op1,flags.result.b); \
lf_var1b=load(op1); \
lf_var2b=op2%9; \
lflags.type=t_RCLb; \
lf_resb=(lf_var1b << lf_var2b) | \
(cf << (lf_var2b-1)) | \
(lf_var1b >> (9-lf_var2b)); \
SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \
SETFLAGBIT(OF,(lf_var1b ^ lf_resb) & 0x80); \
save(op1,lf_resb); \
}
#define RCLW(op1,op2,load,save) \
if (op2%17) { \
LoadZF;LoadSF;LoadAF; \
Bit16u cf=get_CF(); \
flags.var1.w=load(op1); \
flags.var2.b=op2%17; \
flags.type=t_RCLw; \
flags.result.w=(flags.var1.w << flags.var2.b) | \
(cf << (flags.var2.b-1)) | \
(flags.var1.w >> (17-flags.var2.b)); \
SETFLAGBIT(CF,((flags.var1.w >> (16-flags.var2.b)) & 1)); \
SETFLAGBIT(OF,(flags.var1.w ^ flags.result.w) & 0x8000); \
save(op1,flags.result.w); \
lf_var1w=load(op1); \
lf_var2b=op2%17; \
lflags.type=t_RCLw; \
lf_resw=(lf_var1w << lf_var2b) | \
(cf << (lf_var2b-1)) | \
(lf_var1w >> (17-lf_var2b)); \
SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \
SETFLAGBIT(OF,(lf_var1w ^ lf_resw) & 0x8000); \
save(op1,lf_resw); \
}
#define RCLD(op1,op2,load,save) \
if (op2) { \
LoadZF;LoadSF;LoadAF; \
Bit32u cf=get_CF(); \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
flags.type=t_RCLd; \
if (flags.var2.b==1) { \
flags.result.d=(flags.var1.d << 1) | cf; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lflags.type=t_RCLd; \
if (lf_var2b==1) { \
lf_resd=(lf_var1d << 1) | cf; \
} else { \
flags.result.d=(flags.var1.d << flags.var2.b) | \
(cf << (flags.var2.b-1)) | \
(flags.var1.d >> (33-flags.var2.b)); \
lf_resd=(lf_var1d << lf_var2b) | \
(cf << (lf_var2b-1)) | \
(lf_var1d >> (33-lf_var2b)); \
} \
SETFLAGBIT(CF,((flags.var1.d >> (32-flags.var2.b)) & 1)); \
SETFLAGBIT(OF,(flags.var1.d ^ flags.result.d) & 0x80000000); \
save(op1,flags.result.d); \
SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \
SETFLAGBIT(OF,(lf_var1d ^ lf_resd) & 0x80000000); \
save(op1,lf_resd); \
}
#define RCRB(op1,op2,load,save) \
if (op2%9) { \
LoadZF;LoadSF;LoadAF; \
Bit8u cf=get_CF(); \
flags.var1.b=load(op1); \
flags.var2.b=op2%9; \
flags.type=t_RCRb; \
flags.result.b=(flags.var1.b >> flags.var2.b) | \
(cf << (8-flags.var2.b)) | \
(flags.var1.b << (9-flags.var2.b)); \
save(op1,flags.result.b); \
lf_var1b=load(op1); \
lf_var2b=op2%9; \
lflags.type=t_RCRb; \
lf_resb=(lf_var1b >> lf_var2b) | \
(cf << (8-lf_var2b)) | \
(lf_var1b << (9-lf_var2b)); \
save(op1,lf_resb); \
}
#define RCRW(op1,op2,load,save) \
if (op2%17) { \
LoadZF;LoadSF;LoadAF; \
Bit16u cf=get_CF(); \
flags.var1.w=load(op1); \
flags.var2.b=op2%17; \
flags.type=t_RCRw; \
flags.result.w=(flags.var1.w >> flags.var2.b) | \
(cf << (16-flags.var2.b)) | \
(flags.var1.w << (17-flags.var2.b)); \
save(op1,flags.result.w); \
lf_var1w=load(op1); \
lf_var2b=op2%17; \
lflags.type=t_RCRw; \
lf_resw=(lf_var1w >> lf_var2b) | \
(cf << (16-lf_var2b)) | \
(lf_var1w << (17-lf_var2b)); \
save(op1,lf_resw); \
}
#define RCRD(op1,op2,load,save) \
if (op2) { \
LoadZF;LoadSF;LoadAF; \
Bit32u cf=get_CF(); \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
flags.type=t_RCRd; \
if (flags.var2.b==1) { \
flags.result.d=flags.var1.d >> 1 | cf << 31; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lflags.type=t_RCRd; \
if (lf_var2b==1) { \
lf_resd=lf_var1d >> 1 | cf << 31; \
} else { \
flags.result.d=(flags.var1.d >> flags.var2.b) | \
(cf << (32-flags.var2.b)) | \
(flags.var1.d << (33-flags.var2.b)); \
lf_resd=(lf_var1d >> lf_var2b) | \
(cf << (32-lf_var2b)) | \
(lf_var1d << (33-lf_var2b)); \
} \
save(op1,flags.result.d); \
save(op1,lf_resd); \
}
#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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b << lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lf_var1w=load(op1);lf_var2b=op2 ; \
lf_resw=lf_var1w << lf_var2b; \
save(op1,lf_resw); \
lflags.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;
lf_var1d=load(op1);lf_var2b=op2; \
lf_resd=lf_var1d << lf_var2b; \
save(op1,lf_resd); \
lflags.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;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b >> lf_var2b; \
save(op1,lf_resb); \
lflags.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;
lf_var1w=load(op1);lf_var2b=op2; \
lf_resw=lf_var1w >> lf_var2b; \
save(op1,lf_resw); \
lflags.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;
lf_var1d=load(op1);lf_var2b=op2; \
lf_resd=lf_var1d >> lf_var2b; \
save(op1,lf_resd); \
lflags.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)); \
lf_var1b=load(op1);lf_var2b=op2; \
if (lf_var2b>8) lf_var2b=8; \
if (lf_var1b & 0x80) { \
lf_resb=(lf_var1b >> lf_var2b)| \
(0xff << (8 - lf_var2b)); \
} else { \
flags.result.b=flags.var1.b >> flags.var2.b; \
lf_resb=lf_var1b >> lf_var2b; \
} \
save(op1,flags.result.b); \
flags.type=t_SARb;
save(op1,lf_resb); \
lflags.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)); \
lf_var1w=load(op1);lf_var2b=op2; \
if (lf_var2b>16) lf_var2b=16; \
if (lf_var1w & 0x8000) { \
lf_resw=(lf_var1w >> lf_var2b)| \
(0xffff << (16 - lf_var2b)); \
} else { \
flags.result.w=flags.var1.w >> flags.var2.b; \
lf_resw=lf_var1w >> lf_var2b; \
} \
save(op1,flags.result.w); \
flags.type=t_SARw;
save(op1,lf_resw); \
lflags.type=t_SARw;
#define SARD(op1,op2,load,save) \
if (!op2) break; \
flags.var2.b=op2;flags.var1.d=load(op1); \
if (flags.var1.d & 0x80000000) { \
flags.result.d=(flags.var1.d >> flags.var2.b)| \
(0xffffffff << (32 - flags.var2.b)); \
lf_var2b=op2;lf_var1d=load(op1); \
if (lf_var1d & 0x80000000) { \
lf_resd=(lf_var1d >> lf_var2b)| \
(0xffffffff << (32 - lf_var2b)); \
} else { \
flags.result.d=flags.var1.d >> flags.var2.b; \
lf_resd=lf_var1d >> lf_var2b; \
} \
save(op1,flags.result.d); \
flags.type=t_SARd;
save(op1,lf_resd); \
lflags.type=t_SARd;
@ -474,7 +474,7 @@
} \
SETFLAGBIT(SF,(reg_al&0x80)); \
SETFLAGBIT(ZF,(reg_al==0)); \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define DAS() \
@ -490,7 +490,7 @@
} else { \
SETFLAGBIT(CF,false); \
} \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define AAA() \
@ -505,7 +505,7 @@
SETFLAGBIT(CF,false); \
} \
reg_al &= 0x0F; \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define AAS() \
if (((reg_al & 0x0f)>9) || get_AF()) { \
@ -519,14 +519,14 @@
SETFLAGBIT(CF,false); \
} \
reg_al &= 0x0F; \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define AAM(op1) \
{ \
Bit8u BLAH=op1; \
reg_ah=reg_al / BLAH; \
reg_al=reg_al % BLAH; \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
SETFLAGBIT(SF,(reg_al & 0x80)); \
SETFLAGBIT(ZF,(reg_al == 0)); \
SETFLAGBIT(PF,parity_lookup[reg_al]); \
@ -547,11 +547,11 @@
SETFLAGBIT(SF,reg_al >= 0x80); \
SETFLAGBIT(ZF,reg_al == 0); \
SETFLAGBIT(PF,parity_lookup[reg_al]); \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
}
#define MULB(op1,load,save) \
flags.type=t_MUL; \
lflags.type=t_MUL; \
reg_ax=reg_al*load(op1); \
if (reg_ax & 0xff00) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
@ -564,7 +564,7 @@
Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \
reg_ax=(Bit16u)(tempu); \
reg_dx=(Bit16u)(tempu >> 16); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if (reg_dx) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
} else { \
@ -577,7 +577,7 @@
Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \
reg_eax=(Bit32u)(tempu); \
reg_edx=(Bit32u)(tempu >> 32); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if (reg_edx) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
} else { \
@ -654,7 +654,7 @@
#define IMULB(op1,load,save) \
{ \
flags.type=t_MUL; \
lflags.type=t_MUL; \
reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \
if ((reg_ax & 0xff80)==0xff80 || \
(reg_ax & 0xff80)==0x0000) { \
@ -670,7 +670,7 @@
Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \
reg_ax=(Bit16s)(temps); \
reg_dx=(Bit16s)(temps >> 16); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if (((temps & 0xffff8000)==0xffff8000 || \
(temps & 0xffff8000)==0x0000)) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
@ -685,7 +685,7 @@
((Bit64s)((Bit32s)(load(op1)))); \
reg_eax=(Bit32u)(temps); \
reg_edx=(Bit32u)(temps >> 32); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if ((reg_edx==0xffffffff) && \
(reg_eax & 0x80000000) ) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
@ -702,7 +702,7 @@
Bits res; \
res=((Bit16s)op2) * ((Bit16s)op3); \
save(op1,res & 0xffff); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if ((res> -32768) && (res<32767)) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
} else { \
@ -714,7 +714,7 @@
{ \
Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \
save(op1,(Bit32s)res); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if ((res>-((Bit64s)(2147483647)+1)) && \
(res<(Bit64s)2147483647)) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
@ -827,39 +827,39 @@
#define DSHLW(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=(load(op1)<<16)|op2; \
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;
lf_var2b=val;lf_var1d=(load(op1)<<16)|op2; \
Bit32u tempd=lf_var1d << lf_var2b; \
if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); \
lf_resw=(Bit16u)(tempd >> 16); \
save(op1,lf_resw); \
lflags.type=t_DSHLw;
#define DSHLD(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=load(op1); \
flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_DSHLd;
lf_var2b=val;lf_var1d=load(op1); \
lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_DSHLd;
/* double-precision shift right has high bits in second argument */
#define DSHRW(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=(op2<<16)|load(op1); \
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;
lf_var2b=val;lf_var1d=(op2<<16)|load(op1); \
Bit32u tempd=lf_var1d >> lf_var2b; \
if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); \
lf_resw=(Bit16u)(tempd); \
save(op1,lf_resw); \
lflags.type=t_DSHRw;
#define DSHRD(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=load(op1); \
flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_DSHRd;
lf_var2b=val;lf_var1d=load(op1); \
lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_DSHRd;
#define BSWAP(op1) \
op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000);

View file

@ -16,6 +16,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined __LAZYFLAGS_H
#define __LAZYFLAG_H
//Flag Handling
Bitu get_CF(void);
Bitu get_AF(void);
@ -26,22 +29,48 @@ Bitu get_PF(void);
void FillFlags(void);
#include "regs.h"
struct LazyFlags {
GenReg32 var1,var2,res;
Bitu type;
Bitu prev_type;
Bitu oldcf;
};
extern LazyFlags lfags;
#define lf_var1b lflags.var1.byte[BL_INDEX]
#define lf_var2b lflags.var2.byte[BL_INDEX]
#define lf_resb lflags.res.byte[BL_INDEX]
#define lf_var1w lflags.var1.word[W_INDEX]
#define lf_var2w lflags.var2.word[W_INDEX]
#define lf_resw lflags.res.word[W_INDEX]
#define lf_var1d lflags.var1.dword[DW_INDEX]
#define lf_var2d lflags.var2.dword[DW_INDEX]
#define lf_resd lflags.res.dword[DW_INDEX]
extern LazyFlags lflags;
#define SETFLAGSb(FLAGB) \
{ \
SETFLAGBIT(OF,get_OF()); \
flags.type=t_UNKNOWN; \
CPU_SetFlags((flags.word&0xffffff00)|((FLAGB) & 0xff)); \
lflags.type=t_UNKNOWN; \
CPU_SetFlags((reg_flags&0xffffff00)|((FLAGB) & 0xff)); \
}
#define SETFLAGSw(FLAGW) \
{ \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
CPU_SetFlagsw(FLAGW); \
}
#define SETFLAGSd(FLAGD) \
{ \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
CPU_SetFlags(FLAGD); \
}
@ -82,3 +111,11 @@ enum {
t_LASTFLAG
};
INLINE void SetTypeCF(void) {
if (lflags.type!=t_CF) {
lflags.prev_type=lflags.type;
lflags.type=t_CF;
}
}
#endif