Rewrites for new flags
Moved functions into instructions.h Added some new opcodes Removed start.h and stop.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@916
This commit is contained in:
parent
72b321a4cf
commit
3874c20563
9 changed files with 298 additions and 546 deletions
|
@ -24,6 +24,7 @@
|
|||
GetRM; \
|
||||
GetEAa;
|
||||
|
||||
|
||||
#define RMEbGb(inst) \
|
||||
{ \
|
||||
GetRMrb; \
|
||||
|
@ -38,6 +39,12 @@
|
|||
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; \
|
||||
|
@ -45,6 +52,13 @@
|
|||
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; \
|
||||
|
@ -52,6 +66,19 @@
|
|||
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; \
|
||||
|
@ -59,6 +86,14 @@
|
|||
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; \
|
||||
|
@ -66,6 +101,28 @@
|
|||
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)}
|
||||
|
||||
|
|
|
@ -99,23 +99,7 @@ restart:
|
|||
case 0x26: /* SEG ES: */
|
||||
SegPrefix(es);break;
|
||||
case 0x27: /* DAA */
|
||||
if (((reg_al & 0x0F)>0x09) || get_AF()) {
|
||||
reg_al+=0x06;
|
||||
flags.af=true;
|
||||
} else {
|
||||
flags.af=false;
|
||||
}
|
||||
flags.cf=get_CF();
|
||||
if ((reg_al > 0x9F) || flags.cf) {
|
||||
reg_al+=0x60;
|
||||
flags.cf=true;
|
||||
} else {
|
||||
flags.cf=false;
|
||||
}
|
||||
flags.sf=(reg_al>>7)>0;
|
||||
flags.zf=(reg_al==0);
|
||||
//TODO Maybe parity
|
||||
flags.type=t_UNKNOWN;
|
||||
DAA();
|
||||
break;
|
||||
case 0x28: /* SUB Eb,Gb */
|
||||
RMEbGb(SUBB);break;
|
||||
|
@ -132,19 +116,7 @@ restart:
|
|||
case 0x2e: /* SEG CS: */
|
||||
SegPrefix(cs);break;
|
||||
case 0x2f: /* DAS */
|
||||
if (((reg_al & 0x0f) > 9) || get_AF()) {
|
||||
reg_al-=6;
|
||||
flags.af=true;
|
||||
} else {
|
||||
flags.af=false;
|
||||
}
|
||||
if ((reg_al>0x9f) || get_CF()) {
|
||||
reg_al-=0x60;
|
||||
flags.cf=true;
|
||||
} else {
|
||||
flags.cf=false;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
DAS();
|
||||
break;
|
||||
case 0x30: /* XOR Eb,Gb */
|
||||
RMEbGb(XORB);break;
|
||||
|
@ -161,18 +133,7 @@ restart:
|
|||
case 0x36: /* SEG SS: */
|
||||
SegPrefix(ss);break;
|
||||
case 0x37: /* AAA */
|
||||
if (get_AF() || ((reg_al & 0xf) > 9))
|
||||
{
|
||||
reg_al += 6;
|
||||
reg_ah += 1;
|
||||
flags.af=true;
|
||||
flags.cf=true;
|
||||
} else {
|
||||
flags.af=false;
|
||||
flags.cf=false;
|
||||
}
|
||||
reg_al &= 0x0F;
|
||||
flags.type=t_UNKNOWN;
|
||||
AAA();
|
||||
break;
|
||||
case 0x38: /* CMP Eb,Gb */
|
||||
RMEbGb(CMPB);break;
|
||||
|
@ -189,14 +150,7 @@ restart:
|
|||
case 0x3e: /* SEG DS: */
|
||||
SegPrefix(ds);break;
|
||||
case 0x3f: /* AAS */
|
||||
if (((reg_al & 0x0f)>9) || get_AF()) {
|
||||
reg_al=(reg_al-6) & 0xF;
|
||||
reg_ah--;
|
||||
flags.af=flags.cf=true;
|
||||
} else {
|
||||
flags.af=flags.cf=false;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
AAS();
|
||||
break;
|
||||
case 0x40: /* INC AX */
|
||||
INCW(reg_ax,LoadRw,SaveRw);break;
|
||||
|
@ -240,7 +194,7 @@ restart:
|
|||
Push_16(reg_bx);break;
|
||||
case 0x54: /* PUSH SP */
|
||||
//TODO Check if this is correct i think it's SP+2 or something
|
||||
Push_16(reg_sp);break;
|
||||
Push_16(reg_sp);break;
|
||||
case 0x55: /* PUSH BP */
|
||||
Push_16(reg_bp);break;
|
||||
case 0x56: /* PUSH SI */
|
||||
|
@ -255,8 +209,8 @@ restart:
|
|||
reg_dx=Pop_16();break;
|
||||
case 0x5b: /* POP BX */
|
||||
reg_bx=Pop_16();break;
|
||||
case 0x5c: /* POP SP */
|
||||
reg_sp=Pop_16();break;
|
||||
case 0x5c: /* POP SP */
|
||||
reg_sp=Pop_16();break;
|
||||
case 0x5d: /* POP BP */
|
||||
reg_bp=Pop_16();break;
|
||||
case 0x5e: /* POP SI */
|
||||
|
@ -264,8 +218,11 @@ restart:
|
|||
case 0x5f: /* POP DI */
|
||||
reg_di=Pop_16();break;
|
||||
case 0x60: /* PUSHA */
|
||||
Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
|
||||
Push_16(reg_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
|
||||
{
|
||||
Bit16u old_sp=reg_sp;
|
||||
Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
|
||||
Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
|
||||
}
|
||||
break;
|
||||
case 0x61: /* POPA */
|
||||
reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP
|
||||
|
@ -278,7 +235,7 @@ restart:
|
|||
bound_min=LoadMw(eaa);
|
||||
bound_max=LoadMw(eaa+2);
|
||||
if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) {
|
||||
INTERRUPT(5);
|
||||
EXCEPTION(5);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -308,35 +265,19 @@ restart:
|
|||
case 0x68: /* PUSH Iw */
|
||||
Push_16(Fetchw());break;
|
||||
case 0x69: /* IMUL Gw,Ew,Iw */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit32s res;
|
||||
if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*earws) * (Bit32s)Fetchws();}
|
||||
else {GetEAa;res=(Bit32s)LoadMws(eaa) * (Bit32s)Fetchws();}
|
||||
*rmrw=res & 0xFFFF;
|
||||
flags.type=t_MUL;
|
||||
if ((res> -32768) && (res<32767)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
};
|
||||
RMGwEwOp3(DIMULW,Fetchws());
|
||||
break;
|
||||
case 0x6a: /* PUSH Ib */
|
||||
Push_16(Fetchbs());break;
|
||||
Push_16(Fetchbs());
|
||||
break;
|
||||
case 0x6b: /* IMUL Gw,Ew,Ib */
|
||||
{
|
||||
GetRMrw;Bit32s res;
|
||||
if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*earws) * (Bit32s)Fetchbs();}
|
||||
else {GetEAa;res=(Bit32s)LoadMws(eaa) * (Bit32s)Fetchbs();}
|
||||
*rmrw=res & 0xFFFF;
|
||||
flags.type=t_MUL;
|
||||
if ((res> -32768) && (res<32767)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
}
|
||||
RMGwEwOp3(DIMULW,Fetchbs());
|
||||
break;
|
||||
case 0x6c: /* INSB */
|
||||
{
|
||||
stringDI;
|
||||
SaveMb(to,IO_Read(reg_dx));
|
||||
if (flags.df) reg_di--; else reg_di++;
|
||||
if (GETFLAG(DF)) reg_di--; else reg_di++;
|
||||
break;
|
||||
}
|
||||
case 0x6d: /* INSW */
|
||||
|
@ -344,14 +285,14 @@ restart:
|
|||
stringDI;
|
||||
SaveMb(to,IO_Read(reg_dx));
|
||||
SaveMb((to+1),IO_Read(reg_dx+1));
|
||||
if (flags.df) reg_di-=2; else reg_di+=2;
|
||||
if (GETFLAG(DF)) reg_di-=2; else reg_di+=2;
|
||||
break;
|
||||
}
|
||||
case 0x6e: /* OUTSB */
|
||||
{
|
||||
stringSI;
|
||||
IO_Write(reg_dx,LoadMb(from));
|
||||
if (flags.df) reg_si--; else reg_si++;
|
||||
if (GETFLAG(DF)) reg_si--; else reg_si++;
|
||||
break;
|
||||
}
|
||||
case 0x6f: /* OUTSW */
|
||||
|
@ -359,7 +300,7 @@ restart:
|
|||
stringSI;
|
||||
IO_Write(reg_dx,LoadMb(from));
|
||||
IO_Write(reg_dx+1,LoadMb(from+1));
|
||||
if (flags.df) reg_si-=2; else reg_si+=2;
|
||||
if (GETFLAG(DF)) reg_si-=2; else reg_si+=2;
|
||||
break;
|
||||
}
|
||||
case 0x70: /* JO */
|
||||
|
@ -486,9 +427,11 @@ restart:
|
|||
break;
|
||||
}
|
||||
case 0x84: /* TEST Eb,Gb */
|
||||
RMEbGb(TESTB);break;
|
||||
RMEbGb(TESTB);
|
||||
break;
|
||||
case 0x85: /* TEST Ew,Gw */
|
||||
RMEwGw(TESTW);break;
|
||||
RMEwGw(TESTW);
|
||||
break;
|
||||
case 0x86: /* XCHG Eb,Gb */
|
||||
{
|
||||
GetRMrb;Bit8u oldrmrb=*rmrb;
|
||||
|
@ -636,27 +579,15 @@ restart:
|
|||
case 0x9b: /* WAIT */
|
||||
break; /* No waiting here */
|
||||
case 0x9c: /* PUSHF */
|
||||
{
|
||||
Bit16u pflags=
|
||||
(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) |
|
||||
(get_ZF() << 6) | (get_SF() << 7) | (flags.tf << 8) |
|
||||
(flags.intf << 9) |(flags.df << 10) | (get_OF() << 11) |
|
||||
(flags.io << 12) | (flags.nt <<14);
|
||||
Push_16(pflags);
|
||||
break;
|
||||
}
|
||||
FILLFLAGS;
|
||||
Push_16(flags.word);
|
||||
break;
|
||||
case 0x9d: /* POPF */
|
||||
{
|
||||
Bit16u bits=Pop_16();
|
||||
Save_Flagsw(bits);
|
||||
break;
|
||||
}
|
||||
SETFLAGSw(Pop_16());
|
||||
CheckTF();
|
||||
break;
|
||||
case 0x9e: /* SAHF */
|
||||
flags.of =get_OF();
|
||||
flags.type=t_UNKNOWN;
|
||||
flags.cf =(reg_ah & 0x001)!=0;flags.pf =(reg_ah & 0x004)!=0;
|
||||
flags.af =(reg_ah & 0x010)!=0;flags.zf =(reg_ah & 0x040)!=0;
|
||||
flags.sf =(reg_ah & 0x080)!=0;
|
||||
SETFLAGSb(reg_ah);
|
||||
break;
|
||||
case 0x9f: /* LAHF */
|
||||
{
|
||||
|
@ -688,7 +619,7 @@ restart:
|
|||
{
|
||||
stringSI;stringDI;
|
||||
SaveMb(to,LoadMb(from));;
|
||||
if (flags.df) { reg_si--;reg_di--; }
|
||||
if (GETFLAG(DF)) { reg_si--;reg_di--; }
|
||||
else {reg_si++;reg_di++;}
|
||||
break;
|
||||
}
|
||||
|
@ -696,7 +627,7 @@ restart:
|
|||
{
|
||||
stringSI;stringDI;
|
||||
SaveMw(to,LoadMw(from));
|
||||
if (flags.df) { reg_si-=2;reg_di-=2; }
|
||||
if (GETFLAG(DF)) { reg_si-=2;reg_di-=2; }
|
||||
else {reg_si+=2;reg_di+=2;}
|
||||
break;
|
||||
}
|
||||
|
@ -704,7 +635,7 @@ restart:
|
|||
{
|
||||
stringSI;stringDI;
|
||||
CMPB(from,LoadMb(to),LoadMb,0);
|
||||
if (flags.df) { reg_si--;reg_di--; }
|
||||
if (GETFLAG(DF)) { reg_si--;reg_di--; }
|
||||
else {reg_si++;reg_di++;}
|
||||
break;
|
||||
}
|
||||
|
@ -712,7 +643,7 @@ restart:
|
|||
{
|
||||
stringSI;stringDI;
|
||||
CMPW(from,LoadMw(to),LoadMw,0);
|
||||
if (flags.df) { reg_si-=2;reg_di-=2; }
|
||||
if (GETFLAG(DF)) { reg_si-=2;reg_di-=2; }
|
||||
else {reg_si+=2;reg_di+=2;}
|
||||
break;
|
||||
}
|
||||
|
@ -724,7 +655,7 @@ restart:
|
|||
{
|
||||
stringDI;
|
||||
SaveMb(to,reg_al);
|
||||
if (flags.df) { reg_di--; }
|
||||
if (GETFLAG(DF)) { reg_di--; }
|
||||
else {reg_di++;}
|
||||
break;
|
||||
}
|
||||
|
@ -732,7 +663,7 @@ restart:
|
|||
{
|
||||
stringDI;
|
||||
SaveMw(to,reg_ax);
|
||||
if (flags.df) { reg_di-=2; }
|
||||
if (GETFLAG(DF)) { reg_di-=2; }
|
||||
else {reg_di+=2;}
|
||||
break;
|
||||
}
|
||||
|
@ -740,7 +671,7 @@ restart:
|
|||
{
|
||||
stringSI;
|
||||
reg_al=LoadMb(from);
|
||||
if (flags.df) { reg_si--; }
|
||||
if (GETFLAG(DF)) { reg_si--; }
|
||||
else {reg_si++;}
|
||||
break;
|
||||
}
|
||||
|
@ -748,7 +679,7 @@ restart:
|
|||
{
|
||||
stringSI;
|
||||
reg_ax=LoadMw(from);
|
||||
if (flags.df) { reg_si-=2;}
|
||||
if (GETFLAG(DF)) { reg_si-=2;}
|
||||
else {reg_si+=2;}
|
||||
break;
|
||||
}
|
||||
|
@ -756,7 +687,7 @@ restart:
|
|||
{
|
||||
stringDI;
|
||||
CMPB(reg_al,LoadMb(to),LoadRb,0);
|
||||
if (flags.df) { reg_di--; }
|
||||
if (GETFLAG(DF)) { reg_di--; }
|
||||
else {reg_di++;}
|
||||
break;
|
||||
}
|
||||
|
@ -764,7 +695,7 @@ restart:
|
|||
{
|
||||
stringDI;
|
||||
CMPW(reg_ax,LoadMw(to),LoadRw,0);
|
||||
if (flags.df) { reg_di-=2; }
|
||||
if (GETFLAG(DF)) { reg_di-=2; }
|
||||
else {reg_di+=2;}
|
||||
break;
|
||||
}
|
||||
|
@ -872,7 +803,7 @@ restart:
|
|||
}
|
||||
LOADIP;
|
||||
#endif
|
||||
INTERRUPT(3);
|
||||
EXCEPTION(3);
|
||||
break;
|
||||
case 0xcd: /* INT Ib */
|
||||
{
|
||||
|
@ -881,17 +812,19 @@ restart:
|
|||
SAVEIP;
|
||||
if (DEBUG_IntBreakpoint(num)) return 1;
|
||||
#endif
|
||||
INTERRUPT(num);
|
||||
EXCEPTION(num);
|
||||
}
|
||||
break;
|
||||
case 0xce: /* INTO */
|
||||
if (get_OF()) INTERRUPT(4);
|
||||
if (get_OF()) EXCEPTION(4);
|
||||
break;
|
||||
case 0xcf: /* IRET */
|
||||
{
|
||||
Bit16u newip=Pop_16();Bit16u newcs=Pop_16();
|
||||
SegSet16(cs,newcs);SETIP(newip);
|
||||
Bit16u pflags=Pop_16();Save_Flagsw(pflags);
|
||||
Bit16u pflags=Pop_16();
|
||||
SETFLAGSw(pflags);
|
||||
CheckTF();
|
||||
break;
|
||||
}
|
||||
case 0xd0: /* GRP2 Eb,1 */
|
||||
|
@ -903,26 +836,12 @@ restart:
|
|||
case 0xd3: /* GRP2 Ew,CL */
|
||||
GRP2W(reg_cl);break;
|
||||
case 0xd4: /* AAM Ib */
|
||||
{
|
||||
Bit8u ib=Fetchb();
|
||||
|
||||
reg_ah=reg_al / ib;
|
||||
reg_al=reg_al % ib;
|
||||
flags.type=t_UNKNOWN;
|
||||
flags.sf=(reg_ah & 0x80) > 0;
|
||||
flags.zf=(reg_ax == 0);
|
||||
//TODO PF
|
||||
flags.pf=0;
|
||||
}
|
||||
AAM(Fetchb());
|
||||
break;
|
||||
case 0xd5: /* AAD Ib */
|
||||
reg_al=reg_ah*Fetchb()+reg_al;
|
||||
reg_ah=0;
|
||||
flags.cf=(reg_al>=0x80);
|
||||
flags.zf=(reg_al==0);
|
||||
//TODO PF
|
||||
flags.type=t_UNKNOWN;
|
||||
AAD(Fetchb());
|
||||
break;
|
||||
|
||||
case 0xd6: /* SALC */
|
||||
reg_al = get_CF() ? 0xFF : 0;
|
||||
break;
|
||||
|
@ -1052,28 +971,28 @@ restart:
|
|||
case 0xf4: /* HLT */
|
||||
break;
|
||||
case 0xf5: /* CMC */
|
||||
flags.cf=!get_CF();
|
||||
SETFLAGBIT(CF,!get_CF());
|
||||
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||
flags.type=t_CF;
|
||||
break;
|
||||
case 0xf6: /* GRP3 Eb(,Ib) */
|
||||
{
|
||||
{
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
switch ((rm & 0x38)>>3) {
|
||||
case 0x00: /* TEST Eb,Ib */
|
||||
case 0x08: /* TEST Eb,Ib Undocumented*/
|
||||
case 0x01: /* TEST Eb,Ib Undocumented*/
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)}
|
||||
else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);}
|
||||
break;
|
||||
}
|
||||
case 0x10: /* NOT Eb */
|
||||
case 0x02: /* NOT Eb */
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;}
|
||||
else {GetEAa;SaveMb(eaa,~LoadMb(eaa));}
|
||||
break;
|
||||
}
|
||||
case 0x18: /* NEG Eb */
|
||||
case 0x03: /* NEG Eb */
|
||||
{
|
||||
flags.type=t_NEGb;
|
||||
if (rm >= 0xc0 ) {
|
||||
|
@ -1085,69 +1004,38 @@ restart:
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 0x20: /* MUL AL,Eb */
|
||||
{
|
||||
flags.type=t_MUL;
|
||||
if (rm >= 0xc0 ) {GetEArb;reg_ax=reg_al * (*earb);}
|
||||
else {GetEAa;reg_ax=reg_al * LoadMb(eaa);}
|
||||
flags.cf=flags.of=((reg_ax & 0xff00) !=0);
|
||||
break;
|
||||
}
|
||||
case 0x28: /* IMUL AL,Eb */
|
||||
{
|
||||
flags.type=t_MUL;
|
||||
if (rm >= 0xc0 ) {GetEArb;reg_ax=(Bit8s)reg_al * (*earbs);}
|
||||
else {GetEAa;reg_ax=((Bit8s)reg_al) * LoadMbs(eaa);}
|
||||
flags.cf=flags.of=!((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000);
|
||||
break;
|
||||
}
|
||||
case 0x30: /* DIV Eb */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit8u val;
|
||||
if (rm >= 0xc0 ) {GetEArb;val=*earb;}
|
||||
else {GetEAa;val=LoadMb(eaa);}
|
||||
if (val==0) {INTERRUPT(0);break;}
|
||||
Bit16u quotientu=reg_ax / val;
|
||||
reg_ah=(Bit8u)(reg_ax % val);
|
||||
reg_al=quotientu & 0xff;
|
||||
if (quotientu!=reg_al)
|
||||
INTERRUPT(0);
|
||||
break;
|
||||
}
|
||||
case 0x38: /* IDIV Eb */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit8s val;
|
||||
if (rm >= 0xc0 ) {GetEArb;val=*earbs;}
|
||||
else {GetEAa;val=LoadMbs(eaa);}
|
||||
if (val==0) {INTERRUPT(0);break;}
|
||||
Bit16s quotients=((Bit16s)reg_ax) / val;
|
||||
reg_ah=(Bit8s)(((Bit16s)reg_ax) % val);
|
||||
reg_al=quotients & 0xff;
|
||||
if (quotients!=(Bit8s)reg_al)
|
||||
INTERRUPT(0);
|
||||
break;
|
||||
}
|
||||
case 0x04: /* MUL AL,Eb */
|
||||
RMEb(MULB);
|
||||
break;
|
||||
case 0x05: /* IMUL AL,Eb */
|
||||
RMEb(IMULB);
|
||||
break;
|
||||
case 0x06: /* DIV Eb */
|
||||
RMEb(DIVB);
|
||||
break;
|
||||
case 0x07: /* IDIV Eb */
|
||||
RMEb(IDIVB);
|
||||
break;
|
||||
}
|
||||
break;}
|
||||
break;
|
||||
}
|
||||
case 0xf7: /* GRP3 Ew(,Iw) */
|
||||
{ GetRM;
|
||||
switch (rm & 0x38) {
|
||||
switch ((rm & 0x38)>>3) {
|
||||
case 0x00: /* TEST Ew,Iw */
|
||||
case 0x08: /* TEST Ew,Iw Undocumented*/
|
||||
case 0x01: /* TEST Ew,Iw Undocumented*/
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);}
|
||||
else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
case 0x10: /* NOT Ew */
|
||||
case 0x02: /* NOT Ew */
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;}
|
||||
else {GetEAa;SaveMw(eaa,~LoadMw(eaa));}
|
||||
break;
|
||||
}
|
||||
case 0x18: /* NEG Ew */
|
||||
case 0x03: /* NEG Ew */
|
||||
{
|
||||
flags.type=t_NEGw;
|
||||
if (rm >= 0xc0 ) {
|
||||
|
@ -1159,104 +1047,57 @@ restart:
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 0x20: /* MUL AX,Ew */
|
||||
{
|
||||
flags.type=t_MUL;Bit32u tempu;
|
||||
if (rm >= 0xc0 ) {GetEArw;tempu=reg_ax * (*earw);}
|
||||
else {GetEAa;tempu=reg_ax * LoadMw(eaa);}
|
||||
reg_ax=(Bit16u)(tempu & 0xffff);reg_dx=(Bit16u)(tempu >> 16);
|
||||
flags.cf=flags.of=(reg_dx !=0);
|
||||
break;
|
||||
}
|
||||
case 0x28: /* IMUL AX,Ew */
|
||||
{
|
||||
flags.type=t_MUL;Bit32s temps;
|
||||
if (rm >= 0xc0 ) {GetEArw;temps=((Bit16s)reg_ax) * (*earws);}
|
||||
else {GetEAa;temps=((Bit16s)reg_ax) * LoadMws(eaa);}
|
||||
reg_ax=Bit16u(temps & 0xffff);reg_dx=(Bit16u)(temps >> 16);
|
||||
if ( (reg_dx==0xffff) && (reg_ax & 0x8000) ) {
|
||||
flags.cf=flags.of=false;
|
||||
} else if ( (reg_dx==0x0000) && (reg_ax<0x8000) ) {
|
||||
flags.cf=flags.of=false;
|
||||
} else {
|
||||
flags.cf=flags.of=true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x30: /* DIV Ew */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit16u val;
|
||||
if (rm >= 0xc0 ) {GetEArw;val=*earw;}
|
||||
else {GetEAa;val=LoadMw(eaa);}
|
||||
if (val==0) {INTERRUPT(0);break;}
|
||||
Bit32u tempu=(reg_dx<<16)|reg_ax;
|
||||
Bit32u quotientu=tempu/val;
|
||||
reg_dx=(Bit16u)(tempu % val);
|
||||
reg_ax=(Bit16u)(quotientu & 0xffff);
|
||||
if (quotientu>0xffff)
|
||||
INTERRUPT(0);
|
||||
break;
|
||||
}
|
||||
case 0x38: /* IDIV Ew */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit16s val;
|
||||
if (rm >= 0xc0 ) {GetEArw;val=*earws;}
|
||||
else {GetEAa;val=LoadMws(eaa);}
|
||||
if (val==0) {INTERRUPT(0);break;}
|
||||
Bit32s temps=(reg_dx<<16)|reg_ax;
|
||||
Bit32s quotients=temps/val;
|
||||
reg_dx=(Bit16s)(temps % val);
|
||||
reg_ax=(Bit16s)quotients;
|
||||
if (quotients!=(Bit16s)reg_ax)
|
||||
INTERRUPT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x04: /* MUL AX,Ew */
|
||||
RMEw(MULW);
|
||||
break;
|
||||
case 0x05: /* IMUL AX,Ew */
|
||||
RMEw(IMULW)
|
||||
break;
|
||||
case 0x06: /* DIV Ew */
|
||||
RMEw(DIVW)
|
||||
break;
|
||||
case 0x07: /* IDIV Ew */
|
||||
RMEw(IDIVW)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xf8: /* CLC */
|
||||
flags.cf=false;
|
||||
SETFLAGBIT(CF,false);
|
||||
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||
flags.type=t_CF;
|
||||
break;
|
||||
case 0xf9: /* STC */
|
||||
flags.cf=true;
|
||||
SETFLAGBIT(CF,true);
|
||||
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||
flags.type=t_CF;
|
||||
break;
|
||||
case 0xfa: /* CLI */
|
||||
flags.intf=false;
|
||||
SETFLAGBIT(IF,false);
|
||||
break;
|
||||
case 0xfb: /* STI */
|
||||
flags.intf=true;
|
||||
if (flags.intf && PIC_IRQCheck) {
|
||||
SETFLAGBIT(IF,true);
|
||||
if (PIC_IRQCheck) {
|
||||
SAVEIP;
|
||||
PIC_runIRQs();
|
||||
LOADIP;
|
||||
};
|
||||
break;
|
||||
case 0xfc: /* CLD */
|
||||
flags.df=false;
|
||||
SETFLAGBIT(DF,false);
|
||||
break;
|
||||
case 0xfd: /* STD */
|
||||
flags.df=true;
|
||||
SETFLAGBIT(DF,true);
|
||||
break;
|
||||
case 0xfe: /* GRP4 Eb */
|
||||
{
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
case 0x00: /* INC Eb */
|
||||
flags.cf=get_CF();flags.type=t_INCb;
|
||||
if (rm >= 0xc0 ) {GetEArb;flags.result.b=*earb+=1;}
|
||||
else {GetEAa;flags.result.b=LoadMb(eaa)+1;SaveMb(eaa,flags.result.b);}
|
||||
RMEb(INCB);
|
||||
break;
|
||||
case 0x08: /* DEC Eb */
|
||||
flags.cf=get_CF();flags.type=t_DECb;
|
||||
if (rm >= 0xc0 ) {GetEArb;flags.result.b=*earb-=1;}
|
||||
else {GetEAa;flags.result.b=LoadMb(eaa)-1;SaveMb(eaa,flags.result.b);}
|
||||
RMEb(DECB);
|
||||
break;
|
||||
case 0x38: /* CallBack */
|
||||
{
|
||||
|
@ -1289,15 +1130,11 @@ restart:
|
|||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
case 0x00: /* INC Ew */
|
||||
flags.cf=get_CF();flags.type=t_INCw;
|
||||
if (rm >= 0xc0 ) {GetEArw;flags.result.w=*earw+=1;}
|
||||
else {GetEAa;flags.result.w=LoadMw(eaa)+1;SaveMw(eaa,flags.result.w);}
|
||||
RMEw(INCW);
|
||||
break;
|
||||
case 0x08: /* DEC Ew */
|
||||
flags.cf=get_CF();flags.type=t_DECw;
|
||||
if (rm >= 0xc0 ) {GetEArw;flags.result.w=*earw-=1;}
|
||||
else {GetEAa;flags.result.w=LoadMw(eaa)-1;SaveMw(eaa,flags.result.w);}
|
||||
break;
|
||||
RMEw(DECW);
|
||||
break;
|
||||
case 0x10: /* CALL Ev */
|
||||
if (rm >= 0xc0 ) {GetEArw;Push_16(GETIP);SETIP(*earw);}
|
||||
else {GetEAa;Push_16(GETIP);SETIP(LoadMw(eaa));}
|
||||
|
|
|
@ -167,31 +167,13 @@ switch(Fetchb()) {
|
|||
case 0x68: /* PUSH Id */
|
||||
Push_32(Fetchd());break;
|
||||
case 0x69: /* IMUL Gd,Ed,Id */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit64s res;
|
||||
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchds();}
|
||||
else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchds();}
|
||||
*rmrd=(Bit32s)(res);
|
||||
flags.type=t_MUL;
|
||||
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
}
|
||||
RMGdEdOp3(DIMULD,Fetchds());
|
||||
break;
|
||||
case 0x6a: /* PUSH Ib */
|
||||
Push_32(Fetchbs());break;
|
||||
case 0x6b: /* IMUL Gd,Ed,Ib */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit64s res;
|
||||
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchbs();}
|
||||
else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchbs();}
|
||||
*rmrd=(Bit32s)(res);
|
||||
flags.type=t_MUL;
|
||||
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
}
|
||||
RMGdEdOp3(DIMULD,Fetchbs());
|
||||
break;
|
||||
case 0x81: /* Grpl Ed,Id */
|
||||
{
|
||||
GetRM;
|
||||
|
@ -324,35 +306,23 @@ switch(Fetchb()) {
|
|||
else reg_edx=0;
|
||||
break;
|
||||
case 0x9c: /* PUSHFD */
|
||||
{
|
||||
Bit32u pflags=
|
||||
(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) |
|
||||
(get_ZF() << 6) | (get_SF() << 7) | (flags.tf << 8) |
|
||||
(flags.intf << 9) |(flags.df << 10) | (get_OF() << 11) |
|
||||
(flags.io << 12) | (flags.nt <<14);
|
||||
Push_32(pflags);
|
||||
break;
|
||||
}
|
||||
FILLFLAGS;
|
||||
Push_32(flags.word);
|
||||
break;
|
||||
case 0x9d: /* POPFD */
|
||||
{
|
||||
Bit16u val=(Bit16u)(Pop_32()&0xffff);
|
||||
Save_Flagsw(val);
|
||||
break;
|
||||
}
|
||||
SETFLAGSd(Pop_32())
|
||||
CheckTF();
|
||||
break;
|
||||
case 0xa1: /* MOV EAX,Ow */
|
||||
{
|
||||
reg_eax=LoadMd(GetEADirect[prefix.mark]());
|
||||
}
|
||||
reg_eax=LoadMd(GetEADirect[prefix.mark]());
|
||||
break;
|
||||
case 0xa3: /* MOV Ow,EAX */
|
||||
{
|
||||
SaveMd(GetEADirect[prefix.mark](),reg_eax);
|
||||
}
|
||||
SaveMd(GetEADirect[prefix.mark](),reg_eax);
|
||||
break;
|
||||
case 0xa5: /* MOVSD */
|
||||
{
|
||||
stringSI;stringDI;SaveMd(to,LoadMd(from));
|
||||
if (flags.df) { reg_si-=4;reg_di-=4; }
|
||||
if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; }
|
||||
else { reg_si+=4;reg_di+=4;}
|
||||
}
|
||||
break;
|
||||
|
@ -363,7 +333,7 @@ switch(Fetchb()) {
|
|||
{
|
||||
stringDI;
|
||||
SaveMd(to,reg_eax);
|
||||
if (flags.df) { reg_di-=4; }
|
||||
if (GETFLAG(DF)) { reg_di-=4; }
|
||||
else {reg_di+=4;}
|
||||
break;
|
||||
}
|
||||
|
@ -371,7 +341,7 @@ switch(Fetchb()) {
|
|||
{
|
||||
stringSI;
|
||||
reg_eax=LoadMd(from);
|
||||
if (flags.df) { reg_si-=4;}
|
||||
if (GETFLAG(DF)) { reg_si-=4;}
|
||||
else {reg_si+=4;}
|
||||
break;
|
||||
}
|
||||
|
@ -379,7 +349,7 @@ switch(Fetchb()) {
|
|||
{
|
||||
stringDI;
|
||||
CMPD(reg_eax,LoadMd(to),LoadRd,0);
|
||||
if (flags.df) { reg_di-=4; }
|
||||
if (GETFLAG(DF)) { reg_di-=4; }
|
||||
else {reg_di+=4;}
|
||||
break;
|
||||
}
|
||||
|
@ -424,6 +394,13 @@ switch(Fetchb()) {
|
|||
GRP2D(1);break;
|
||||
case 0xd3: /* GRP2 Ed,CL */
|
||||
GRP2D(reg_cl);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 */
|
||||
prefix.count++;
|
||||
Repeat_Normal(false,true);
|
||||
|
@ -434,24 +411,22 @@ switch(Fetchb()) {
|
|||
continue;
|
||||
case 0xf7: /* GRP3 Ed(,Id) */
|
||||
{
|
||||
union { Bit64u u;Bit64s s;} temp;
|
||||
union {Bit64u u;Bit64s s;} quotient;
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
switch ((rm & 0x38)>>3) {
|
||||
case 0x00: /* TEST Ed,Id */
|
||||
case 0x08: /* TEST Ed,Id Undocumented*/
|
||||
case 0x01: /* TEST Ed,Id Undocumented*/
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
|
||||
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
|
||||
break;
|
||||
}
|
||||
case 0x10: /* NOT Ed */
|
||||
case 0x02: /* NOT Ed */
|
||||
{
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
|
||||
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
|
||||
break;
|
||||
}
|
||||
case 0x18: /* NEG Ed */
|
||||
case 0x03: /* NEG Ed */
|
||||
{
|
||||
flags.type=t_NEGd;
|
||||
if (rm >= 0xc0 ) {
|
||||
|
@ -463,60 +438,18 @@ switch(Fetchb()) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 0x20: /* MUL EAX,Ed */
|
||||
{
|
||||
flags.type=t_MUL;
|
||||
if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64u)reg_eax * (Bit64u)(*eard);}
|
||||
else {GetEAa;temp.u=(Bit64u)reg_eax * (Bit64u)LoadMd(eaa);}
|
||||
reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_edx=(Bit32u)(temp.u >> 32);
|
||||
flags.cf=flags.of=(reg_edx !=0);
|
||||
break;
|
||||
}
|
||||
case 0x28: /* IMUL EAX,Ed */
|
||||
{
|
||||
flags.type=t_MUL;
|
||||
if (rm >= 0xc0 ) {GetEArd;temp.s=((Bit64s)((Bit32s)reg_eax) * (Bit64s)(*eards));}
|
||||
else {GetEAa;temp.s=((Bit64s)((Bit32s)reg_eax) * (Bit64s)(LoadMds(eaa)));}
|
||||
reg_eax=Bit32u(temp.s & 0xffffffff);reg_edx=(Bit32u)(temp.s >> 32);
|
||||
if ( (reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) {
|
||||
flags.cf=flags.of=false;
|
||||
} else if ( (reg_edx==0x00000000) && (reg_eax<0x80000000) ) {
|
||||
flags.cf=flags.of=false;
|
||||
} else {
|
||||
flags.cf=flags.of=true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x30: /* DIV Ed */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit32u val;
|
||||
if (rm >= 0xc0 ) {GetEArd;val=*eard;}
|
||||
else {GetEAa;val=LoadMd(eaa);}
|
||||
if (val==0) {INTERRUPT(0);break;}
|
||||
temp.u=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||
quotient.u=temp.u/val;
|
||||
reg_edx=(Bit32u)(temp.u % val);
|
||||
reg_eax=(Bit32u)(quotient.u & 0xffffffff);
|
||||
if (quotient.u>0xffffffff)
|
||||
INTERRUPT(0);
|
||||
break;
|
||||
}
|
||||
case 0x38: /* IDIV Ed */
|
||||
{
|
||||
// flags.type=t_DIV;
|
||||
Bit32s val;
|
||||
if (rm >= 0xc0 ) {GetEArd;val=*eards;}
|
||||
else {GetEAa;val=LoadMds(eaa);}
|
||||
if (val==0) {INTERRUPT(0);break;}
|
||||
temp.s=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||
quotient.s=(temp.s/val);
|
||||
reg_edx=(Bit32s)(temp.s % val);
|
||||
reg_eax=(Bit32s)(quotient.s);
|
||||
if (quotient.s!=(Bit32s)reg_eax)
|
||||
INTERRUPT(0);
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -525,14 +458,10 @@ switch(Fetchb()) {
|
|||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
case 0x00: /* INC Ed */
|
||||
flags.cf=get_CF();flags.type=t_INCd;
|
||||
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard+=1;}
|
||||
else {GetEAa;flags.result.d=LoadMd(eaa)+1;SaveMd(eaa,flags.result.d);}
|
||||
RMEd(INCD);
|
||||
break;
|
||||
case 0x08: /* DEC Ed */
|
||||
flags.cf=get_CF();flags.type=t_DECd;
|
||||
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard-=1;}
|
||||
else {GetEAa;flags.result.d=LoadMd(eaa)-1;SaveMd(eaa,flags.result.d);}
|
||||
RMEd(DECD);
|
||||
break;
|
||||
case 0x30: /* Push Ed */
|
||||
if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
|
||||
|
|
|
@ -41,26 +41,19 @@ switch (Fetchb()) {
|
|||
break;
|
||||
}
|
||||
|
||||
case 0xb6: /* MOVZX Gd,Eb */
|
||||
case 0xb6: /* MOVZX Gd,Eb */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
|
||||
else {GetEAa;*rmrd=LoadMb(eaa);}
|
||||
break;
|
||||
}
|
||||
case 0xaf: /* IMUL Gd,Ed */
|
||||
case 0xaf: /* IMUL Gd,Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
Bit64s res;
|
||||
if (rm >= 0xc0 ) {GetEArd;res=((Bit64s)((Bit32s)*rmrd) * (Bit64s)((Bit32s)*eards));}
|
||||
else {GetEAa;res=((Bit64s)((Bit32s)*rmrd) * (Bit64s)LoadMds(eaa));}
|
||||
*rmrd=(Bit32s)(res);
|
||||
flags.type=t_MUL;
|
||||
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
RMGdEdOp3(DIMULD,*rmrd);
|
||||
break;
|
||||
};
|
||||
case 0xb7: /* MOVXZ Gd,Ew */
|
||||
case 0xb7: /* MOVXZ Gd,Ew */
|
||||
{
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;}
|
||||
|
@ -73,7 +66,7 @@ switch (Fetchb()) {
|
|||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
Bit32u mask=1 << (Fetchb() & 31);
|
||||
flags.cf=(*eard & mask)>0;
|
||||
SETFLAGBIT(CF,(*eard & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
|
@ -84,7 +77,7 @@ switch (Fetchb()) {
|
|||
*eard&=~mask;
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
if (flags.cf) *eard&=~mask;
|
||||
if (GETFLAG(CF)) *eard&=~mask;
|
||||
else *eard|=mask;
|
||||
break;
|
||||
default:
|
||||
|
@ -93,7 +86,7 @@ switch (Fetchb()) {
|
|||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
Bit32u mask=1 << (Fetchb() & 31);
|
||||
flags.cf=(old & mask)>0;
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
|
@ -104,7 +97,7 @@ switch (Fetchb()) {
|
|||
SaveMd(eaa,old & ~mask);
|
||||
break;
|
||||
case 0x38: /* BTC */
|
||||
if (flags.cf) old&=~mask;
|
||||
if (GETFLAG(CF)) old&=~mask;
|
||||
else old|=mask;
|
||||
SaveMd(eaa,old);
|
||||
break;
|
||||
|
@ -122,11 +115,11 @@ switch (Fetchb()) {
|
|||
Bit32u mask=1 << (*rmrd & 31);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
flags.cf=(*eard & mask)>0;
|
||||
SETFLAGBIT(CF,(*eard & mask));
|
||||
*eard^=mask;
|
||||
} else {
|
||||
GetEAa;Bit32u old=LoadMd(eaa);
|
||||
flags.cf=(old & mask)>0;
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMd(eaa,old ^ mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
|
@ -139,11 +132,11 @@ switch (Fetchb()) {
|
|||
if (rm >= 0xc0) { GetEArd; value=*eard; }
|
||||
else { GetEAa; value=LoadMd(eaa); }
|
||||
if (value==0) {
|
||||
flags.zf = true;
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 0;
|
||||
while ((value & 0x01)==0) { result++; value>>=1; }
|
||||
flags.zf = false;
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrd = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
|
@ -156,11 +149,11 @@ switch (Fetchb()) {
|
|||
if (rm >= 0xc0) { GetEArd; value=*eard; }
|
||||
else { GetEAa; value=LoadMd(eaa); }
|
||||
if (value==0) {
|
||||
flags.zf = true;
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 35; // Operandsize-1
|
||||
while ((value & 0x80000000)==0) { result--; value<<=1; }
|
||||
flags.zf = false;
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrd = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
switch(Fetchb()) {
|
||||
case 0x00: /* GRP 6 */
|
||||
{
|
||||
INTERRUPT(6);
|
||||
EXCEPTION(6);
|
||||
break;
|
||||
GetRM;
|
||||
switch (rm & 0x38) {
|
||||
|
@ -40,7 +40,8 @@ switch(Fetchb()) {
|
|||
else {GetEAa;SaveMw(eaa,0);}
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:GRP7:Illegal call %2X",(rm>>3) &3);
|
||||
GetEAa;
|
||||
LOG(LOG_CPU|LOG_ERROR,"GRP7:Illegal call %2X",(rm>>3) &3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -184,28 +185,20 @@ switch(Fetchb()) {
|
|||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
flags.cf=(*earw & mask)>0;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
flags.cf=(old & mask)>0;
|
||||
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 */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHLW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
RMEwGwOp3(DSHLW,Fetchb());
|
||||
break;
|
||||
case 0xa5: /* SHLD Ew,Gw,CL */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHLW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
RMEwGwOp3(DSHLW,reg_cl);
|
||||
break;
|
||||
/* 0xa6 XBTS (early 386 only) CMPXCHG (early 486 only) */
|
||||
/* 0xa7 IBTS (early 386 only) CMPXCHG (early 486 only) */
|
||||
case 0xa8: /* PUSH GS */
|
||||
|
@ -219,42 +212,26 @@ switch(Fetchb()) {
|
|||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
flags.cf=(*earw & mask)>0;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
*earw|=mask;
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
flags.cf=(old & mask)>0;
|
||||
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 */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHRW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
RMEwGwOp3(DSHRW,Fetchb());
|
||||
break;
|
||||
case 0xad: /* SHRD Ew,Gw,CL */
|
||||
{
|
||||
GetRMrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
|
||||
else {GetEAa;DSHRW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
|
||||
break;
|
||||
}
|
||||
RMEwGwOp3(DSHRW,reg_cl);
|
||||
break;
|
||||
case 0xaf: /* IMUL Gw,Ew */
|
||||
{
|
||||
GetRMrw;
|
||||
Bit32s res;
|
||||
if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*rmrw) * (Bit32s)(*earws);}
|
||||
else {GetEAa;res=(Bit32s)(*rmrw) *(Bit32s)LoadMws(eaa);}
|
||||
*rmrw=res & 0xFFFF;
|
||||
flags.type=t_MUL;
|
||||
if ((res> -32768) && (res<32767)) {flags.cf=false;flags.of=false;}
|
||||
else {flags.cf=true;flags.of=true;}
|
||||
break;
|
||||
}
|
||||
RMGwEwOp3(DIMULW,*rmrw);
|
||||
break;
|
||||
|
||||
/* 0xb0 CMPXCHG Eb,Gb */
|
||||
/* 0xb1 CMPXCHG Ew,Gw */
|
||||
case 0xb2: /* LSS */
|
||||
|
@ -269,11 +246,11 @@ switch(Fetchb()) {
|
|||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
flags.cf=(*earw & mask)>0;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
*earw&= ~mask;
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
flags.cf=(old & mask)>0;
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMw(eaa,old & ~mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
|
@ -312,7 +289,7 @@ switch(Fetchb()) {
|
|||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
Bit16u mask=1 << (Fetchb() & 15);
|
||||
flags.cf=(*earw & mask)>0;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
|
@ -331,7 +308,7 @@ switch(Fetchb()) {
|
|||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
Bit16u mask=1 << (Fetchb() & 15);
|
||||
flags.cf=(old & mask)>0;
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
switch (rm & 0x38) {
|
||||
case 0x20: /* BT */
|
||||
break;
|
||||
|
@ -357,11 +334,11 @@ switch(Fetchb()) {
|
|||
Bit16u mask=1 << (*rmrw & 15);
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArw;
|
||||
flags.cf=(*earw & mask)>0;
|
||||
SETFLAGBIT(CF,(*earw & mask));
|
||||
*earw^=mask;
|
||||
} else {
|
||||
GetEAa;Bit16u old=LoadMw(eaa);
|
||||
flags.cf=(old & mask)>0;
|
||||
SETFLAGBIT(CF,(old & mask));
|
||||
SaveMw(eaa,old ^ mask);
|
||||
}
|
||||
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
|
||||
|
@ -374,11 +351,11 @@ switch(Fetchb()) {
|
|||
if (rm >= 0xc0) { GetEArw; value=*earw; }
|
||||
else { GetEAa; value=LoadMw(eaa); }
|
||||
if (value==0) {
|
||||
flags.zf = true;
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 0;
|
||||
while ((value & 0x01)==0) { result++; value>>=1; }
|
||||
flags.zf = false;
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrw = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
|
@ -391,11 +368,11 @@ switch(Fetchb()) {
|
|||
if (rm >= 0xc0) { GetEArw; value=*earw; }
|
||||
else { GetEAa; value=LoadMw(eaa); }
|
||||
if (value==0) {
|
||||
flags.zf = true;
|
||||
SETFLAGBIT(ZF,true);
|
||||
} else {
|
||||
result = 15; // Operandsize-1
|
||||
while ((value & 0x8000)==0) { result--; value<<=1; }
|
||||
flags.zf = false;
|
||||
SETFLAGBIT(ZF,false);
|
||||
*rmrw = result;
|
||||
}
|
||||
flags.type=t_UNKNOWN;
|
||||
|
|
|
@ -1,20 +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.
|
||||
*/
|
||||
|
||||
/* Setup the CS:IP and SS:SP Pointers */
|
||||
LOADIP;
|
|
@ -1,21 +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.
|
||||
*/
|
||||
|
||||
decode_end:
|
||||
|
||||
SAVEIP;
|
|
@ -32,6 +32,26 @@ static INLINE void ADDIPFAST(Bit16s blah) {
|
|||
IPPoint+=blah;
|
||||
}
|
||||
|
||||
#define CheckTF() \
|
||||
if (GETFLAG(TF)) { \
|
||||
cpudecoder=CPU_Real_16_Slow_Decode_Trap; \
|
||||
goto decode_end; \
|
||||
}
|
||||
|
||||
|
||||
#define EXCEPTION(blah) \
|
||||
{ \
|
||||
Bit8u new_num=blah; \
|
||||
SAVEIP; \
|
||||
if (Interrupt(new_num)) { \
|
||||
if (GETFLAG(TF)) { \
|
||||
cpudecoder=CPU_Real_16_Slow_Decode_Trap; \
|
||||
return 0; \
|
||||
} \
|
||||
goto decode_start; \
|
||||
} else return 0; \
|
||||
}
|
||||
|
||||
static INLINE Bit8u Fetchb() {
|
||||
Bit8u temp=LoadMb(IPPoint);
|
||||
IPPoint+=1;
|
||||
|
@ -82,6 +102,34 @@ static INLINE Bit32u Pop_32() {
|
|||
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 \
|
||||
EAPoint to; \
|
||||
to=SegBase(es)+reg_di
|
||||
|
@ -99,18 +147,12 @@ static INLINE Bit32u Pop_32() {
|
|||
#include "table_ea.h"
|
||||
#include "../modrm.h"
|
||||
|
||||
|
||||
static Bit8s table_df_8[2]={1,-1};
|
||||
static Bit16s table_df_16[2]={2,-2};
|
||||
static Bit32s table_df_32[2]={4,-4};
|
||||
|
||||
|
||||
static void Repeat_Normal(bool testz,bool prefix_66) {
|
||||
|
||||
PhysPt base_si,base_di;
|
||||
|
||||
Bit16s direct;
|
||||
if (flags.df) direct=-1;
|
||||
if (GETFLAG(DF)) direct=-1;
|
||||
else direct=1;
|
||||
base_di=SegBase(es);
|
||||
if (prefix.mark & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op");
|
||||
|
@ -362,48 +404,3 @@ normalexit:
|
|||
PrefixReset;
|
||||
}
|
||||
|
||||
//flags.io and nt shouldn't be compiled for 386
|
||||
#ifdef CPU_386
|
||||
#define Save_Flagsw(FLAGW) \
|
||||
{ \
|
||||
flags.type=t_UNKNOWN; \
|
||||
flags.cf =(FLAGW & 0x001)>0;flags.pf =(FLAGW & 0x004)>0; \
|
||||
flags.af =(FLAGW & 0x010)>0;flags.zf =(FLAGW & 0x040)>0; \
|
||||
flags.sf =(FLAGW & 0x080)>0;flags.tf =(FLAGW & 0x100)>0; \
|
||||
flags.intf =(FLAGW & 0x200)>0; \
|
||||
flags.df =(FLAGW & 0x400)>0;flags.of =(FLAGW & 0x800)>0; \
|
||||
flags.io =(FLAGW >> 12) & 0x03; \
|
||||
flags.nt =(FLAGW & 0x4000)>0; \
|
||||
if (flags.intf && PIC_IRQCheck) { \
|
||||
SAVEIP; \
|
||||
PIC_runIRQs(); \
|
||||
LOADIP; \
|
||||
} \
|
||||
if (flags.tf) { \
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \
|
||||
goto decode_end; \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define Save_Flagsw(FLAGW) \
|
||||
{ \
|
||||
flags.type=t_UNKNOWN; \
|
||||
flags.cf =(FLAGW & 0x001)>0;flags.pf =(FLAGW & 0x004)>0; \
|
||||
flags.af =(FLAGW & 0x010)>0;flags.zf =(FLAGW & 0x040)>0; \
|
||||
flags.sf =(FLAGW & 0x080)>0;flags.tf =(FLAGW & 0x100)>0; \
|
||||
flags.intf =(FLAGW & 0x200)>0; \
|
||||
flags.df =(FLAGW & 0x400)>0;flags.of =(FLAGW & 0x800)>0; \
|
||||
if (flags.intf && PIC_IRQCheck) { \
|
||||
SAVEIP; \
|
||||
PIC_runIRQs(); \
|
||||
LOADIP; \
|
||||
} \
|
||||
if (flags.tf) { \
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \
|
||||
goto decode_end; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -63,12 +63,14 @@ extern Bitu cycle_count;
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
#include "instructions.h"
|
||||
#include "core_16/support.h"
|
||||
static Bitu CPU_Real_16_Slow_Decode_Trap(void);
|
||||
|
||||
static Bitu CPU_Real_16_Slow_Decode(void) {
|
||||
#include "core_16/start.h"
|
||||
decode_start:
|
||||
LOADIP;
|
||||
while (CPU_Cycles>0) {
|
||||
#if C_DEBUG
|
||||
cycle_count++;
|
||||
|
@ -85,7 +87,8 @@ static Bitu CPU_Real_16_Slow_Decode(void) {
|
|||
}
|
||||
CPU_Cycles--;
|
||||
}
|
||||
#include "core_16/stop.h"
|
||||
decode_end:
|
||||
SAVEIP;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
|
@ -96,7 +99,7 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) {
|
|||
CPU_Real_16_Slow_Decode();
|
||||
|
||||
// LOG_DEBUG("TRAP: Trap Flag executed");
|
||||
INTERRUPT(1);
|
||||
Interrupt(1);
|
||||
|
||||
CPU_Cycles = oldCycles-1;
|
||||
cpudecoder = &CPU_Real_16_Slow_Decode;
|
||||
|
@ -107,9 +110,9 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) {
|
|||
|
||||
void CPU_Real_16_Slow_Start(void) {
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode;
|
||||
EAPrefixTable[0]=&GetEA_16_n;
|
||||
EAPrefixTable[1]=&GetEA_16_s;
|
||||
EAPrefixTable[2]=&GetEA_32_n;
|
||||
EAPrefixTable[3]=&GetEA_32_s;
|
||||
EAPrefixTable[0]=&GetEA_16_n;
|
||||
EAPrefixTable[1]=&GetEA_16_s;
|
||||
PrefixReset;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue