New prefix variables and a new string repeat function.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@427
This commit is contained in:
parent
5b84e7c805
commit
15033b27a4
1 changed files with 276 additions and 41 deletions
|
@ -88,8 +88,8 @@ static INLINE Bit32u Pop_32() {
|
|||
|
||||
#define stringSI \
|
||||
EAPoint from; \
|
||||
if (prefixes & PREFIX_SEG) { \
|
||||
from=(segprefix_base+reg_si); \
|
||||
if (prefix.mark & PREFIX_SEG) { \
|
||||
from=(prefix.segbase+reg_si); \
|
||||
PrefixReset; \
|
||||
} else { \
|
||||
from=SegBase(ds)+reg_si; \
|
||||
|
@ -102,48 +102,265 @@ static INLINE Bit32u Pop_32() {
|
|||
#include "instructions.h"
|
||||
|
||||
|
||||
static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) {
|
||||
bool again;
|
||||
do {
|
||||
again=false;
|
||||
Bit8u repcode=Fetchb();
|
||||
switch (repcode) {
|
||||
case 0x26: /* ES Prefix */
|
||||
again=true;
|
||||
from=SegBase(es);
|
||||
break;
|
||||
case 0x2e: /* CS Prefix */
|
||||
again=true;
|
||||
from=SegBase(cs);
|
||||
break;
|
||||
case 0x36: /* SS Prefix */
|
||||
again=true;
|
||||
from=SegBase(ss);
|
||||
break;
|
||||
case 0x3e: /* DS Prefix */
|
||||
again=true;
|
||||
from=SegBase(ds);
|
||||
break;
|
||||
case 0xa5: /* REP MOVSD */
|
||||
for (;reg_cx>0;reg_cx--) {
|
||||
SaveMd(to+reg_di,LoadMd(from+reg_si));
|
||||
reg_di+=direct*4;
|
||||
reg_si+=direct*4;
|
||||
}
|
||||
break;
|
||||
case 0xab: /* REP STOSW */
|
||||
for (;reg_cx>0;reg_cx--) {
|
||||
SaveMd(to+reg_di,reg_eax);
|
||||
reg_di+=direct*4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
E_Exit("CPU:Opcode 66:Illegal REP prefix %2X",repcode);
|
||||
static Bits Repeat_Normal(bool testz,bool prefix_66,Bits count_remain) {
|
||||
|
||||
Bits count=count_remain;
|
||||
PhysPt base_si,base_di;
|
||||
|
||||
Bit16s direct;
|
||||
if (flags.df) direct=-1;
|
||||
else direct=1;
|
||||
base_di=SegBase(es);
|
||||
rep_again:
|
||||
if (prefix.mark & PREFIX_SEG) {
|
||||
base_si=(prefix.segbase);
|
||||
} else {
|
||||
base_si=SegBase(ds);
|
||||
}
|
||||
switch (Fetchb()) {
|
||||
case 0x26: /* ES Prefix */
|
||||
prefix.segbase=SegBase(es);
|
||||
prefix.mark|=PREFIX_SEG;
|
||||
prefix.count++;
|
||||
goto rep_again;
|
||||
case 0x2e: /* CS Prefix */
|
||||
prefix.segbase=SegBase(cs);
|
||||
prefix.mark|=PREFIX_SEG;
|
||||
prefix.count++;
|
||||
goto rep_again;
|
||||
case 0x36: /* SS Prefix */
|
||||
prefix.segbase=SegBase(ss);
|
||||
prefix.mark|=PREFIX_SEG;
|
||||
prefix.count++;
|
||||
goto rep_again;
|
||||
case 0x3e: /* DS Prefix */
|
||||
prefix.segbase=SegBase(ds);
|
||||
prefix.mark|=PREFIX_SEG;
|
||||
prefix.count++;
|
||||
goto rep_again;
|
||||
case 0x66: /* Size Prefix */
|
||||
prefix.count++;
|
||||
prefix_66=!prefix_66;
|
||||
goto rep_again;
|
||||
case 0x6c: /* REP INSB */
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMb(base_di+reg_di,IO_Read(reg_dx));
|
||||
reg_di+=direct;
|
||||
}
|
||||
} while (again);
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0x6d: /* REP INSW/D */
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
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 (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0x6e: /* REP OUTSB */
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
IO_Write(reg_dx,LoadMb(base_si+reg_si));
|
||||
reg_si+=direct;
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0x6f: /* REP OUTSW/D */
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
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 (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xa4: /* REP MOVSB */
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMb(base_di+reg_di,LoadMb(base_si+reg_si));
|
||||
reg_si+=direct;reg_di+=direct;
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xa5: /* REP MOVSW/D */
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMd(base_di+reg_di,LoadMd(base_si+reg_si));
|
||||
reg_si+=direct;reg_di+=direct;
|
||||
}
|
||||
} else {
|
||||
direct*=2;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMw(base_di+reg_di,LoadMw(base_si+reg_si));
|
||||
reg_si+=direct;reg_di+=direct;
|
||||
}
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xa6: /* REP CMPSB */
|
||||
{
|
||||
if (!reg_cx) goto stopit;Bit8u op1,op2;
|
||||
for (;(reg_cx && count>0);) {
|
||||
op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di);
|
||||
reg_cx--,count--;reg_si+=direct;reg_di+=direct;
|
||||
if ((op1==op2)!=testz) break;
|
||||
}
|
||||
CMPB(op1,op2,LoadRb,0);
|
||||
if ((op1==op2)!=testz) goto stopit;
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
}
|
||||
break;
|
||||
case 0xa7: /* REP CMPSW */
|
||||
{
|
||||
if (!reg_cx) goto stopit;
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
Bit32u op1,op2;
|
||||
for (;(reg_cx && count>0);) {
|
||||
op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di);
|
||||
reg_cx--,count--;reg_si+=direct;reg_di+=direct;
|
||||
if ((op1==op2)!=testz) break;
|
||||
}
|
||||
CMPD(op1,op2,LoadRd,0);
|
||||
if ((op1==op2)!=testz) goto stopit;
|
||||
} else {
|
||||
direct*=2;
|
||||
Bit16u op1,op2;
|
||||
for (;(reg_cx && count>0);) {
|
||||
op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di);
|
||||
reg_cx--,count--;reg_si+=direct;reg_di+=direct;
|
||||
if ((op1==op2)!=testz) break;
|
||||
}
|
||||
CMPW(op1,op2,LoadRw,0);
|
||||
if ((op1==op2)!=testz) goto stopit;
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
}
|
||||
break;
|
||||
case 0xaa: /* REP STOSB */
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMb(base_di+reg_di,reg_al);
|
||||
reg_di+=direct;
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xab: /* REP STOSW */
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMd(base_di+reg_di,reg_eax);
|
||||
reg_di+=direct;
|
||||
}
|
||||
} else {
|
||||
direct*=2;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
SaveMw(base_di+reg_di,reg_ax);
|
||||
reg_di+=direct;
|
||||
}
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xac: /* REP LODSB */
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
reg_al=LoadMb(base_si+reg_si);
|
||||
reg_si+=direct;
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xad: /* REP LODSW */
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
reg_eax=LoadMd(base_si+reg_si);
|
||||
reg_si+=direct;
|
||||
}
|
||||
} else {
|
||||
direct*=2;
|
||||
for (;(reg_cx && count>0);reg_cx--,count--) {
|
||||
reg_ax=LoadMw(base_si+reg_si);
|
||||
reg_si+=direct;
|
||||
}
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
break;
|
||||
case 0xae: /* REP SCASB */
|
||||
{
|
||||
if (!reg_cx) goto stopit;Bit8u op2;
|
||||
for (;(reg_cx && count>0);) {
|
||||
op2=LoadMb(base_di+reg_di);
|
||||
reg_cx--,count--;reg_di+=direct;
|
||||
if ((reg_al==op2)!=testz) break;
|
||||
}
|
||||
CMPB(reg_al,op2,LoadRb,0);
|
||||
if ((reg_al==op2)!=testz) goto stopit;
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
}
|
||||
break;
|
||||
case 0xaf: /* REP SCASW */
|
||||
{
|
||||
if (!reg_cx) goto stopit;
|
||||
if (prefix_66) {
|
||||
direct*=4;
|
||||
Bit32u op2;
|
||||
for (;(reg_cx && count>0);) {
|
||||
op2=LoadMd(base_di+reg_di);
|
||||
reg_cx--,count--;reg_di+=direct;
|
||||
if ((reg_eax==op2)!=testz) break;
|
||||
}
|
||||
CMPD(reg_eax,op2,LoadRd,0);
|
||||
if ((reg_eax==op2)!=testz) goto stopit;
|
||||
} else {
|
||||
direct*=2;
|
||||
Bit16u op2;
|
||||
for (;(reg_cx && count>0);) {
|
||||
op2=LoadMw(base_di+reg_di);
|
||||
reg_cx--,count--;reg_di+=direct;
|
||||
if ((reg_ax==op2)!=testz) break;
|
||||
}
|
||||
CMPW(reg_ax,op2,LoadRw,0);
|
||||
if ((reg_ax==op2)!=testz) goto stopit;
|
||||
}
|
||||
if (reg_cx && count<=0) goto countzero;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
IPPoint--;
|
||||
LOG_DEBUG("Unhandled REP Prefix %X",Fetchb());
|
||||
|
||||
}
|
||||
stopit:
|
||||
PrefixReset;
|
||||
return count_remain-count;
|
||||
countzero:
|
||||
IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */
|
||||
PrefixReset;
|
||||
return count_remain;
|
||||
}
|
||||
|
||||
//flags.io and nt shouldn't be compiled for 386
|
||||
#ifdef CPU_386
|
||||
#define Save_Flagsw(FLAGW) \
|
||||
{ \
|
||||
flags.type=t_UNKNOWN; \
|
||||
|
@ -159,7 +376,25 @@ static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) {
|
|||
PIC_runIRQs(); \
|
||||
LOADIP; \
|
||||
} \
|
||||
if (flags.tf) E_Exit("CPU:Trap Flag not supported"); \
|
||||
if (flags.tf) LOG_DEBUG("CPU:Trap Flag not supported"); \
|
||||
}
|
||||
|
||||
#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) LOG_DEBUG("CPU:Trap Flag not supported"); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue