/*
JPC: An x86 PC Hardware Emulator for a pure Java Virtual Machine
Copyright (C) 2012-2013 Ian Preston
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as published by
the Free Software Foundation.
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 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Details (including contact information) can be found at:
jpc.sourceforge.net
or the developer website
sourceforge.net/projects/jpc/
End of licence header
*/
package org.jpc.emulator.execution;
import org.jpc.emulator.execution.*;
import org.jpc.emulator.execution.decoder.*;
import org.jpc.emulator.processor.*;
import static org.jpc.emulator.processor.Processor.*;
import static org.jpc.emulator.execution.Executable.*;
public class StaticOpcodes
{
public static final void aaa(Processor cpu)
{
/*
* Note: This instruction incorrectly documented in Intel's materials.
* The right description is:
*
* IF (((AL and 0FH) > 9) or (AF==1)
* THEN
* IF CPU<286 THEN { AL <- AL+6 }
* ELSE { AX <- AX+6 }
* AH <- AH+1
* CF <- 1
* AF <- 1
* ELSE
* CF <- 0
* AF <- 0
* ENDIF
* AL <- AL and 0Fh
*/
/* Validated against Intel Pentium family hardware. */
boolean cf = false, af = false;
if (((cpu.r_eax.get32() & 0xf) > 9) || cpu.af())
{
cpu.r_ax.set16(cpu.r_ax.get16() + 0x106);
af = cf = true;
}
cpu.r_al.set8(cpu.r_eax.get32() & 0xf);
/* AAA affects also the following flags: Z,S,O,P */
/* modification of the flags is undocumented */
/* The following behaviour seems to match the P6 and
its derived processors. */
cpu.flagResult = cpu.r_eax.get8();
cpu.flagStatus = OSZP;
cpu.af = af;
cpu.cf = cf;
}
public static void aad(Processor cpu, int base)
{
int tl = (cpu.r_eax.get8() & 0xff);
int th = (cpu.r_eax.getHigh() & 0xff);
int ax1 = th * base;
int ax2 = ax1 + tl;
cpu.r_ax.set16(ax2 & 0xff);
//flags
cpu.of = cpu.af = cpu.cf = false;
cpu.flagResult = cpu.r_al.get8();
cpu.flagStatus = SZP;
}
public static void aam(Processor cpu, int base)
{
if (base == 0)
throw ProcessorException.DIVIDE_ERROR;
int inAL = 0xff & cpu.r_al.get8();
int ah = 0xff & (inAL / base);
int al = 0xff & (inAL % base);
cpu.r_eax.set16(al | (ah << 8));
//flags
cpu.of = cpu.af = cpu.cf = false;
cpu.flagResult = cpu.r_al.get8();
cpu.flagStatus = SZP;
}
public static void aas(Processor cpu)
{
boolean cf = false, af = false;
if (((cpu.r_eax.get32() & 0xf) > 9) || cpu.af())
{
cpu.r_ax.set16(cpu.r_ax.get16() - 0x106);
af = cf = true;
}
cpu.r_al.set8(cpu.r_eax.get32() & 0xf);
/* AAS affects also the following flags: Z,S,O,P */
/* modification of the flags is undocumented */
/* The following behaviour seems to match the P6 and
its derived processors. */
cpu.flagResult = cpu.r_eax.get8();
cpu.flagStatus = OSZP;
cpu.af = af;
cpu.cf = cf;
}
public static final void daa(Processor cpu)
{
int tempAL = cpu.r_al.get8() & 0xff;
boolean tempCF = false, tempAF = false;
if (((tempAL & 0xf) > 0x9) || cpu.af())
{
tempCF = (tempAL > 0xF9) || cpu.cf();
cpu.r_al.set8(tempAL + 6);
tempAF = true;
}
if ((tempAL > 0x99) || cpu.cf()) {
cpu.r_al.set8(cpu.r_al.get8() + 0x60);
tempCF = true;
}
cpu.of(false);
cpu.flagResult = (byte)cpu.r_al.get8();
cpu.flagStatus = SZP;
cpu.cf(tempCF);
cpu.af(tempAF);
}
public static final void das(Processor cpu)
{
boolean tempCF = false, tempAF = false;
int tempAL = 0xff & cpu.r_al.get8();
if (((tempAL & 0xf) > 0x9) || cpu.af()) {
tempCF = (tempAL < 0x06) || cpu.cf();
cpu.r_al.set8(tempAL - 0x06);
tempAF = true;
}
if ((tempAL > 0x99) || cpu.cf()) {
cpu.r_al.set8(0xFF & cpu.r_al.get8() - 0x60);
tempCF = true;
}
cpu.of(false); // strictly undefined
cpu.cf(tempCF);
cpu.af(tempAF);
cpu.flagResult = cpu.r_al.get8();
cpu.flagStatus = SZP;
}
public static int lar(Processor cpu, int selector, int original)
{
if ((selector & 0xFFC) == 0)
{
cpu.zf(false);
return original;
}
int offset = selector & 0xfff8;
//allow all normal segments
// and available and busy 32 bit and 16 bit TSS (9, b, 3, 1)
// and ldt and tsk gate (2, 5)
// and 32 bit and 16 bit call gates (c, 4)
final boolean valid[] = {
false, true, true, true,
true, true, false, false,
false, true, false, true,
true, false, false, false,
true, true, true, true,
true, true, true, true,
true, true, true, true,
true, true, true, true
};
Segment descriptorTable;
if ((selector & 0x4) != 0)
descriptorTable = cpu.ldtr;
else
descriptorTable = cpu.gdtr;
if ((offset + 7) > descriptorTable.getLimit()) {
cpu.zf(false);
return original;
}
int descriptor = cpu.readSupervisorDoubleWord(descriptorTable, offset + 4);
int type = (descriptor & 0x1f00) >> 8;
int dpl = (descriptor & 0x6000) >> 13;
int rpl = (selector & 0x3);
int conformingCode = ProtectedModeSegment.TYPE_CODE | ProtectedModeSegment.TYPE_CODE_CONFORMING;
if ((((type & conformingCode) != conformingCode) && ((cpu.getCPL() > dpl) || (rpl > dpl))) || !valid[type])
{
cpu.zf(false);
return original;
} else
{
cpu.zf(true);
return descriptor & 0x00FFFF00;
}
}
public static int lsl(Processor cpu, int selector, int original)
{
int offset = selector & 0xfff8;
final boolean valid[] = {
false, true, true, true,
true, true, false, false,
false, true, false, true,
true, false, false, false,
true, true, true, true,
true, true, true, true,
true, true, true, true,
true, true, true, true
};
Segment descriptorTable;
if ((selector & 0x4) != 0)
descriptorTable = cpu.ldtr;
else
descriptorTable = cpu.gdtr;
if ((offset + 8) > descriptorTable.getLimit()) { //
cpu.zf(false);
return original;
}
int segmentDescriptor = cpu.readSupervisorDoubleWord(descriptorTable, offset + 4);
int type = (segmentDescriptor & 0x1f00) >> 8;
int dpl = (segmentDescriptor & 0x6000) >> 13;
int rpl = (selector & 0x3);
int conformingCode = ProtectedModeSegment.TYPE_CODE | ProtectedModeSegment.TYPE_CODE_CONFORMING;
if ((((type & conformingCode) != conformingCode) && ((cpu.getCPL() > dpl) || (rpl > dpl))) || !valid[type]) {
cpu.zf(false);
return original;
}
int lowsize;
if ((selector & 0x4) != 0) // ldtr or gtdr
lowsize = cpu.readSupervisorWord(cpu.ldtr, offset);
else
lowsize = cpu.readSupervisorWord(cpu.gdtr, offset);
int size = (segmentDescriptor & 0xf0000) | (lowsize & 0xFFFF);
if ((segmentDescriptor & 0x800000) != 0) // granularity ==1
size = (size << 12) | 0xFFF;
cpu.zf(true);
return size;
}
public static void lodsb_a16(Processor cpu, Segment seg)
{
int addr = 0xFFFF & cpu.r_esi.get16();
cpu.r_al.set8(seg.getByte(addr));
if (cpu.df)
addr -= 1;
else
addr += 1;
cpu.r_esi.set16(addr);
}
public static void lodsb_a32(Processor cpu, Segment seg)
{
int addr = cpu.r_esi.get32();
cpu.r_al.set8(seg.getByte(addr));
if (cpu.df)
addr -= 1;
else
addr += 1;
cpu.r_esi.set32(addr);
}
public static void lodsw_a16(Processor cpu, Segment seg)
{
int addr = 0xFFFF & cpu.r_esi.get16();
cpu.r_ax.set16(seg.getWord(addr));
if (cpu.df)
addr -= 2;
else
addr += 2;
cpu.r_esi.set16(addr);
}
public static void lodsw_a32(Processor cpu, Segment seg)
{
int addr = cpu.r_esi.get32();
cpu.r_ax.set16(seg.getWord(addr));
if (cpu.df)
addr -= 2;
else
addr += 2;
cpu.r_esi.set32(addr);
}
public static void lodsd_a16(Processor cpu, Segment seg)
{
int addr = 0xFFFF & cpu.r_esi.get16();
cpu.r_eax.set32(seg.getDoubleWord(addr));
if (cpu.df)
addr -= 4;
else
addr += 4;
cpu.r_esi.set16(addr);
}
public static void lodsd_a32(Processor cpu, Segment seg)
{
int addr = cpu.r_esi.get32();
cpu.r_eax.set32(seg.getDoubleWord(addr));
if (cpu.df)
addr -= 4;
else
addr += 4;
cpu.r_esi.set32(addr);
}
public static void rep_lodsb_a16(Processor cpu, Segment seg)
{
int count = 0xffff & cpu.r_ecx.get16();
int addr = 0xffff & cpu.r_esi.get16();
int data = 0xff & cpu.r_al.get8();
try {
if (cpu.df)
{
while (count != 0)
{
data = 0xff & seg.getByte(addr & 0xffff);
addr -= 1;
count--;
}
}
else
{
while (count != 0)
{
data = 0xff & seg.getByte(addr & 0xffff);
addr += 1;
count--;
}
}
} finally
{
cpu.r_ecx.set16(count);
cpu.r_esi.set16(addr);
cpu.r_al.set8(data);
}
}
public static void rep_lodsb_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int addr = cpu.r_esi.get32();
int data = 0xff & cpu.r_al.get8();
try {
if (cpu.df)
{
while (count != 0)
{
data = 0xff & seg.getByte(addr);
addr -= 1;
count--;
}
}
else
{
while (count != 0)
{
data = 0xff & seg.getByte(addr);
addr += 1;
count--;
}
}
} finally
{
cpu.r_ecx.set32(count);
cpu.r_esi.set32(addr);
cpu.r_al.set8(data);
}
}
public static void rep_lodsw_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int addr = cpu.r_esi.get32();
int data = 0xffff & cpu.r_ax.get16();
try {
if (cpu.df)
{
while (count != 0)
{
data = 0xffff & seg.getWord(addr);
addr -= 2;
count--;
}
}
else
{
while (count != 0)
{
data = 0xffff & seg.getWord(addr);
addr += 2;
count--;
}
}
} finally
{
cpu.r_ecx.set32(count);
cpu.r_esi.set32(addr);
cpu.r_ax.set16(data);
}
}
public static void rep_lodsd_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int addr = cpu.r_esi.get32();
int data = cpu.r_eax.get32();
try {
if (cpu.df)
{
while (count != 0)
{
data = seg.getDoubleWord(addr);
addr -= 4;
count--;
}
}
else
{
while (count != 0)
{
data = seg.getDoubleWord(addr);
addr += 4;
count--;
}
}
} finally
{
cpu.r_ecx.set32(count);
cpu.r_esi.set32(addr);
cpu.r_eax.set32(data);
}
}
public static void cmpsb_a16(Processor cpu, Segment seg)
{
int addrOne = 0xFFFF & cpu.r_si.get16();
int addrTwo = 0xFFFF & cpu.r_di.get16();
int dataOne = seg.getByte(addrOne);
int dataTwo = cpu.es.getByte(addrTwo);
if (cpu.df) {
addrOne -= 1;
addrTwo -= 1;
} else {
addrOne += 1;
addrTwo += 1;
}
cpu.r_di.set16(addrTwo);
cpu.r_si.set16(addrOne);
cpu.flagOp1 = (byte)dataOne;
cpu.flagOp2 = (byte)dataTwo;
cpu.flagResult = (byte)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
public static void cmpsb_a32(Processor cpu, Segment seg)
{
int addrOne = cpu.r_esi.get32();
int addrTwo = cpu.r_edi.get32();
int dataOne = seg.getByte(addrOne);
int dataTwo = cpu.es.getByte(addrTwo);
if (cpu.df) {
addrOne -= 1;
addrTwo -= 1;
} else {
addrOne += 1;
addrTwo += 1;
}
cpu.r_edi.set32(addrTwo);
cpu.r_esi.set32(addrOne);
cpu.flagOp1 = (byte)dataOne;
cpu.flagOp2 = (byte)dataTwo;
cpu.flagResult = (byte)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
public static void cmpsw_a16(Processor cpu, Segment seg)
{
int addrOne = 0xFFFF & cpu.r_si.get16();
int addrTwo = 0xFFFF & cpu.r_di.get16();
int dataOne = seg.getWord(addrOne);
int dataTwo = cpu.es.getWord(addrTwo);
if (cpu.df) {
addrOne -= 2;
addrTwo -= 2;
} else {
addrOne += 2;
addrTwo += 2;
}
cpu.r_di.set16(addrTwo);
cpu.r_si.set16(addrOne);
cpu.flagOp1 = (short)dataOne;
cpu.flagOp2 = (short)dataTwo;
cpu.flagResult = (short)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
public static void cmpsw_a32(Processor cpu, Segment seg)
{
int addrOne = cpu.r_esi.get32();
int addrTwo = cpu.r_edi.get32();
int dataOne = seg.getWord(addrOne);
int dataTwo = cpu.es.getWord(addrTwo);
if (cpu.df) {
addrOne -= 2;
addrTwo -= 2;
} else {
addrOne += 2;
addrTwo += 2;
}
cpu.r_di.set32(addrTwo);
cpu.r_si.set32(addrOne);
cpu.flagOp1 = (short)dataOne;
cpu.flagOp2 = (short)dataTwo;
cpu.flagResult = (short)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
public static void cmpsd_a16(Processor cpu, Segment seg)
{
int addrOne = 0xFFFF & cpu.r_si.get16();
int addrTwo = 0xFFFF & cpu.r_di.get16();
int dataOne = seg.getDoubleWord(addrOne);
int dataTwo = cpu.es.getDoubleWord(addrTwo);
if (cpu.df) {
addrOne -= 4;
addrTwo -= 4;
} else {
addrOne += 4;
addrTwo += 4;
}
cpu.r_di.set16(addrTwo);
cpu.r_si.set16(addrOne);
cpu.flagOp1 = dataOne;
cpu.flagOp2 = dataTwo;
cpu.flagResult = dataOne-dataTwo;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
public static void cmpsd_a32(Processor cpu, Segment seg)
{
int addrOne = cpu.r_esi.get32();
int addrTwo = cpu.r_edi.get32();
int dataOne = seg.getDoubleWord(addrOne);
int dataTwo = cpu.es.getDoubleWord(addrTwo);
if (cpu.df) {
addrOne -= 4;
addrTwo -= 4;
} else {
addrOne += 4;
addrTwo += 4;
}
cpu.r_di.set32(addrTwo);
cpu.r_si.set32(addrOne);
cpu.flagOp1 = dataOne;
cpu.flagOp2 = dataTwo;
cpu.flagResult = dataOne-dataTwo;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
public static void rep_cmpsb_a16(Processor cpu, Segment seg)
{
int count = 0xFFFF & cpu.r_cx.get16();
int addrOne = 0xFFFF & cpu.r_si.get16();
int addrTwo = 0xFFFF & cpu.r_di.get16();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getByte(addrOne & 0xffff);
dataTwo = cpu.es.getByte(addrTwo & 0xffff);
count--;
addrOne -= 1;
addrTwo -= 1;
if (dataOne != dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getByte(addrOne & 0xffff);
dataTwo = cpu.es.getByte(addrTwo & 0xffff);
count--;
addrOne += 1;
addrTwo += 1;
if (dataOne != dataTwo)
break;
}
}
}
finally {
cpu.r_cx.set16(count);
cpu.r_di.set16(addrTwo);
cpu.r_si.set16(addrOne);
cpu.flagOp1 = (byte)dataOne;
cpu.flagOp2 = (byte)dataTwo;
cpu.flagResult = (byte)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static void rep_cmpsb_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int addrOne = cpu.r_esi.get32();
int addrTwo = cpu.r_edi.get32();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getByte(addrOne);
dataTwo = cpu.es.getByte(addrTwo);
count--;
addrOne -= 1;
addrTwo -= 1;
if (dataOne != dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getByte(addrOne);
dataTwo = cpu.es.getByte(addrTwo);
count--;
addrOne += 1;
addrTwo += 1;
if (dataOne != dataTwo)
break;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addrTwo);
cpu.r_esi.set32(addrOne);
cpu.flagOp1 = (byte)dataOne;
cpu.flagOp2 = (byte)dataTwo;
cpu.flagResult = (byte)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static void repne_cmpsb_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int addrOne = cpu.r_esi.get32();
int addrTwo = cpu.r_edi.get32();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getByte(addrOne);
dataTwo = cpu.es.getByte(addrTwo);
count--;
addrOne -= 1;
addrTwo -= 1;
if (dataOne == dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getByte(addrOne);
dataTwo = cpu.es.getByte(addrTwo);
count--;
addrOne += 1;
addrTwo += 1;
if (dataOne == dataTwo)
break;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addrTwo);
cpu.r_esi.set32(addrOne);
cpu.flagOp1 = (byte)dataOne;
cpu.flagOp2 = (byte)dataTwo;
cpu.flagResult = (byte)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static void rep_cmpsw_a16(Processor cpu, Segment seg)
{
int count = 0xFFFF & cpu.r_cx.get16();
int addrOne = 0xFFFF & cpu.r_si.get16();
int addrTwo = 0xFFFF & cpu.r_di.get16();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getWord(addrOne & 0xffff);
dataTwo = cpu.es.getWord(addrTwo & 0xffff);
count--;
addrOne -= 2;
addrTwo -= 2;
if (dataOne != dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getWord(addrOne & 0xffff);
dataTwo = cpu.es.getWord(addrTwo & 0xffff);
count--;
addrOne += 2;
addrTwo += 2;
if (dataOne != dataTwo)
break;
}
}
}
finally {
cpu.r_cx.set16(count);
cpu.r_di.set16(addrTwo);
cpu.r_si.set16(addrOne);
cpu.flagOp1 = (short)dataOne;
cpu.flagOp2 = (short)dataTwo;
cpu.flagResult = (short)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static void rep_cmpsw_a32(Processor cpu, Segment seg)
{
int count = cpu.r_cx.get32();
int addrOne = cpu.r_si.get32();
int addrTwo = cpu.r_di.get32();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getWord(addrOne);
dataTwo = cpu.es.getWord(addrTwo);
count--;
addrOne -= 2;
addrTwo -= 2;
if (dataOne != dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getWord(addrOne);
dataTwo = cpu.es.getWord(addrTwo);
count--;
addrOne += 2;
addrTwo += 2;
if (dataOne != dataTwo)
break;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addrTwo);
cpu.r_esi.set32(addrOne);
cpu.flagOp1 = (short)dataOne;
cpu.flagOp2 = (short)dataTwo;
cpu.flagResult = (short)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static void repne_cmpsw_a32(Processor cpu, Segment seg)
{
int count = cpu.r_cx.get32();
int addrOne = cpu.r_si.get32();
int addrTwo = cpu.r_di.get32();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getWord(addrOne);
dataTwo = cpu.es.getWord(addrTwo);
count--;
addrOne -= 2;
addrTwo -= 2;
if (dataOne == dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getWord(addrOne);
dataTwo = cpu.es.getWord(addrTwo);
count--;
addrOne += 2;
addrTwo += 2;
if (dataOne == dataTwo)
break;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addrTwo);
cpu.r_esi.set32(addrOne);
cpu.flagOp1 = (short)dataOne;
cpu.flagOp2 = (short)dataTwo;
cpu.flagResult = (short)(dataOne-dataTwo);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static void rep_cmpsd_a16(Processor cpu, Segment seg)
{
int count = 0xFFFF & cpu.r_cx.get16();
int addrOne = 0xFFFF & cpu.r_si.get16();
int addrTwo = 0xFFFF & cpu.r_di.get16();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getDoubleWord(addrOne & 0xffff);
dataTwo = cpu.es.getDoubleWord(addrTwo & 0xffff);
count--;
addrOne -= 4;
addrTwo -= 4;
if (dataOne != dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getDoubleWord(addrOne & 0xffff);
dataTwo = cpu.es.getDoubleWord(addrTwo & 0xffff);
count--;
addrOne += 4;
addrTwo += 4;
if (dataOne != dataTwo)
break;
}
}
}
finally {
cpu.r_cx.set16(count);
cpu.r_di.set16(addrTwo);
cpu.r_si.set16(addrOne);
cpu.flagOp1 = dataOne;
cpu.flagOp2 = dataTwo;
cpu.flagResult = (dataOne-dataTwo);
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static void rep_cmpsd_a32(Processor cpu, Segment seg)
{
int count = cpu.r_cx.get32();
int addrOne = cpu.r_si.get32();
int addrTwo = cpu.r_di.get32();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getDoubleWord(addrOne);
dataTwo = cpu.es.getDoubleWord(addrTwo);
count--;
addrOne -= 4;
addrTwo -= 4;
if (dataOne != dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getDoubleWord(addrOne);
dataTwo = cpu.es.getDoubleWord(addrTwo);
count--;
addrOne += 4;
addrTwo += 4;
if (dataOne != dataTwo)
break;
}
}
}
finally {
cpu.r_cx.set32(count);
cpu.r_di.set32(addrTwo);
cpu.r_si.set32(addrOne);
cpu.flagOp1 = dataOne;
cpu.flagOp2 = dataTwo;
cpu.flagResult = (dataOne-dataTwo);
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static void repne_cmpsd_a32(Processor cpu, Segment seg)
{
int count = cpu.r_cx.get32();
int addrOne = cpu.r_si.get32();
int addrTwo = cpu.r_di.get32();
int dataOne =0, dataTwo =0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
dataOne = seg.getDoubleWord(addrOne);
dataTwo = cpu.es.getDoubleWord(addrTwo);
count--;
addrOne -= 4;
addrTwo -= 4;
if (dataOne == dataTwo)
break;
}
} else {
while (count != 0) {
dataOne = seg.getDoubleWord(addrOne);
dataTwo = cpu.es.getDoubleWord(addrTwo);
count--;
addrOne += 4;
addrTwo += 4;
if (dataOne == dataTwo)
break;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addrTwo);
cpu.r_esi.set32(addrOne);
cpu.flagOp1 = dataOne;
cpu.flagOp2 = dataTwo;
cpu.flagResult = (dataOne-dataTwo);
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static void movsb_a16(Processor cpu, Segment seg)
{
int inAddr = cpu.r_edi.get16() & 0xffff;
int outAddr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
//check hardware interrupts
cpu.es.setByte(inAddr & 0xffff, seg.getByte(outAddr & 0xffff));
outAddr -= 1;
inAddr -= 1;
} else {
//check hardware interrupts
cpu.es.setByte(inAddr & 0xffff, seg.getByte(outAddr & 0xffff));
outAddr += 1;
inAddr += 1;
}
}
finally {
cpu.r_edi.set16(inAddr & 0xffff);
cpu.r_esi.set16(outAddr & 0xffff);
}
}
public static void movsb_a32(Processor cpu, Segment seg)
{
int inAddr = cpu.r_edi.get32();
int outAddr = cpu.r_esi.get32();
try {
if (cpu.df) {
//check hardware interrupts
cpu.es.setByte(inAddr, seg.getByte(outAddr));
outAddr -= 1;
inAddr -= 1;
} else {
//check hardware interrupts
cpu.es.setByte(inAddr, seg.getByte(outAddr));
outAddr += 1;
inAddr += 1;
}
}
finally {
cpu.r_edi.set32(inAddr);
cpu.r_esi.set32(outAddr);
}
}
public static void movsw_a16(Processor cpu, Segment seg)
{
int inAddr = cpu.r_edi.get16() & 0xffff;
int outAddr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
//check hardware interrupts
cpu.es.setWord(inAddr & 0xffff, seg.getWord(outAddr & 0xffff));
outAddr -= 2;
inAddr -= 2;
} else {
//check hardware interrupts
cpu.es.setWord(inAddr & 0xffff, seg.getWord(outAddr & 0xffff));
outAddr += 2;
inAddr += 2;
}
}
finally {
cpu.r_edi.set16(inAddr & 0xffff);
cpu.r_esi.set16(outAddr & 0xffff);
}
}
public static void movsw_a32(Processor cpu, Segment seg)
{
int inAddr = cpu.r_edi.get32();
int outAddr = cpu.r_esi.get32();
try {
if (cpu.df) {
//check hardware interrupts
cpu.es.setWord(inAddr, seg.getWord(outAddr));
outAddr -= 2;
inAddr -= 2;
} else {
//check hardware interrupts
cpu.es.setWord(inAddr, seg.getWord(outAddr));
outAddr += 2;
inAddr += 2;
}
}
finally {
cpu.r_edi.set32(inAddr);
cpu.r_esi.set32(outAddr);
}
}
public static void movsd_a16(Processor cpu, Segment seg)
{
int inAddr = cpu.r_edi.get16() & 0xffff;
int outAddr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
//check hardware interrupts
cpu.es.setDoubleWord(inAddr & 0xffff, seg.getDoubleWord(outAddr & 0xffff));
outAddr -= 4;
inAddr -= 4;
} else {
//check hardware interrupts
cpu.es.setDoubleWord(inAddr & 0xffff, seg.getDoubleWord(outAddr & 0xffff));
outAddr += 4;
inAddr += 4;
}
}
finally {
cpu.r_edi.set16(inAddr & 0xffff);
cpu.r_esi.set16(outAddr & 0xffff);
}
}
public static void movsd_a32(Processor cpu, Segment seg)
{
int inAddr = cpu.r_edi.get32();
int outAddr = cpu.r_esi.get32();
try {
if (cpu.df) {
//check hardware interrupts
cpu.es.setDoubleWord(inAddr, seg.getDoubleWord(outAddr));
outAddr -= 4;
inAddr -= 4;
} else {
//check hardware interrupts
cpu.es.setDoubleWord(inAddr, seg.getDoubleWord(outAddr));
outAddr += 4;
inAddr += 4;
}
}
finally {
cpu.r_edi.set32(inAddr);
cpu.r_esi.set32(outAddr);
}
}
public static void rep_movsb_a16(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get16() & 0xffff;
int inAddr = cpu.r_edi.get16() & 0xffff;
int outAddr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
cpu.es.setByte(inAddr & 0xffff, seg.getByte(outAddr & 0xffff));
count--;
outAddr -= 1;
inAddr -= 1;
}
} else {
while (count != 0) {
//check hardware interrupts
cpu.es.setByte(inAddr & 0xffff, seg.getByte(outAddr & 0xffff));
count--;
outAddr += 1;
inAddr += 1;
}
}
}
finally {
cpu.r_ecx.set16(count & 0xffff);
cpu.r_edi.set16(inAddr & 0xffff);
cpu.r_esi.set16(outAddr & 0xffff);
}
}
public static void rep_movsb_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int inAddr = cpu.r_edi.get32();
int outAddr = cpu.r_esi.get32();
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
cpu.es.setByte(inAddr, seg.getByte(outAddr));
count--;
outAddr -= 1;
inAddr -= 1;
}
} else {
while (count != 0) {
//check hardware interrupts
cpu.es.setByte(inAddr, seg.getByte(outAddr));
count--;
outAddr += 1;
inAddr += 1;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(inAddr);
cpu.r_esi.set32(outAddr);
}
}
public static void rep_movsw_a16(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get16() & 0xffff;
int inAddr = cpu.r_edi.get16() & 0xffff;
int outAddr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
cpu.es.setWord(inAddr & 0xffff, seg.getWord(outAddr & 0xffff));
count--;
outAddr -= 2;
inAddr -= 2;
}
} else {
while (count != 0) {
//check hardware interrupts
cpu.es.setWord(inAddr & 0xffff, seg.getWord(outAddr & 0xffff));
count--;
outAddr += 2;
inAddr += 2;
}
}
}
finally {
cpu.r_ecx.set16(count & 0xffff);
cpu.r_edi.set16(inAddr & 0xffff);
cpu.r_esi.set16(outAddr & 0xffff);
}
}
public static void rep_movsw_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int inAddr = cpu.r_edi.get32();
int outAddr = cpu.r_esi.get32();
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
cpu.es.setWord(inAddr, seg.getWord(outAddr));
count--;
outAddr -= 2;
inAddr -= 2;
}
} else {
while (count != 0) {
//check hardware interrupts
cpu.es.setWord(inAddr, seg.getWord(outAddr));
count--;
outAddr += 2;
inAddr += 2;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(inAddr);
cpu.r_esi.set32(outAddr);
}
}
public static void rep_movsd_a32(Processor cpu, Segment seg)
{
int count = cpu.r_ecx.get32();
int targetAddr = cpu.r_edi.get32();
int srcAddr = cpu.r_esi.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setDoubleWord(targetAddr, seg.getDoubleWord(srcAddr));
count--;
srcAddr -= 4;
targetAddr -= 4;
}
} else {
while (count != 0) {
cpu.es.setDoubleWord(targetAddr, seg.getDoubleWord(srcAddr));
count--;
srcAddr += 4;
targetAddr += 4;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(targetAddr);
cpu.r_esi.set32(srcAddr);
}
}
public static void rep_movsd_a16(Processor cpu, Segment seg)
{
int count = 0xffff & cpu.r_cx.get16();
int targetAddr = 0xffff & cpu.r_di.get16();
int srcAddr = 0xffff & cpu.r_esi.get16();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setDoubleWord(targetAddr & 0xffff, seg.getDoubleWord(srcAddr & 0xffff));
count--;
srcAddr -= 4;
targetAddr -= 4;
}
} else {
while (count != 0) {
cpu.es.setDoubleWord(targetAddr & 0xffff, seg.getDoubleWord(srcAddr & 0xffff));
count--;
srcAddr += 4;
targetAddr += 4;
}
}
}
finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(targetAddr);
cpu.r_esi.set16(srcAddr);
}
}
public static void insb_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_di.get16() & 0xffff;
seg.setByte(addr & 0xffff, (byte)0); // test memory writable
seg.setByte(addr, (byte)cpu.ioports.ioPortRead8(port));
if (cpu.df) {
addr -= 1;
} else {
addr += 1;
}
cpu.r_di.set16(addr);
}
public static void insb_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_edi.get32();
seg.setByte(addr, (byte)0); // test memory writable
seg.setByte(addr, (byte)cpu.ioports.ioPortRead8(port));
if (cpu.df) {
addr -= 1;
} else {
addr += 1;
}
cpu.r_edi.set32(addr);
}
public static void insw_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_di.get16() & 0xffff;
seg.setWord(addr & 0xffff, (short)0); // test memory writable
seg.setWord(addr, (short)cpu.ioports.ioPortRead16(port));
if (cpu.df) {
addr -= 2;
} else {
addr += 2;
}
cpu.r_di.set16(addr);
}
public static void insw_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_edi.get32();
seg.setWord(addr, (short)0); // test memory writable
seg.setWord(addr, (short)cpu.ioports.ioPortRead16(port));
if (cpu.df) {
addr -= 2;
} else {
addr += 2;
}
cpu.r_di.set32(addr);
}
public static void rep_insb_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
seg.setByte(addr, (byte)0); // test memory writable
seg.setByte(addr, (byte)cpu.ioports.ioPortRead8(port));
count--;
addr -= 1;
}
} else {
while (count != 0) {
//check hardware interrupts
seg.setByte(addr, (byte)0); // test memory writable
seg.setByte(addr, (byte)cpu.ioports.ioPortRead8(port));
count--;
addr += 1;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
}
}
public static void rep_insw_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
seg.setWord(addr & 0xffff, (short)0); // test memory writable
seg.setWord(addr & 0xffff, (short)cpu.ioports.ioPortRead16(port));
count--;
addr -= 2;
}
} else {
while (count != 0) {
//check hardware interrupts
seg.setWord(addr & 0xffff, (short)0); // test memory writable
seg.setWord(addr & 0xffff, (short)cpu.ioports.ioPortRead16(port));
count--;
addr += 2;
}
}
}
finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
}
}
public static void rep_insw_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
seg.setWord(addr, (short)0); // test memory writable
seg.setWord(addr, (short)cpu.ioports.ioPortRead16(port));
count--;
addr -= 2;
}
} else {
while (count != 0) {
//check hardware interrupts
seg.setWord(addr, (short)0); // test memory writable
seg.setWord(addr, (short)cpu.ioports.ioPortRead16(port));
count--;
addr += 2;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
}
}
public static void rep_insd_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
seg.setDoubleWord(addr & 0xffff, 0); // test memory writable
seg.setDoubleWord(addr & 0xffff, cpu.ioports.ioPortRead32(port));
count--;
addr -= 4;
}
} else {
while (count != 0) {
//check hardware interrupts
seg.setDoubleWord(addr & 0xffff, 0); // test memory writable
seg.setDoubleWord(addr & 0xffff, cpu.ioports.ioPortRead32(port));
count--;
addr += 4;
}
}
}
finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
}
}
public static void rep_insd_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
try {
if (cpu.df) {
while (count != 0) {
//check hardware interrupts
seg.setDoubleWord(addr, 0); // test memory writable
seg.setDoubleWord(addr, cpu.ioports.ioPortRead32(port));
count--;
addr -= 4;
}
} else {
while (count != 0) {
//check hardware interrupts
seg.setDoubleWord(addr, 0); // test memory writable
seg.setDoubleWord(addr, cpu.ioports.ioPortRead32(port));
count--;
addr += 4;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
}
}
public static void outsb_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_si.get16() & 0xffff;
cpu.ioports.ioPortWrite8(port, 0xff & seg.getByte(addr));
if (cpu.df) {
addr -= 1;
} else {
addr += 1;
}
cpu.r_si.set16(addr);
}
public static void outsb_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_esi.get32();
cpu.ioports.ioPortWrite8(port, 0xff & seg.getByte(addr));
if (cpu.df) {
addr -= 1;
} else {
addr += 1;
}
cpu.r_esi.set32(addr);
}
public static void outsw_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_si.get16() & 0xffff;
cpu.ioports.ioPortWrite16(port, 0xffff & seg.getWord(addr));
if (cpu.df) {
addr -= 2;
} else {
addr += 2;
}
cpu.r_si.set16(addr);
}
public static void outsd_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_si.get16() & 0xffff;
cpu.ioports.ioPortWrite32(port, seg.getDoubleWord(addr));
if (cpu.df) {
addr -= 4;
} else {
addr += 4;
}
cpu.r_si.set16(addr);
}
public static void outsd_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int addr = cpu.r_esi.get32();
cpu.ioports.ioPortWrite32(port, seg.getDoubleWord(addr));
if (cpu.df) {
addr -= 4;
} else {
addr += 4;
}
cpu.r_esi.set32(addr);
}
public static void rep_outsb_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
cpu.ioports.ioPortWrite8(port, 0xff & seg.getByte(addr & 0xffff));
count--;
addr -= 1;
}
} else {
while (count != 0) {
cpu.ioports.ioPortWrite8(port, 0xff & seg.getByte(addr & 0xffff));
count--;
addr += 1;
}
}
}
finally {
cpu.r_ecx.set16(count);
cpu.r_esi.set16(addr);
}
}
public static void rep_outsb_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get32();
int addr = cpu.r_esi.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.ioports.ioPortWrite8(port, 0xff & seg.getByte(addr & 0xffff));
count--;
addr -= 1;
}
} else {
while (count != 0) {
cpu.ioports.ioPortWrite8(port, 0xff & seg.getByte(addr & 0xffff));
count--;
addr += 1;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_esi.set32(addr);
}
}
public static void rep_outsw_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
cpu.ioports.ioPortWrite16(port, 0xffff & seg.getWord(addr & 0xffff));
count--;
addr -= 2;
}
} else {
while (count != 0) {
cpu.ioports.ioPortWrite16(port, 0xffff & seg.getWord(addr & 0xffff));
count--;
addr += 2;
}
}
}
finally {
cpu.r_ecx.set16(count);
cpu.r_esi.set16(addr);
}
}
public static void rep_outsw_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get32();
int addr = cpu.r_esi.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.ioports.ioPortWrite16(port, 0xffff & seg.getWord(addr));
count--;
addr -= 2;
}
} else {
while (count != 0) {
cpu.ioports.ioPortWrite16(port, 0xffff & seg.getWord(addr));
count--;
addr += 2;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_esi.set32(addr);
}
}
public static void rep_outsd_a16(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_esi.get16() & 0xffff;
try {
if (cpu.df) {
while (count != 0) {
cpu.ioports.ioPortWrite32(port, seg.getDoubleWord(addr & 0xffff));
count--;
addr -= 4;
}
} else {
while (count != 0) {
cpu.ioports.ioPortWrite32(port, seg.getDoubleWord(addr & 0xffff));
count--;
addr += 4;
}
}
}
finally {
cpu.r_ecx.set16(count);
cpu.r_esi.set16(addr);
}
}
public static void rep_outsd_a32(Processor cpu, Segment seg)
{
int port = cpu.r_dx.get16() & 0xffff;
int count = cpu.r_ecx.get32();
int addr = cpu.r_esi.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.ioports.ioPortWrite32(port, seg.getDoubleWord(addr));
count--;
addr -= 4;
}
} else {
while (count != 0) {
cpu.ioports.ioPortWrite32(port, seg.getDoubleWord(addr));
count--;
addr += 4;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_esi.set32(addr);
}
}
public static void rep_stosb_a16(Processor cpu)
{
int count = cpu.r_cx.get16() & 0xffff;
int tAddr = cpu.r_di.get16() & 0xffff;
byte data = (byte)cpu.r_al.get8();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setByte(tAddr & 0xffff, data);
count--;
tAddr -= 1;
}
} else {
while (count != 0) {
cpu.es.setByte(tAddr & 0xffff, data);
count--;
tAddr += 1;
}
}
}
finally {
cpu.r_cx.set16(count);
cpu.r_di.set16(tAddr);
}
}
public static void rep_stosb_a32(Processor cpu)
{
int count = cpu.r_ecx.get32();
int tAddr = cpu.r_edi.get32();
int data = cpu.r_al.get8();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setByte(tAddr, (byte) data);
count--;
tAddr -= 1;
}
} else {
while (count != 0) {
cpu.es.setByte(tAddr, (byte) data);
count--;
tAddr += 1;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(tAddr);
}
}
public static void stosb_a16(Processor cpu)
{
int tAddr = cpu.r_di.get16() & 0xffff;
byte data = (byte)cpu.r_al.get8();
try {
if (cpu.df) {
cpu.es.setByte(tAddr, data);
tAddr -= 1;
} else {
cpu.es.setByte(tAddr, data);
tAddr += 1;
}
}
finally {
cpu.r_di.set16(tAddr);
}
}
public static void stosb_a32(Processor cpu)
{
int tAddr = cpu.r_di.get32();
byte data = (byte)cpu.r_al.get8();
try {
if (cpu.df) {
cpu.es.setByte(tAddr, data);
tAddr -= 1;
} else {
cpu.es.setByte(tAddr, data);
tAddr += 1;
}
}
finally {
cpu.r_di.set32(tAddr);
}
}
public static void stosw_a16(Processor cpu)
{
int tAddr = cpu.r_di.get16() & 0xffff;
short data = (short)cpu.r_ax.get16();
try {
if (cpu.df) {
cpu.es.setWord(tAddr, data);
tAddr -= 2;
} else {
cpu.es.setWord(tAddr, data);
tAddr += 2;
}
}
finally {
cpu.r_di.set16(tAddr);
}
}
public static void stosw_a32(Processor cpu)
{
int tAddr = cpu.r_di.get32();
short data = (short)cpu.r_ax.get16();
try {
if (cpu.df) {
cpu.es.setWord(tAddr, data);
tAddr -= 2;
} else {
cpu.es.setWord(tAddr, data);
tAddr += 2;
}
}
finally {
cpu.r_di.set32(tAddr);
}
}
public static void stosd_a16(Processor cpu)
{
int tAddr = cpu.r_di.get16() & 0xffff;
int data = cpu.r_eax.get32();
try {
if (cpu.df) {
cpu.es.setDoubleWord(tAddr, data);
tAddr -= 4;
} else {
cpu.es.setDoubleWord(tAddr, data);
tAddr += 4;
}
}
finally {
cpu.r_di.set16(tAddr);
}
}
public static void stosd_a32(Processor cpu)
{
int tAddr = cpu.r_edi.get32();
int data = cpu.r_eax.get32();
try {
if (cpu.df) {
cpu.es.setDoubleWord(tAddr, data);
tAddr -= 4;
} else {
cpu.es.setDoubleWord(tAddr, data);
tAddr += 4;
}
}
finally {
cpu.r_edi.set32(tAddr);
}
}
public static void rep_stosw_a16(Processor cpu)
{
int count = cpu.r_cx.get16() & 0xffff;
int tAddr = cpu.r_di.get16() & 0xffff;
short data = (short)cpu.r_ax.get16();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setWord(tAddr & 0xffff, data);
count--;
tAddr -= 2;
}
} else {
while (count != 0) {
cpu.es.setWord(tAddr & 0xffff, data);
count--;
tAddr += 2;
}
}
}
finally {
cpu.r_cx.set16(count);
cpu.r_di.set16(tAddr);
}
}
public static void rep_stosw_a32(Processor cpu)
{
int count = cpu.r_ecx.get32();
int tAddr = cpu.r_edi.get32();
short data = (short)cpu.r_eax.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setWord(tAddr, data);
count--;
tAddr -= 2;
}
} else {
while (count != 0) {
cpu.es.setWord(tAddr, data);
count--;
tAddr += 2;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(tAddr);
}
}
public static void rep_stosd_a16(Processor cpu)
{
int count = cpu.r_cx.get16() & 0xffff;
int tAddr = cpu.r_di.get16() & 0xffff;
int data = cpu.r_eax.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setDoubleWord(tAddr & 0xffff, data);
count--;
tAddr -= 4;
}
} else {
while (count != 0) {
cpu.es.setDoubleWord(tAddr & 0xffff, data);
count--;
tAddr += 4;
}
}
}
finally {
cpu.r_cx.set16(count);
cpu.r_di.set16(tAddr);
}
}
public static void rep_stosd_a32(Processor cpu)
{
int count = cpu.r_ecx.get32();
int tAddr = cpu.r_edi.get32();
int data = cpu.r_eax.get32();
try {
if (cpu.df) {
while (count != 0) {
cpu.es.setDoubleWord(tAddr, data);
count--;
tAddr -= 4;
}
} else {
while (count != 0) {
cpu.es.setDoubleWord(tAddr, data);
count--;
tAddr += 4;
}
}
}
finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(tAddr);
}
}
public static final void scasb_a16(Processor cpu)
{
int data = 0xff & cpu.r_ax.get8();
int addr = cpu.r_edi.get16() & 0xffff;
int input = 0;
try {
if (cpu.df) {
input = 0xff & cpu.es.getByte(addr);
addr -= 1;
} else {
input = 0xff & cpu.es.getByte(addr);
addr += 1;
}
} finally {
cpu.r_edi.set16(addr & 0xffff);
cpu.flagOp1 = (byte)data;
cpu.flagOp2 = (byte)input;
cpu.flagResult = (byte)(data-input);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static final void scasb_a32(Processor cpu)
{
int data = 0xff & cpu.r_ax.get8();
int addr = cpu.r_edi.get32();
int input = 0;
try {
if (cpu.df) {
input = 0xff & cpu.es.getByte(addr);
addr -= 1;
} else {
input = 0xff & cpu.es.getByte(addr);
addr += 1;
}
} finally {
cpu.r_edi.set32(addr);
cpu.flagOp1 = (byte)data;
cpu.flagOp2 = (byte)input;
cpu.flagResult = (byte)(data-input);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static final void scasw_a16(Processor cpu)
{
int data = 0xffff & cpu.r_ax.get16();
int addr = cpu.r_edi.get16() & 0xffff;
int input = 0;
try {
if (cpu.df) {
input = 0xffff & cpu.es.getWord(addr);
addr -= 2;
} else {
input = 0xffff & cpu.es.getWord(addr);
addr += 2;
}
} finally {
cpu.r_edi.set16(addr & 0xffff);
cpu.flagOp1 = (short)data;
cpu.flagOp2 = (short)input;
cpu.flagResult = (short)data-input;
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static final void scasw_a32(Processor cpu)
{
int data = 0xffff & cpu.r_ax.get16();
int addr = cpu.r_edi.get32();
int input = 0;
try {
if (cpu.df) {
input = 0xffff & cpu.es.getWord(addr);
addr -= 2;
} else {
input = 0xffff & cpu.es.getWord(addr);
addr += 2;
}
} finally {
cpu.r_edi.set32(addr);
cpu.flagOp1 = (short)data;
cpu.flagOp2 = (short)input;
cpu.flagResult = (short)data-input;
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static final void scasd_a32(Processor cpu)
{
int data = cpu.r_eax.get32();
int addr = cpu.r_edi.get32();
int input = 0;
try {
if (cpu.df) {
input = cpu.es.getDoubleWord(addr);
addr -= 4;
} else {
input = cpu.es.getDoubleWord(addr);
addr += 4;
}
} finally {
cpu.r_edi.set32(addr);
cpu.flagOp1 = data;
cpu.flagOp2 = input;
cpu.flagResult = data-input;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static final void repne_scasb_a16(Processor cpu)
{
int data = 0xff & cpu.r_al.get8();
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
boolean used = count != 0;
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr & 0xffff);
count--;
addr -= 1;
if (data == input) break;
}
} else {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr & 0xffff);
count--;
addr += 1;
if (data == input) break;
}
}
} finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
cpu.flagOp1 = (byte)data;
cpu.flagOp2 = (byte)input;
cpu.flagResult = (byte)(data-input);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static final void repe_scasb_a16(Processor cpu)
{
int data = 0xff & cpu.r_al.get8();
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
boolean used = count != 0;
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr & 0xffff);
count--;
addr -= 1;
if (data != input) break;
}
} else {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr & 0xffff);
count--;
addr += 1;
if (data != input) break;
}
}
} finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
cpu.flagOp1 = (byte)data;
cpu.flagOp2 = (byte)input;
cpu.flagResult = (byte)(data-input);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static final void rep_scasb_a32(Processor cpu)
{
int data = 0xff & cpu.r_al.get8();
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr);
count--;
addr -= 1;
if (data != input) break;
}
} else {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr);
count--;
addr += 1;
if (data != input) break;
}
}
} finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
cpu.flagOp1 = (byte)data;
cpu.flagOp2 = (byte)input;
cpu.flagResult = (byte)(data-input);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static final void repne_scasb_a32(Processor cpu)
{
int data = 0xff & cpu.r_al.get8();
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr);
count--;
addr -= 1;
if (data == input) break;
}
} else {
while (count != 0) {
input = 0xff & cpu.es.getByte(addr);
count--;
addr += 1;
if (data == input) break;
}
}
} finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
cpu.flagOp1 = (byte)data;
cpu.flagOp2 = (byte)input;
cpu.flagResult = (byte)(data-input);
cpu.flagIns = UCodes.SUB8;
cpu.flagStatus = OSZAPC;
}
}
public static final void repe_scasw_a16(Processor cpu)
{
int data = 0xffff & cpu.r_ax.get16();
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr & 0xffff);
count--;
addr -= 2;
if (data != input) break;
}
} else {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr & 0xffff);
count--;
addr += 2;
if (data != input) break;
}
}
} finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
cpu.flagOp1 = (short)data;
cpu.flagOp2 = (short)input;
cpu.flagResult = (short)(data-input);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static final void repe_scasw_a32(Processor cpu)
{
int data = 0xffff & cpu.r_ax.get16();
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr);
count--;
addr -= 2;
if (data != input) break;
}
} else {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr);
count--;
addr += 2;
if (data != input) break;
}
}
} finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
cpu.flagOp1 = (short)data;
cpu.flagOp2 = (short)input;
cpu.flagResult = (short)(data-input);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static final void repne_scasw_a16(Processor cpu)
{
int data = 0xffff & cpu.r_ax.get16();
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr & 0xffff);
count--;
addr -= 2;
if (data == input) break;
}
} else {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr & 0xffff);
count--;
addr += 2;
if (data == input) break;
}
}
} finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
cpu.flagOp1 = (short)data;
cpu.flagOp2 = (short)input;
cpu.flagResult = (short)(data-input);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static final void repne_scasw_a32(Processor cpu)
{
int data = 0xffff & cpu.r_ax.get16();
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr);
count--;
addr -= 2;
if (data == input) break;
}
} else {
while (count != 0) {
input = 0xffff & cpu.es.getWord(addr);
count--;
addr += 2;
if (data == input) break;
}
}
} finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
cpu.flagOp1 = (short)data;
cpu.flagOp2 = (short)input;
cpu.flagResult = (short)(data-input);
cpu.flagIns = UCodes.SUB16;
cpu.flagStatus = OSZAPC;
}
}
public static final void rep_scasd_a16(Processor cpu)
{
int data = cpu.r_eax.get32();
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = cpu.es.getDoubleWord(addr & 0xffff);
count--;
addr -= 4;
if (data != input) break;
}
} else {
while (count != 0) {
input = cpu.es.getDoubleWord(addr & 0xffff);
count--;
addr += 4;
if (data != input) break;
}
}
} finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
cpu.flagOp1 = data;
cpu.flagOp2 = input;
cpu.flagResult = data-input;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static final void repne_scasd_a16(Processor cpu)
{
int data = cpu.r_eax.get32();
int count = cpu.r_ecx.get16() & 0xffff;
int addr = cpu.r_edi.get16() & 0xffff;
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = cpu.es.getDoubleWord(addr & 0xffff);
count--;
addr -= 4;
if (data == input) break;
}
} else {
while (count != 0) {
input = cpu.es.getDoubleWord(addr & 0xffff);
count--;
addr += 4;
if (data == input) break;
}
}
} finally {
cpu.r_ecx.set16(count);
cpu.r_edi.set16(addr);
cpu.flagOp1 = data;
cpu.flagOp2 = input;
cpu.flagResult = data-input;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static final void rep_scasd_a32(Processor cpu)
{
int data = cpu.r_eax.get32();
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = cpu.es.getDoubleWord(addr);
count--;
addr -= 4;
if (data != input) break;
}
} else {
while (count != 0) {
input = cpu.es.getDoubleWord(addr);
count--;
addr += 4;
if (data != input) break;
}
}
} finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
cpu.flagOp1 = data;
cpu.flagOp2 = input;
cpu.flagResult = data-input;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
public static final void repne_scasd_a32(Processor cpu)
{
int data = cpu.r_eax.get32();
int count = cpu.r_ecx.get32();
int addr = cpu.r_edi.get32();
int input = 0;
if (count != 0)
try {
if (cpu.df) {
while (count != 0) {
input = cpu.es.getDoubleWord(addr);
count--;
addr -= 4;
if (data == input) break;
}
} else {
while (count != 0) {
input = cpu.es.getDoubleWord(addr);
count--;
addr += 4;
if (data == input) break;
}
}
} finally {
cpu.r_ecx.set32(count);
cpu.r_edi.set32(addr);
cpu.flagOp1 = data;
cpu.flagOp2 = input;
cpu.flagResult = data-input;
cpu.flagIns = UCodes.SUB32;
cpu.flagStatus = OSZAPC;
}
}
//from the j2se api as not in midp
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
}