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:
parent
e92e17addd
commit
66df37b533
21 changed files with 614 additions and 3833 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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());
|
||||
}
|
|
@ -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());
|
||||
}
|
|
@ -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:;
|
||||
}
|
||||
|
|
@ -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]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi };
|
||||
|
||||
INLINE PhysPt Sib(Bitu mode) {
|
||||
Bit8u sib=Fetchb();
|
||||
PhysPt base;
|
||||
switch (sib&7) {
|
||||
case 0: /* EAX Base */
|
||||
base=SegBase(ds)+reg_eax;break;
|
||||
case 1: /* ECX Base */
|
||||
base=SegBase(ds)+reg_ecx;break;
|
||||
case 2: /* EDX Base */
|
||||
base=SegBase(ds)+reg_edx;break;
|
||||
case 3: /* EBX Base */
|
||||
base=SegBase(ds)+reg_ebx;break;
|
||||
case 4: /* ESP Base */
|
||||
base=SegBase(ss)+reg_esp;break;
|
||||
case 5: /* #1 Base */
|
||||
if (!mode) {
|
||||
base=SegBase(ds)+Fetchd();break;
|
||||
} else {
|
||||
base=SegBase(ss)+reg_ebp;break;
|
||||
}
|
||||
case 6: /* ESI Base */
|
||||
base=SegBase(ds)+reg_esi;break;
|
||||
case 7: /* EDI Base */
|
||||
base=SegBase(ds)+reg_edi;break;
|
||||
}
|
||||
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
|
||||
return base;
|
||||
};
|
||||
|
||||
|
||||
static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
|
||||
static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
|
||||
static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
|
||||
static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
|
||||
static PhysPt EA_32_04_n(void) { return Sib(0);}
|
||||
static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
|
||||
static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; }
|
||||
static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
|
||||
|
||||
static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
|
||||
static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
|
||||
static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
|
||||
static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
|
||||
static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
|
||||
static PhysPt EA_32_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};
|
|
@ -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++;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue