v1.17.0: Widening registers

This commit is contained in:
Jeff Parsons 2015-01-19 22:32:15 -08:00 committed by jeffpar
commit 1ede9acf15
133 changed files with 20419 additions and 19923 deletions

View file

@ -140,11 +140,11 @@ if (!fGenMods) {
print(" /**");
print(" * @this {X86CPU}");
print(" *");
print(" * op=0x" + toHex(op, 2) + " (" + sOpCode.toLowerCase() + " AX," + sDst + ")");
print(" * op=0x" + toHex(op, 2) + " (" + sOpCode.toLowerCase() + " EAX," + sDst + ")");
print(" */");
sOp = "op" + sOpCode + sDst;
print(" " + sOp + ": function() {");
print(" var temp = this.regAX; this.regAX = " + sDstReg + "; " + sDstReg + " = temp;");
print(" var temp = this.regEAX; this.regEAX = " + sDstReg + "; " + sDstReg + " = temp;");
print(" },");
if (sOps) sOps += ((cOps % 4)? ", " : ",\n");
sOps += " this." + sOp;
@ -279,46 +279,46 @@ function genMode(d, w, mrm, sGroup, sRO) {
if (!w) {
switch (reg) {
case 0:
sRegGet = "this.regAX & 0xff";
sRegSet = "this.regAX = (this.regAX & ~0xff) | ";
sRegGet = "this.regEAX & 0xff";
sRegSet = "this.regEAX = (this.regEAX & ~0xff) | ";
sRegBTLo = "this.backTrack.btiAL";
break;
case 1:
sRegGet = "this.regCX & 0xff";
sRegSet = "this.regCX = (this.regCX & ~0xff) | ";
sRegGet = "this.regECX & 0xff";
sRegSet = "this.regECX = (this.regECX & ~0xff) | ";
sRegBTLo = "this.backTrack.btiCL";
break;
case 2:
sRegGet = "this.regDX & 0xff";
sRegSet = "this.regDX = (this.regDX & ~0xff) | ";
sRegGet = "this.regEDX & 0xff";
sRegSet = "this.regEDX = (this.regEDX & ~0xff) | ";
sRegBTLo = "this.backTrack.btiDL";
break;
case 3:
sRegGet = "this.regBX & 0xff";
sRegSet = "this.regBX = (this.regBX & ~0xff) | ";
sRegGet = "this.regEBX & 0xff";
sRegSet = "this.regEBX = (this.regEBX & ~0xff) | ";
sRegBTLo = "this.backTrack.btiBL";
break;
case 4:
sRegGet = "this.regAX >> 8";
sRegSet = "this.regAX = (this.regAX & 0xff) | ";
sRegGet = "(this.regEAX >> 8) & 0xff";
sRegSet = "this.regEAX = (this.regEAX & ~0xff00) | ";
sRegSetEnd = " << 8";
sRegBTLo = "this.backTrack.btiAH";
break;
case 5:
sRegGet = "this.regCX >> 8";
sRegSet = "this.regCX = (this.regCX & 0xff) | ";
sRegGet = "(this.regECX >> 8) & 0xff";
sRegSet = "this.regECX = (this.regECX & ~0xff00) | ";
sRegSetEnd = " << 8";
sRegBTLo = "this.backTrack.btiCH";
break;
case 6:
sRegGet = "this.regDX >> 8";
sRegSet = "this.regDX = (this.regDX & 0xff) | ";
sRegGet = "(this.regEDX >> 8) & 0xff";
sRegSet = "this.regEDX = (this.regEDX & ~0xff00) | ";
sRegSetEnd = " << 8";
sRegBTLo = "this.backTrack.btiDH";
break;
case 7:
sRegGet = "this.regBX >> 8";
sRegSet = "this.regBX = (this.regBX & 0xff) | ";
sRegGet = "(this.regEBX >> 8) & 0xff";
sRegSet = "this.regEBX = (this.regEBX & ~0xff00) | ";
sRegSetEnd = " << 8";
sRegBTLo = "this.backTrack.btiBH";
break;
@ -330,42 +330,50 @@ function genMode(d, w, mrm, sGroup, sRO) {
else {
switch (reg) {
case 0:
sRegGet = "this.regAX";
sRegGet = "this.regEAX & this.opMask";
sRegSet = "this.regEAX = (this.regEAX & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiAL";
sRegBTHi = "this.backTrack.btiAH";
break;
case 1:
sRegGet = "this.regCX";
sRegGet = "this.regECX & this.opMask";
sRegSet = "this.regECX = (this.regECX & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiCL";
sRegBTHi = "this.backTrack.btiCH";
break;
case 2:
sRegGet = "this.regDX";
sRegGet = "this.regEDX & this.opMask";
sRegSet = "this.regEDX = (this.regEDX & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiDL";
sRegBTHi = "this.backTrack.btiDH";
break;
case 3:
sRegGet = "this.regBX";
sRegGet = "this.regEBX & this.opMask";
sRegSet = "this.regEBX = (this.regEBX & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiBL";
sRegBTHi = "this.backTrack.btiBH";
break;
case 4:
sRegGet = "this.regSP";
sRegGet = "this.regESP & this.opMask";
sRegSet = "this.regESP = (this.regESP & this.opMaskClear) | ";
sRegBTLo = "X86.BACKTRACK.SP_LO";
sRegBTHi = "X86.BACKTRACK.SP_HI";
break;
case 5:
sRegGet = "this.regBP";
sRegGet = "this.regEBP & this.opMask";
sRegSet = "this.regEBP = (this.regEBP & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiBPLo";
sRegBTHi = "this.backTrack.btiBPHi";
break;
case 6:
sRegGet = "this.regSI";
sRegGet = "this.regESI & this.opMask";
sRegSet = "this.regESI = (this.regESI & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiSILo";
sRegBTHi = "this.backTrack.btiSIHi";
break;
case 7:
sRegGet = "this.regDI";
sRegGet = "this.regEDI & this.opMask";
sRegSet = "this.regEDI = (this.regEDI & this.opMaskClear) | ";
sRegBTLo = "this.backTrack.btiDILo";
sRegBTHi = "this.backTrack.btiDIHi";
break;
@ -394,34 +402,34 @@ function genMode(d, w, mrm, sGroup, sRO) {
case 0:
switch (r_m) {
case 0:
sModAddr = "this.regBX + this.regSI";
sModAddr = "this.regEBX + this.regESI";
sModFunc = "BXSI";
nCycles = "this.CYCLES.nEACyclesBaseIndex"; // 8086: 7
break;
case 1:
sModAddr = "this.regBX + this.regDI";
sModAddr = "this.regEBX + this.regEDI";
sModFunc = "BXDI";
nCycles = "this.CYCLES.nEACyclesBaseIndexExtra"; // 8086: 8
break;
case 2:
sModAddr = "this.regBP + this.regSI";
sModAddr = "this.regEBP + this.regESI";
sModFunc = "BPSI";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseIndexExtra"; // 8086: 8
break;
case 3:
sModAddr = "this.regBP + this.regDI";
sModAddr = "this.regEBP + this.regEDI";
sModFunc = "BPDI";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseIndex"; // 8086: 7
break;
case 4:
sModAddr = "this.regSI";
sModAddr = "this.regESI";
sModFunc = "SI";
nCycles = "this.CYCLES.nEACyclesBase"; // 8086: 5
break;
case 5:
sModAddr = "this.regDI";
sModAddr = "this.regEDI";
sModFunc = "DI";
nCycles = "this.CYCLES.nEACyclesBase"; // 8086: 5
break;
@ -431,7 +439,7 @@ function genMode(d, w, mrm, sGroup, sRO) {
nCycles = "this.CYCLES.nEACyclesDisp"; // 8086: 6
break;
case 7:
sModAddr = "this.regBX";
sModAddr = "this.regEBX";
sModFunc = "BX";
nCycles = "this.CYCLES.nEACyclesBase"; // 8086: 5
break;
@ -443,45 +451,45 @@ function genMode(d, w, mrm, sGroup, sRO) {
case 1:
switch (r_m) {
case 0:
sModAddr = "this.regBX + this.regSI + this.getIPDisp()";
sModAddr = "this.regEBX + this.regESI + this.getIPDisp()";
sModFunc = "BXSID8";
nCycles = "this.CYCLES.nEACyclesBaseIndexDisp"; // 8086: 11
break;
case 1:
sModAddr = "this.regBX + this.regDI + this.getIPDisp()";
sModAddr = "this.regEBX + this.regEDI + this.getIPDisp()";
sModFunc = "BXDID8";
nCycles = "this.CYCLES.nEACyclesBaseIndexDispExtra"; // 8086: 12
break;
case 2:
sModAddr = "this.regBP + this.regSI + this.getIPDisp()";
sModAddr = "this.regEBP + this.regESI + this.getIPDisp()";
sModFunc = "BPSID8";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseIndexDispExtra"; // 8086: 12
break;
case 3:
sModAddr = "this.regBP + this.regDI + this.getIPDisp()";
sModAddr = "this.regEBP + this.regEDI + this.getIPDisp()";
sModFunc = "BPDID8";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseIndexDisp"; // 8086: 11
break;
case 4:
sModAddr = "this.regSI + this.getIPDisp()";
sModAddr = "this.regESI + this.getIPDisp()";
sModFunc = "SID8";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
case 5:
sModAddr = "this.regDI + this.getIPDisp()";
sModAddr = "this.regEDI + this.getIPDisp()";
sModFunc = "DID8";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
case 6:
sModAddr = "this.regBP + this.getIPDisp()";
sModAddr = "this.regEBP + this.getIPDisp()";
sModFunc = "BPD8";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
case 7:
sModAddr = "this.regBX + this.getIPDisp()";
sModAddr = "this.regEBX + this.getIPDisp()";
sModFunc = "BXD8";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
@ -493,45 +501,45 @@ function genMode(d, w, mrm, sGroup, sRO) {
case 2:
switch (r_m) {
case 0:
sModAddr = "this.regBX + this.regSI + this.getIPWord()";
sModAddr = "this.regEBX + this.regESI + this.getIPWord()";
sModFunc = "BXSID16";
nCycles = "this.CYCLES.nEACyclesBaseIndexDisp"; // 8086: 11
break;
case 1:
sModAddr = "this.regBX + this.regDI + this.getIPWord()";
sModAddr = "this.regEBX + this.regEDI + this.getIPWord()";
sModFunc = "BXDID16";
nCycles = "this.CYCLES.nEACyclesBaseIndexDispExtra"; // 8086: 12
break;
case 2:
sModAddr = "this.regBP + this.regSI + this.getIPWord()";
sModAddr = "this.regEBP + this.regESI + this.getIPWord()";
sModFunc = "BPSID16";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseIndexDispExtra"; // 8086: 12
break;
case 3:
sModAddr = "this.regBP + this.regDI + this.getIPWord()";
sModAddr = "this.regEBP + this.regEDI + this.getIPWord()";
sModFunc = "BPDID16";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseIndexDisp"; // 8086: 11
break;
case 4:
sModAddr = "this.regSI + this.getIPWord()";
sModAddr = "this.regESI + this.getIPWord()";
sModFunc = "SID16";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
case 5:
sModAddr = "this.regDI + this.getIPWord()";
sModAddr = "this.regEDI + this.getIPWord()";
sModFunc = "DID16";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
case 6:
sModAddr = "this.regBP + this.getIPWord()";
sModAddr = "this.regEBP + this.getIPWord()";
sModFunc = "BPD16";
sModRegSeg = "this.segStack";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
case 7:
sModAddr = "this.regBX + this.getIPWord()";
sModAddr = "this.regEBX + this.getIPWord()";
sModFunc = "BXD16";
nCycles = "this.CYCLES.nEACyclesBaseDisp"; // 8086: 9
break;
@ -544,46 +552,46 @@ function genMode(d, w, mrm, sGroup, sRO) {
if (!w) {
switch (r_m) {
case 0:
sModRegGet = "this.regAX & 0xff";
sModRegSet = "this.regAX = (this.regAX & ~0xff) | ";
sModRegGet = "this.regEAX & 0xff";
sModRegSet = "this.regEAX = (this.regEAX & ~0xff) | ";
sModRegBTLo = "this.backTrack.btiAL";
break;
case 1:
sModRegGet = "this.regCX & 0xff";
sModRegSet = "this.regCX = (this.regCX & ~0xff) | ";
sModRegGet = "this.regECX & 0xff";
sModRegSet = "this.regECX = (this.regECX & ~0xff) | ";
sModRegBTLo = "this.backTrack.btiCL";
break;
case 2:
sModRegGet = "this.regDX & 0xff";
sModRegSet = "this.regDX = (this.regDX & ~0xff) | ";
sModRegGet = "this.regEDX & 0xff";
sModRegSet = "this.regEDX = (this.regEDX & ~0xff) | ";
sModRegBTLo = "this.backTrack.btiDL";
break;
case 3:
sModRegGet = "this.regBX & 0xff";
sModRegSet = "this.regBX = (this.regBX & ~0xff) | ";
sModRegGet = "this.regEBX & 0xff";
sModRegSet = "this.regEBX = (this.regEBX & ~0xff) | ";
sModRegBTLo = "this.backTrack.btiBL";
break;
case 4:
sModRegGet = "this.regAX >> 8";
sModRegSet = "this.regAX = (this.regAX & 0xff) | ";
sModRegGet = "(this.regEAX >> 8) & 0xff";
sModRegSet = "this.regEAX = (this.regEAX & ~0xff00) | ";
sModRegSetEnd = " << 8";
sModRegBTLo = "this.backTrack.btiAH";
break;
case 5:
sModRegGet = "this.regCX >> 8";
sModRegSet = "this.regCX = (this.regCX & 0xff) | ";
sModRegGet = "(this.regECX >> 8) & 0xff";
sModRegSet = "this.regECX = (this.regECX & ~0xff00) | ";
sModRegSetEnd = " << 8";
sModRegBTLo = "this.backTrack.btiCH";
break;
case 6:
sModRegGet = "this.regDX >> 8";
sModRegSet = "this.regDX = (this.regDX & 0xff) | ";
sModRegGet = "(this.regEDX >> 8) & 0xff";
sModRegSet = "this.regEDX = (this.regEDX & ~0xff00) | ";
sModRegSetEnd = " << 8";
sModRegBTLo = "this.backTrack.btiDH";
break;
case 7:
sModRegGet = "this.regBX >> 8";
sModRegSet = "this.regBX = (this.regBX & 0xff) | ";
sModRegGet = "(this.regEBX >> 8) & 0xff";
sModRegSet = "this.regEBX = (this.regEBX & ~0xff00) | ";
sModRegSetEnd = " << 8";
sModRegBTLo = "this.backTrack.btiBH";
break;
@ -595,42 +603,50 @@ function genMode(d, w, mrm, sGroup, sRO) {
else {
switch (r_m) {
case 0:
sModRegGet = "this.regAX";
sModRegGet = "this.regEAX & this.opMask";
sModRegSet = "this.regEAX = (this.regEAX & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiAL";
sModRegBTHi = "this.backTrack.btiAH";
break;
case 1:
sModRegGet = "this.regCX";
sModRegGet = "this.regECX & this.opMask";
sModRegSet = "this.regECX = (this.regECX & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiCL";
sModRegBTHi = "this.backTrack.btiCH";
break;
case 2:
sModRegGet = "this.regDX";
sModRegGet = "this.regEDX & this.opMask";
sModRegSet = "this.regEDX = (this.regEDX & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiDL";
sModRegBTHi = "this.backTrack.btiDH";
break;
case 3:
sModRegGet = "this.regBX";
sModRegGet = "this.regEBX & this.opMask";
sModRegSet = "this.regEBX = (this.regEBX & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiBL";
sModRegBTHi = "this.backTrack.btiBH";
break;
case 4:
sModRegGet = "this.regSP";
sModRegGet = "this.regESP & this.opMask";
sModRegSet = "this.regESP = (this.regESP & this.opMaskClear) | ";
sModRegBTLo = "X86.BACKTRACK.SP_LO";
sModRegBTHi = "X86.BACKTRACK.SP_HI";
break;
case 5:
sModRegGet = "this.regBP";
sModRegGet = "this.regEBP & this.opMask";
sModRegSet = "this.regEBP = (this.regEBP & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiBPLo";
sModRegBTHi = "this.backTrack.btiBPHi";
break;
case 6:
sModRegGet = "this.regSI";
sModRegGet = "this.regESI & this.opMask";
sModRegSet = "this.regESI = (this.regESI & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiSILo";
sModRegBTHi = "this.backTrack.btiSIHi";
break;
case 7:
sModRegGet = "this.regDI";
sModRegGet = "this.regEDI & this.opMask";
sModRegSet = "this.regEDI = (this.regEDI & this.opMaskClear) | ";
sModRegBTLo = "this.backTrack.btiDILo";
sModRegBTHi = "this.backTrack.btiDIHi";
break;
@ -670,10 +686,10 @@ function genMode(d, w, mrm, sGroup, sRO) {
print(" * @param {Array.<function(number,number)>} afnGrp");
print(" * @param {function()} fnSrc");
print(" */");
print(" " + sOpMod + ": function(afnGrp, fnSrc) {");
print(" " + sOpMod.replace("Byte","").replace("Word","") + ": function " + sOpMod + "(afnGrp, fnSrc) {");
if (sModAddr) {
if (sModAddr.indexOf("+") > 0) {
if (sModAddr.indexOf("+") > 0 || sModAddr.indexOf("regE") >= 0) {
sModAddr = "((" + sModAddr + ") & 0xffff)";
}
if (!d) {
@ -734,10 +750,10 @@ function genMode(d, w, mrm, sGroup, sRO) {
}
if (sModRegBTLo) {
if (!sModRegBTHi) {
print(" if (BACKTRACK) " + sModRegBTLo + " = this.backTrack.btiMemLo;");
print(" if (BACKTRACK) " + sModRegBTLo + " = this.backTrack.btiEALo;");
} else {
print(" if (BACKTRACK) {");
print(" " + sModRegBTLo + " = this.backTrack.btiMemLo; " + sModRegBTHi + " = this.backTrack.btiMemHi;");
print(" " + sModRegBTLo + " = this.backTrack.btiEALo; " + sModRegBTHi + " = this.backTrack.btiEAHi;");
print(" }");
}
}
@ -762,11 +778,11 @@ function genMode(d, w, mrm, sGroup, sRO) {
print(" * @this {X86CPU}");
print(" * @param {function(number,number)} fn (dst,src)");
print(" */");
print(" " + sOpMod + ": function(fn) {");
print(" " + sOpMod.replace("Byte","").replace("Word","") + ": function " + sOpMod + "(fn) {");
if (sModAddr && sRegGet) {
if (sModAddr.indexOf("+") > 0) {
if (sModAddr.indexOf("+") > 0 || sModAddr.indexOf("regE") >= 0) {
sModAddr = "((" + sModAddr + ") & 0xffff)";
}
if (!d) {
@ -775,10 +791,10 @@ function genMode(d, w, mrm, sGroup, sRO) {
print(" var " + sTemp + " = fn.call(this, this.modEA" + aSize[w] + "(" + sModRegSeg + ", " + sModAddr + "), " + sRegGet + ");");
if (sRegBTLo) {
if (!sRegBTHi) {
print(" if (BACKTRACK) this.backTrack.btiMemLo = " + sRegBTLo + ";");
print(" if (BACKTRACK) this.backTrack.btiEALo = " + sRegBTLo + ";");
} else {
print(" if (BACKTRACK) {");
print(" this.backTrack.btiMemLo = " + sRegBTLo + "; this.backTrack.btiMemHi = " + sRegBTHi + ";");
print(" this.backTrack.btiEALo = " + sRegBTLo + "; this.backTrack.btiEAHi = " + sRegBTHi + ";");
print(" }");
}
}
@ -795,10 +811,10 @@ function genMode(d, w, mrm, sGroup, sRO) {
print(" var " + sTemp + " = fn.call(this, this.modEA" + aSize[w] + "(this.regEAWrite), " + sRegGet + ");");
if (sRegBTLo) {
if (!sRegBTHi) {
print(" if (BACKTRACK) this.backTrack.btiMemLo = " + sRegBTLo + ";");
print(" if (BACKTRACK) this.backTrack.btiEALo = " + sRegBTLo + ";");
} else {
print(" if (BACKTRACK) {");
print(" this.backTrack.btiMemLo = " + sRegBTLo + "; this.backTrack.btiMemHi = " + sRegBTHi + ";");
print(" this.backTrack.btiEALo = " + sRegBTLo + "; this.backTrack.btiEAHi = " + sRegBTHi + ";");
print(" }");
}
}
@ -844,10 +860,10 @@ function genMode(d, w, mrm, sGroup, sRO) {
}
if (sRegBTLo && sRegBTLo.indexOf("this.") >= 0) {
if (!sRegBTHi) {
print(" if (BACKTRACK) " + sRegBTLo + " = this.backTrack.btiMemLo;");
print(" if (BACKTRACK) " + sRegBTLo + " = this.backTrack.btiEALo;");
} else {
print(" if (BACKTRACK) {");
print(" " + sRegBTLo + " = this.backTrack.btiMemLo; " + sRegBTHi + " = this.backTrack.btiMemHi;");
print(" " + sRegBTLo + " = this.backTrack.btiEALo; " + sRegBTHi + " = this.backTrack.btiEAHi;");
print(" }");
}
}

View file

@ -3323,7 +3323,7 @@ ChipSet.prototype.getIRRVector = function(iPIC)
var nIRQ = pic.nIRQBase + nIRL;
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
this.printMessage("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel) + " stack=" + str.toHexAddr(this.cpu.regSP, this.cpu.segSS.sel), true);
this.printMessage("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.regIP, this.cpu.segCS.sel) + " stack=" + str.toHexAddr(this.cpu.regESP, this.cpu.segSS.sel), true);
}
if (MAXDEBUG && DEBUGGER) {
this.acInterrupts[nIRQ]++;
@ -4721,19 +4721,19 @@ ChipSet.prototype.intBIOSRTC = function(addr)
* By computing AH now, we get the incoming AH value; if we computed it below, along with
* the rest of the register values, we'd get the outgoing AH value, which is not what we want.
*/
var AH = this.cpu.regAX >> 8;
var AH = this.cpu.regEAX >> 8;
this.cpu.addIntReturn(addr, function(chipset, nCycles) {
return function onBIOSRTCReturn(nLevel) {
nCycles = chipset.cpu.getCycles() - nCycles;
var sResult;
var CL = chipset.cpu.regDX & 0xff;
var CH = chipset.cpu.regDX >> 8;
var DL = chipset.cpu.regDX & 0xff;
var DH = chipset.cpu.regDX >> 8;
var CL = chipset.cpu.regEDX & 0xff;
var CH = chipset.cpu.regEDX >> 8;
var DL = chipset.cpu.regEDX & 0xff;
var DH = chipset.cpu.regEDX >> 8;
if (AH == 0x02 || AH == 0x03) {
sResult = " CH(hour)=" + str.toHexWord(CH) + " CL(min)=" + str.toHexByte(CL) + " DH(sec)=" + str.toHexByte(DH);
} else if (AH == 0x04 || AH == 0x05) {
sResult = " CX(year)=" + str.toHexWord(chipset.cpu.regCX) + " DH(month)=" + str.toHexByte(DH) + " DL(day)=" + str.toHexByte(DL);
sResult = " CX(year)=" + str.toHexWord(chipset.cpu.regECX) + " DH(month)=" + str.toHexByte(DH) + " DL(day)=" + str.toHexByte(DL);
}
chipset.dbg.messageIntReturn(Interrupts.RTC.VECTOR, nLevel, nCycles, sResult);
};

View file

@ -1560,22 +1560,22 @@ if (DEBUGGER) {
Debugger.prototype.messageRegs = function() {
var cpu = this.cpu;
var asRegs = Debugger.asRegs;
this.aMessageRegs[asRegs[0]] = str.toHexByte(cpu.regAX & 0xff);
this.aMessageRegs[asRegs[1]] = str.toHexByte(cpu.regCX & 0xff);
this.aMessageRegs[asRegs[2]] = str.toHexByte(cpu.regDX & 0xff);
this.aMessageRegs[asRegs[3]] = str.toHexByte(cpu.regBX & 0xff);
this.aMessageRegs[asRegs[4]] = str.toHexByte(cpu.regAX >> 8);
this.aMessageRegs[asRegs[5]] = str.toHexByte(cpu.regCX >> 8);
this.aMessageRegs[asRegs[6]] = str.toHexByte(cpu.regDX >> 8);
this.aMessageRegs[asRegs[7]] = str.toHexByte(cpu.regBX >> 8);
this.aMessageRegs[asRegs[8]] = str.toHexWord(cpu.regAX);
this.aMessageRegs[asRegs[9]] = str.toHexWord(cpu.regCX);
this.aMessageRegs[asRegs[10]] = str.toHexWord(cpu.regDX);
this.aMessageRegs[asRegs[11]] = str.toHexWord(cpu.regBX);
this.aMessageRegs[asRegs[12]] = str.toHexWord(cpu.regSP);
this.aMessageRegs[asRegs[13]] = str.toHexWord(cpu.regBP);
this.aMessageRegs[asRegs[14]] = str.toHexWord(cpu.regSI);
this.aMessageRegs[asRegs[15]] = str.toHexWord(cpu.regDI);
this.aMessageRegs[asRegs[0]] = str.toHexByte(cpu.regEAX & 0xff);
this.aMessageRegs[asRegs[1]] = str.toHexByte(cpu.regECX & 0xff);
this.aMessageRegs[asRegs[2]] = str.toHexByte(cpu.regEDX & 0xff);
this.aMessageRegs[asRegs[3]] = str.toHexByte(cpu.regEBX & 0xff);
this.aMessageRegs[asRegs[4]] = str.toHexByte(cpu.regEAX >> 8);
this.aMessageRegs[asRegs[5]] = str.toHexByte(cpu.regECX >> 8);
this.aMessageRegs[asRegs[6]] = str.toHexByte(cpu.regEDX >> 8);
this.aMessageRegs[asRegs[7]] = str.toHexByte(cpu.regEBX >> 8);
this.aMessageRegs[asRegs[8]] = str.toHexWord(cpu.regEAX);
this.aMessageRegs[asRegs[9]] = str.toHexWord(cpu.regECX);
this.aMessageRegs[asRegs[10]] = str.toHexWord(cpu.regEDX);
this.aMessageRegs[asRegs[11]] = str.toHexWord(cpu.regEBX);
this.aMessageRegs[asRegs[12]] = str.toHexWord(cpu.regESP);
this.aMessageRegs[asRegs[13]] = str.toHexWord(cpu.regEBP);
this.aMessageRegs[asRegs[14]] = str.toHexWord(cpu.regESI);
this.aMessageRegs[asRegs[15]] = str.toHexWord(cpu.regEDI);
this.aMessageRegs[asRegs[16]] = str.toHexWord(cpu.segES.sel);
this.aMessageRegs[asRegs[17]] = str.toHexWord(cpu.segCS.sel);
this.aMessageRegs[asRegs[18]] = str.toHexWord(cpu.segSS.sel);
@ -1632,7 +1632,7 @@ if (DEBUGGER) {
var fMessage = false;
var nCategory = Debugger.INT_MESSAGES[nInt];
if (nCategory) {
AH = this.cpu.regAX >> 8;
AH = this.cpu.regEAX >> 8;
if (this.messageEnabled(nCategory)) {
fMessage = true;
} else {
@ -1640,7 +1640,7 @@ if (DEBUGGER) {
}
}
if (fMessage) {
var DL = this.cpu.regDX & 0xff;
var DL = this.cpu.regEDX & 0xff;
if (nInt == Interrupts.DOS.VECTOR && AH == 0x0b ||
nCategory == Messages.FDC && DL >= 0x80 || nCategory == Messages.HDC && DL < 0x80) {
fMessage = false;
@ -3034,14 +3034,14 @@ if (DEBUGGER) {
if (fProt === undefined) {
fProt = !!(this.cpu.regMSW & X86.MSW.PE);
}
var s = "AX=" + str.toHexWord(this.cpu.regAX) +
" BX=" + str.toHexWord(this.cpu.regBX) +
" CX=" + str.toHexWord(this.cpu.regCX) +
" DX=" + str.toHexWord(this.cpu.regDX) +
" SP=" + str.toHexWord(this.cpu.regSP) +
" BP=" + str.toHexWord(this.cpu.regBP) +
" SI=" + str.toHexWord(this.cpu.regSI) +
" DI=" + str.toHexWord(this.cpu.regDI) + '\n';
var s = "AX=" + str.toHexWord(this.cpu.regEAX) +
" BX=" + str.toHexWord(this.cpu.regEBX) +
" CX=" + str.toHexWord(this.cpu.regECX) +
" DX=" + str.toHexWord(this.cpu.regEDX) +
" SP=" + str.toHexWord(this.cpu.regESP) +
" BP=" + str.toHexWord(this.cpu.regEBP) +
" SI=" + str.toHexWord(this.cpu.regESI) +
" DI=" + str.toHexWord(this.cpu.regEDI) + '\n';
s += this.getSegStr(this.cpu.segDS, fProt) + ' ' + this.getSegStr(this.cpu.segES, fProt) + ' ' + this.getSegStr(this.cpu.segSS, fProt);
s += (fProt? '\n' : ' ');
s += this.getSegStr(this.cpu.segCS, fProt) + " IP=" + str.toHexWord(this.cpu.regIP) +
@ -3134,28 +3134,28 @@ if (DEBUGGER) {
sValue = sValue.toUpperCase();
switch (sValue) {
case "AX":
value = this.cpu.regAX;
value = this.cpu.regEAX;
break;
case "BX":
value = this.cpu.regBX;
value = this.cpu.regEBX;
break;
case "CX":
value = this.cpu.regCX;
value = this.cpu.regECX;
break;
case "DX":
value = this.cpu.regDX;
value = this.cpu.regEDX;
break;
case "SI":
value = this.cpu.regSI;
value = this.cpu.regESI;
break;
case "DI":
value = this.cpu.regDI;
value = this.cpu.regEDI;
break;
case "BP":
value = this.cpu.regBP;
value = this.cpu.regEBP;
break;
case "SP":
value = this.cpu.regSP;
value = this.cpu.regESP;
break;
case "CS":
value = this.cpu.segCS.sel;
@ -4283,52 +4283,52 @@ if (DEBUGGER) {
sReg = sReg.toUpperCase();
switch (sReg) {
case "AL":
this.cpu.regAX = (this.cpu.regAX & 0xff00) | (w & 0xff);
this.cpu.regEAX = (this.cpu.regEAX & 0xff00) | (w & 0xff);
break;
case "AH":
this.cpu.regAX = (this.cpu.regAX & 0x00ff) | ((w << 8) & 0xff);
this.cpu.regEAX = (this.cpu.regEAX & 0x00ff) | ((w << 8) & 0xff);
break;
case "AX":
this.cpu.regAX = (w & 0xffff);
this.cpu.regEAX = (w & 0xffff);
break;
case "BL":
this.cpu.regBX = (this.cpu.regBX & 0xff00) | (w & 0xff);
this.cpu.regEBX = (this.cpu.regEBX & 0xff00) | (w & 0xff);
break;
case "BH":
this.cpu.regBX = (this.cpu.regBX & 0x00ff) | ((w << 8) & 0xff);
this.cpu.regEBX = (this.cpu.regEBX & 0x00ff) | ((w << 8) & 0xff);
break;
case "BX":
this.cpu.regBX = (w & 0xffff);
this.cpu.regEBX = (w & 0xffff);
break;
case "CL":
this.cpu.regCX = (this.cpu.regCX & 0xff00) | (w & 0xff);
this.cpu.regECX = (this.cpu.regECX & 0xff00) | (w & 0xff);
break;
case "CH":
this.cpu.regCX = (this.cpu.regCX & 0x00ff) | ((w << 8) & 0xff);
this.cpu.regECX = (this.cpu.regECX & 0x00ff) | ((w << 8) & 0xff);
break;
case "CX":
this.cpu.regCX = (w & 0xffff);
this.cpu.regECX = (w & 0xffff);
break;
case "DL":
this.cpu.regDX = (this.cpu.regDX & 0xff00) | (w & 0xff);
this.cpu.regEDX = (this.cpu.regEDX & 0xff00) | (w & 0xff);
break;
case "DH":
this.cpu.regDX = (this.cpu.regDX & 0x00ff) | ((w << 8) & 0xff);
this.cpu.regEDX = (this.cpu.regEDX & 0x00ff) | ((w << 8) & 0xff);
break;
case "DX":
this.cpu.regDX = (w & 0xffff);
this.cpu.regEDX = (w & 0xffff);
break;
case "SP":
this.cpu.regSP = (w & 0xffff);
this.cpu.regESP = (w & 0xffff);
break;
case "BP":
this.cpu.regBP = (w & 0xffff);
this.cpu.regEBP = (w & 0xffff);
break;
case "SI":
this.cpu.regSI = (w & 0xffff);
this.cpu.regESI = (w & 0xffff);
break;
case "DI":
this.cpu.regDI = (w & 0xffff);
this.cpu.regEDI = (w & 0xffff);
break;
case "DS":
this.cpu.setDS(w);
@ -4746,7 +4746,7 @@ if (DEBUGGER) {
if (this.cmp) this.cmp.reset();
return true;
case "ver":
this.println((APPNAME || "PCjs") + " version " + APPVERSION + " (" + (COMPILED? "RELEASE" : (DEBUG? "DEBUG" : "NODEBUG")) + (PREFETCH? ",PREFETCH" : ",NOPREFETCH") + (EAFUNCS? "EAFUNCS" : ",EATESTS") + (TYPEDARRAYS? ",TYPEDARRAYS" : (FATARRAYS? ",FATARRAYS" : ",DWORDARRAYS")) + ")");
this.println((APPNAME || "PCjs") + " version " + APPVERSION + " (" + (COMPILED? "RELEASE" : (DEBUG? "DEBUG" : "NODEBUG")) + (PREFETCH? ",PREFETCH" : ",NOPREFETCH") + (EAFUNCS? "EAFUNCS" : ",EATESTS") + (TYPEDARRAYS? ",TYPEDARRAYS" : (FATARRAYS? ",FATARRAYS" : ",DWORDARRAYS")) + (BACKTRACK? ",BACKTRACK" : "") + ")");
return true;
default:
ch0 = sCmd.charAt(0);

View file

@ -2733,8 +2733,8 @@ HDC.prototype.writeFormat = function(drive, b)
*/
HDC.prototype.intBIOSDisk = function(addr)
{
var AH = this.cpu.regAX >> 8;
var DL = this.cpu.regDX & 0xff;
var AH = this.cpu.regEAX >> 8;
var DL = this.cpu.regEDX & 0xff;
if (!AH && DL > 0x80) this.iDriveAllowFail = DL - 0x80;
return true;
};
@ -2770,7 +2770,7 @@ HDC.prototype.intBIOSDisk = function(addr)
*/
HDC.prototype.intBIOSDiskette = function(addr)
{
var AH = this.cpu.regAX >> 8;
var AH = this.cpu.regEAX >> 8;
if ((!AH && this.chipset && this.chipset.checkIMR(ChipSet.IRQ.FDC))) {
if (DEBUG) this.printMessage("HDC.intBIOSDiskette(): skipping useless INT 0x40 diskette reset");
return false;

View file

@ -41,6 +41,7 @@ var X86 = {
MODEL_80186: 80186,
MODEL_80188: 80188,
MODEL_80286: 80286,
MODEL_80386: 80386,
/*
* This constant is used to mark points in the code where the physical address being returned
@ -148,7 +149,15 @@ var X86 = {
OFFSET: 0x6,
LIMIT1619: 0x000f,
AVAIL: 0x0010, // NOTE: set in various descriptors in OS/2
DEFSIZE: 0x0040, // clear if default operand/address size is 16-bit, set if 32-bit
/*
* The BIG bit is known as the D bit for code segments; when set, all addresses and operands
* in that code segment are assumed to be 32-bit.
*
* The BIG bit is known as the B bit for data segments; when set, it indicates: 1) all pushes,
* pops, calls and returns use ESP instead of SP, and 2) the upper bound of an expand-down segment
* is 0xffffffff instead of 0xffff.
*/
BIG: 0x0040, // clear if default operand/address size is 16-bit, set if 32-bit
GRANULARITY: 0x0080, // clear if limit is bytes, set if limit is 4Kb pages
BASE2431: 0xff00
},
@ -232,7 +241,7 @@ var X86 = {
AUXOVF_OF: 0x08080,
AUXOVF_CF: 0x10100
},
PARITY: [ // 256-byte array with a 1 wherever the number of set bits in the array index is EVEN
PARITY: [ // 256-byte array with a 1 wherever the number of set bits in the array index is EVEN
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,

View file

@ -44,7 +44,8 @@ if (typeof module !== 'undefined') {
var X86Seg = require("./x86seg");
var X86Grps = require("./x86grps");
var X86Help = require("./x86help");
var X86Mods = require("./x86mods");
var X86ModB = require("./x86modb");
var X86ModW = require("./x86modw");
var X86OpXX = require("./x86opxx");
var X86Op0F = require("./x86op0f");
}
@ -97,6 +98,9 @@ function X86CPU(parmsCPU) {
case X86.MODEL_80286:
nCyclesDefault = 6000000;
break;
case X86.MODEL_80386:
nCyclesDefault = 16000000;
break;
}
CPU.call(this, parmsCPU, nCyclesDefault);
@ -795,14 +799,14 @@ X86CPU.prototype.reset = function()
*/
X86CPU.prototype.resetRegs = function()
{
this.regAX = 0;
this.regBX = 0;
this.regCX = 0;
this.regDX = 0;
this.regSP = 0;
this.regBP = 0;
this.regSI = 0;
this.regDI = 0;
this.regEAX = 0;
this.regEBX = 0;
this.regECX = 0;
this.regEDX = 0;
this.regESP = 0;
this.regEBP = 0;
this.regESI = 0;
this.regEDI = 0;
/*
* NOTE: Even though the MSW and IDTR are 80286-specific, we initialize them for ALL CPUs, so that
@ -825,10 +829,15 @@ X86CPU.prototype.resetRegs = function()
* segment number and base physical address, respectively), but all segment registers are now defined
* as X86Seg objects.
*/
this.segCS = new X86Seg(this, X86Seg.ID.CODE, "CS");
this.segDS = new X86Seg(this, X86Seg.ID.DATA, "DS");
this.segES = new X86Seg(this, X86Seg.ID.DATA, "ES");
this.segSS = new X86Seg(this, X86Seg.ID.STACK, "SS");
this.segCS = new X86Seg(this, X86Seg.ID.CODE, "CS");
this.segDS = new X86Seg(this, X86Seg.ID.DATA, "DS");
this.segES = new X86Seg(this, X86Seg.ID.DATA, "ES");
this.segSS = new X86Seg(this, X86Seg.ID.STACK, "SS");
if (this.model >= X86.MODEL_80386) {
this.segFS = new X86Seg(this, X86Seg.ID.DATA, "FS");
this.segGS = new X86Seg(this, X86Seg.ID.DATA, "GS");
}
this.segNULL = new X86Seg(this, X86Seg.ID.NULL, "NULL");
this.setCSIP(0, 0xFFFF); // this should be called before the first setPS() call
@ -937,6 +946,18 @@ X86CPU.prototype.resetRegs = function()
this.segData = this.segDS;
this.segStack = this.segSS;
this.opFlags = this.opPrefixes = 0;
this.opSize = 2;
this.opMask = 0xffff;
this.opMaskClear = ~this.opMask;
this.addrSize = 2;
this.addrMask = 0xffff;
this.addrMaskClear = ~this.addrMask;
this.aOpModMemByte = X86ModB.aOpModMem;
this.aOpModRegByte = X86ModB.aOpModReg;
this.aOpModGrpByte = X86ModB.aOpModGrp;
this.aOpModMemWord = X86ModW.aOpModMem;
this.aOpModRegWord = X86ModW.aOpModReg;
this.aOpModGrpWord = X86ModW.aOpModGrp;
};
/**
@ -947,7 +968,7 @@ X86CPU.prototype.resetRegs = function()
*/
X86CPU.prototype.getChecksum = function()
{
var sum = (this.regAX + this.regBX + this.regCX + this.regDX + this.regSP + this.regBP + this.regSI + this.regDI) | 0;
var sum = (this.regEAX + this.regEBX + this.regECX + this.regEDX + this.regESP + this.regEBP + this.regESI + this.regEDI) | 0;
sum = (sum + this.regIP + this.segCS.sel + this.segDS.sel + this.segSS.sel + this.segES.sel + this.getPS()) | 0;
return sum;
};
@ -1138,7 +1159,7 @@ X86CPU.prototype.restoreProtMode = function(a)
X86CPU.prototype.save = function()
{
var state = new State(this);
state.set(0, [this.regAX, this.regBX, this.regCX, this.regDX, this.regSP, this.regBP, this.regSI, this.regDI, this.nIOPL]);
state.set(0, [this.regEAX, this.regEBX, this.regECX, this.regEDX, this.regESP, this.regEBP, this.regESI, this.regEDI, this.nIOPL]);
state.set(1, [this.regIP, this.segCS.save(), this.segDS.save(), this.segSS.save(), this.segES.save(), this.saveProtMode(), this.getPS()]);
state.set(2, [this.segData.sName, this.segStack.sName, this.opFlags, this.opPrefixes, this.intFlags, this.regEA, this.regEAWrite]);
state.set(3, [0, this.nTotalCycles, this.getSpeed()]);
@ -1159,14 +1180,14 @@ X86CPU.prototype.restore = function(data)
{
var a;
a = data[0];
this.regAX = a[0];
this.regBX = a[1];
this.regCX = a[2];
this.regDX = a[3];
this.regSP = a[4];
this.regBP = a[5];
this.regSI = a[6];
this.regDI = a[7];
this.regEAX = a[0];
this.regEBX = a[1];
this.regECX = a[2];
this.regEDX = a[3];
this.regESP = a[4];
this.regEBP = a[5];
this.regESI = a[6];
this.regEDI = a[7];
this.nIOPL = a[8] || 0;
a = data[1];
this.segCS.restore(a[1]);
@ -1176,8 +1197,12 @@ X86CPU.prototype.restore = function(data)
this.restoreProtMode(a[5]);
this.setPS(a[6]);
this.setIP(a[0]);
if (this.model >= X86.MODEL_80386) {
this.segFS.restore(a[7]);
this.segGS.restore(a[8]);
}
a = data[2];
this.segData = a[0] != null && this.getSeg(a[0]) || this.segDS;
this.segData = a[0] != null && this.getSeg(a[0]) || this.segDS;
this.segStack = a[1] != null && this.getSeg(a[1]) || this.segSS;
this.opFlags = a[2];
this.opPrefixes = a[3];
@ -1222,8 +1247,8 @@ X86CPU.prototype.setMemoryEnabled = function()
*/
X86CPU.prototype.verifyMemoryEnabled = function()
{
this.assert(!(this.regAX & 0xffff0000) && !(this.regBX & 0xffff0000) && !(this.regCX & 0xffff0000) && !(this.regDX & 0xffff0000));
this.assert(!(this.regSI & 0xffff0000) && !(this.regDI & 0xffff0000) && !(this.regBP & 0xffff0000) && !(this.regSP & 0xffff0000));
this.assert(!(this.regEAX & 0xffff0000) && !(this.regEBX & 0xffff0000) && !(this.regECX & 0xffff0000) && !(this.regEDX & 0xffff0000));
this.assert(!(this.regESI & 0xffff0000) && !(this.regEDI & 0xffff0000) && !(this.regEBP & 0xffff0000) && !(this.regESP & 0xffff0000));
this.assert((this.getEAByte == this.getEAByteEnabled && this.getEAWord == this.getEAWordEnabled && this.modEAByte == this.modEAByteEnabled && this.modEAWord == this.modEAWordEnabled && this.setEAByte == this.setEAByteEnabled && this.setEAWord == this.setEAWordEnabled), "verifyMemoryEnabled() failed");
};
@ -1270,7 +1295,7 @@ X86CPU.prototype.getSeg = function(sName)
*/
X86CPU.prototype.setCS = function(sel)
{
this.regEIP = this.segCS.load(sel) + this.regIP;
this.regEIP = this.segCS.load(sel & 0xffff) + this.regIP;
this.opFlags |= this.OPFLAG_NOINTR8086;
if (PREFETCH) this.flushPrefetch(this.regEIP);
};
@ -1283,7 +1308,7 @@ X86CPU.prototype.setCS = function(sel)
*/
X86CPU.prototype.setDS = function(sel)
{
this.segDS.load(sel);
this.segDS.load(sel & 0xffff);
this.opFlags |= this.OPFLAG_NOINTR8086;
};
@ -1295,7 +1320,9 @@ X86CPU.prototype.setDS = function(sel)
*/
X86CPU.prototype.setSS = function(sel)
{
this.segSS.load(sel);
this.segSS.load(sel & 0xffff);
this.segSS.addrMask = (this.model >= X86.MODEL_80386 && (this.segSS.ext & X86.DESC.EXT.BIG))? 0xffffffff : 0xffff;
this.segSS.addrMaskClear = ~this.segSS.addrMask;
this.opFlags |= X86.OPFLAG.NOINTR;
};
@ -1307,7 +1334,7 @@ X86CPU.prototype.setSS = function(sel)
*/
X86CPU.prototype.setES = function(sel)
{
this.segES.load(sel);
this.segES.load(sel & 0xffff);
this.opFlags |= this.OPFLAG_NOINTR8086;
};
@ -2310,9 +2337,9 @@ X86CPU.prototype.getIPWord = function()
*/
X86CPU.prototype.popWord = function()
{
var regSP = this.regSP;
this.regSP = (this.regSP + 2) & 0xffff;
return this.getSOWord(this.segSS, regSP);
var regESP = this.regESP;
this.regESP = (this.regESP + 2) & 0xffff;
return this.getSOWord(this.segSS, regESP);
};
/**
@ -2324,7 +2351,7 @@ X86CPU.prototype.popWord = function()
X86CPU.prototype.pushWord = function(w)
{
this.assert((w & 0xffff) == w);
this.setSOWord(this.segSS, (this.regSP = (this.regSP - 2) & 0xffff), w);
this.setSOWord(this.segSS, (this.regESP = (this.regESP - 2) & 0xffff), w);
};
/**
@ -2478,14 +2505,14 @@ X86CPU.prototype.delayINTR = function()
X86CPU.prototype.displayStatus = function(fForce)
{
if (fForce || !this.aFlags.fRunning || this.aFlags.fDisplayLiveRegs) {
this.displayReg("AX", this.regAX);
this.displayReg("BX", this.regBX);
this.displayReg("CX", this.regCX);
this.displayReg("DX", this.regDX);
this.displayReg("SP", this.regSP);
this.displayReg("BP", this.regBP);
this.displayReg("SI", this.regSI);
this.displayReg("DI", this.regDI);
this.displayReg("AX", this.regEAX);
this.displayReg("BX", this.regEBX);
this.displayReg("CX", this.regECX);
this.displayReg("DX", this.regEDX);
this.displayReg("SP", this.regESP);
this.displayReg("BP", this.regEBP);
this.displayReg("SI", this.regESI);
this.displayReg("DI", this.regEDI);
this.displayReg("CS", this.segCS.sel);
this.displayReg("DS", this.segDS.sel);
this.displayReg("SS", this.segSS.sel);
@ -2741,7 +2768,6 @@ if (typeof APP_PCJS !== 'undefined') {
APP_PCJS.X86.X86Seg = X86Seg;
APP_PCJS.X86.X86Grps = X86Grps;
APP_PCJS.X86.X86Help = X86Help;
APP_PCJS.X86.X86Mods = X86Mods;
APP_PCJS.X86.X86Op0F = X86Op0F;
APP_PCJS.X86.X86OpXX = X86OpXX;
}

View file

@ -723,14 +723,14 @@ var X86Grps = {
* @return {number} (we return dst unchanged, since it's actually AX that's modified)
*/
opGrpMULb: function(dst, src) {
this.regAX = this.regMD16 = (this.resultValue = (src = this.regAX & 0xff) * dst) & 0xffff;
this.regEAX = this.regMD16 = (this.resultValue = (src = this.regEAX & 0xff) * dst) & 0xffff;
this.resultAuxOverflow = this.resultParitySign = this.resultValue;
this.resultSize = X86.RESULT.SIZE_BYTE;
/*
* TODO: Look into a more efficient way of setting/synchronizing CF and OF; this code works,
* but it somewhat defeats the purpose of the indirect result variables that we've set above.
*/
if (this.regAX & 0xff00) {
if (this.regEAX & 0xff00) {
this.setCF(); this.setOF();
} else {
this.clearCF(); this.clearOF();
@ -766,8 +766,8 @@ var X86Grps = {
* @return {number} (we return dst unchanged, since it's actually AX that's modified)
*/
opGrpIMULb: function(dst, src) {
var result = (((src = this.regAX) << 24) >> 24) * ((dst << 24) >> 24);
this.regAX = this.regMD16 = result & 0xffff;
var result = (((src = this.regEAX) << 24) >> 24) * ((dst << 24) >> 24);
this.regEAX = this.regMD16 = result & 0xffff;
this.resultValue = this.resultAuxOverflow = this.resultParitySign = result;
this.resultSize = X86.RESULT.SIZE_BYTE;
/*
@ -807,12 +807,12 @@ var X86Grps = {
/*
* Detect small divisor (quotient overflow)
*/
var uQuotient = ((src = this.regAX) / dst);
var uQuotient = ((src = this.regEAX) / dst);
if (uQuotient > 0xff) {
X86Help.opHelpDIVOverflow.call(this);
return dst;
}
this.regMD16 = this.regAX = (uQuotient & 0xff) | (((this.regAX % dst) & 0xff) << 8);
this.regMD16 = this.regEAX = (uQuotient & 0xff) | (((this.regEAX % dst) & 0xff) << 8);
/*
* TODO: Verify that all of the arithmetic flags are "undefined" after DIV, and that this code unnecessary
*/
@ -854,12 +854,12 @@ var X86Grps = {
/*
* Detect small divisor (quotient overflow)
*/
var lQuotient = ((((src = this.regAX) << 16) >> 16) / ((dst << 24) >> 24));
var lQuotient = ((((src = this.regEAX) << 16) >> 16) / ((dst << 24) >> 24));
if (lQuotient > ((lQuotient << 24) >> 24) & 0xffff) {
X86Help.opHelpDIVOverflow.call(this);
return dst;
}
this.regMD16 = this.regAX = (lQuotient & 0xff) | (((((this.regAX << 16) >> 16) % ((dst << 24) >> 24)) & 0xff) << 8);
this.regMD16 = this.regEAX = (lQuotient & 0xff) | (((((this.regEAX << 16) >> 16) % ((dst << 24) >> 24)) & 0xff) << 8);
/*
* TODO: Verify that all of the arithmetic flags are "undefined" after IDIV, and that this code unnecessary
*/
@ -883,15 +883,15 @@ var X86Grps = {
* @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)
*/
opGrpMULw: function(dst, src) {
this.regMD16 = this.regAX = (this.resultValue = (src = this.regAX) * dst) & 0xffff;
this.regMD32 = this.regDX = (this.resultValue >> 16) & 0xffff;
this.regMD16 = this.regEAX = (this.resultValue = (src = this.regEAX) * dst) & 0xffff;
this.regMD32 = this.regEDX = (this.resultValue >> 16) & 0xffff;
this.resultAuxOverflow = this.resultParitySign = this.resultValue;
this.resultSize = X86.RESULT.SIZE_WORD;
/*
* TODO: Look into a more efficient way of setting/synchronizing CF and OF; this code works,
* but it somewhat defeats the purpose of the indirect result variables that we've set above.
*/
if (this.regDX) {
if (this.regEDX) {
this.setCF(); this.setOF();
} else {
this.clearCF(); this.clearOF();
@ -927,9 +927,9 @@ var X86Grps = {
* @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)
*/
opGrpIMULw: function(dst, src) {
var result = (((src = this.regAX) << 16) >> 16) * ((dst << 16) >> 16);
this.regAX = this.regMD16 = result & 0xffff;
this.regDX = this.regMD32 = (result >> 16) & 0xffff;
var result = (((src = this.regEAX) << 16) >> 16) * ((dst << 16) >> 16);
this.regEAX = this.regMD16 = result & 0xffff;
this.regEDX = this.regMD32 = (result >> 16) & 0xffff;
this.resultValue = this.resultAuxOverflow = this.resultParitySign = result;
this.resultSize = X86.RESULT.SIZE_WORD;
/*
@ -969,18 +969,18 @@ var X86Grps = {
/*
* Detect small divisor (quotient overflow)
*
* WARNING: We CANNOT simply do "src = (this.regDX << 16) | this.regAX", because if bit 15 of DX
* WARNING: We CANNOT simply do "src = (this.regEDX << 16) | this.regEAX", because if bit 15 of DX
* is set, JavaScript will create a negative 32-bit number. So we instead use non-bit-wise operators
* to force JavaScript to create a floating-point value that won't suffer from 32-bit-math side-effects.
*/
src = this.regAX + this.regDX * X86.RESULT.SIZE_WORD;
src = this.regEAX + this.regEDX * X86.RESULT.SIZE_WORD;
var uQuotient = Math.floor(src / dst);
if (uQuotient >= X86.RESULT.SIZE_WORD) {
X86Help.opHelpDIVOverflow.call(this);
return dst;
}
this.regMD16 = this.regAX = (uQuotient & 0xffff);
this.regMD32 = this.regDX = (src % dst) & 0xffff;
this.regMD16 = this.regEAX = (uQuotient & 0xffff);
this.regMD32 = this.regEDX = (src % dst) & 0xffff;
/*
* TODO: Verify that all of the arithmetic flags are "undefined" after DIV, and that this code unnecessary
*/
@ -1023,14 +1023,14 @@ var X86Grps = {
* Detect small divisor (quotient overflow)
*/
var lDivisor = ((dst << 16) >> 16);
src = (this.regDX << 16) | this.regAX;
src = (this.regEDX << 16) | this.regEAX;
var lQuotient = Math.floor(src / lDivisor);
if (lQuotient != ((lQuotient & 0xffff) << 16) >> 16) {
X86Help.opHelpDIVOverflow.call(this);
return dst;
}
this.regMD16 = this.regAX = (lQuotient & 0xffff);
this.regMD32 = this.regDX = (src % lDivisor) & 0xffff;
this.regMD16 = this.regEAX = (lQuotient & 0xffff);
this.regMD32 = this.regEDX = (src % lDivisor) & 0xffff;
/*
* TODO: Verify that all of the arithmetic flags are "undefined" after IDIV, and that this code unnecessary
*/
@ -1200,7 +1200,7 @@ var X86Grps = {
* @return {number}
*/
opGrp2CountCL: function() {
var count = this.regCX & this.nShiftCountMask;
var count = this.regECX & this.nShiftCountMask;
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS);
return count;
},
@ -1261,7 +1261,7 @@ var X86Grps = {
*
* Opcodes Intel PCjs PC Mag TechRef
* ------- ----- ---- --------------
* 0x80-0x83 Grp1 Grp1b, Grp1w, Grp1b, and Grp1sw Group A
* 0x80-0x83 Grp1 Grp1b and Grp1w Group A
* 0xC0-0xC1 Grp2 Grp2b and Grp2w (opGrp2bi/wi) Group B
* 0xD0-0xD3 Grp2 Grp2b and Grp2w (opGrp2b1/w1 and opGrp2bCL/wCL) Group B
* 0xF6-0xF7 Grp3 Grp3b and Grp3w Group C

View file

@ -353,28 +353,28 @@ var X86Help = {
//
switch (this.bModRM & 0x7) {
case 0x0: // AL
this.regAX = (this.regAX & ~0xff) | dst;
this.regEAX = (this.regEAX & ~0xff) | dst;
break;
case 0x1: // CL
this.regCX = (this.regCX & ~0xff) | dst;
this.regECX = (this.regECX & ~0xff) | dst;
break;
case 0x2: // DL
this.regDX = (this.regDX & ~0xff) | dst;
this.regEDX = (this.regEDX & ~0xff) | dst;
break;
case 0x3: // BL
this.regBX = (this.regBX & ~0xff) | dst;
this.regEBX = (this.regEBX & ~0xff) | dst;
break;
case 0x4: // AH
this.regAX = (this.regAX & 0xff) | (dst << 8);
this.regEAX = (this.regEAX & 0xff) | (dst << 8);
break;
case 0x5: // CH
this.regCX = (this.regCX & 0xff) | (dst << 8);
this.regECX = (this.regECX & 0xff) | (dst << 8);
break;
case 0x6: // DH
this.regDX = (this.regDX & 0xff) | (dst << 8);
this.regEDX = (this.regEDX & 0xff) | (dst << 8);
break;
case 0x7: // BH
this.regBX = (this.regBX & 0xff) | (dst << 8);
this.regEBX = (this.regEBX & 0xff) | (dst << 8);
break;
default:
break; // there IS no other case, but JavaScript inspections don't know that
@ -415,28 +415,28 @@ var X86Help = {
//
switch (this.bModRM & 0x7) {
case 0x0: // AX
this.regAX = dst;
this.regEAX = dst;
break;
case 0x1: // CX
this.regCX = dst;
this.regECX = dst;
break;
case 0x2: // DX
this.regDX = dst;
this.regEDX = dst;
break;
case 0x3: // BX
this.regBX = dst;
this.regEBX = dst;
break;
case 0x4: // SP
this.regSP = dst;
this.regESP = dst;
break;
case 0x5: // BP
this.regBP = dst;
this.regEBP = dst;
break;
case 0x6: // SI
this.regSI = dst;
this.regESI = dst;
break;
case 0x7: // DI
this.regDI = dst;
this.regEDI = dst;
break;
default:
break; // there IS no other case, but JavaScript inspections don't know that
@ -508,9 +508,9 @@ var X86Help = {
opHelpRETF: function(n) {
var regIP = this.popWord();
var regCS = this.popWord();
if (n) this.regSP = (this.regSP + n) & 0xffff;
if (n) this.regESP = (this.regESP + n) & 0xffff;
if (this.setCSIP(regIP, regCS, false)) {
if (n) this.regSP = (this.regSP + n) & 0xffff;
if (n) this.regESP = (this.regESP + n) & 0xffff;
/*
* As per Intel documentation: "If any of [the DS or ES] registers refer to segments whose DPL is
* less than the new CPL (excluding conforming code segments), the segment register is loaded with

8619
modules/pcjs/lib/x86modb.js Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

9534
modules/pcjs/lib/x86modw.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -36,7 +36,6 @@ if (typeof module !== 'undefined') {
var X86 = require("./x86");
var X86Grps = require("./x86grps");
var X86Help = require("./x86help");
var X86Mods = require("./x86mods");
}
var X86Op0F = {
@ -50,7 +49,7 @@ var X86Op0F = {
if ((bModRM & 0x38) < 0x10) { // possible reg values: 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
if (EAFUNCS) this.modEAWord = this.modEAWordDisabled; else this.opFlags |= X86.OPFLAG.NOREAD;
}
X86Mods.aOpModsGrpWord[bModRM].call(this, this.aOpGrp6, X86Grps.opGrpNoSrc);
this.aOpModGrpWord[bModRM].call(this, this.aOpGrp6, X86Grps.opGrpNoSrc);
if (EAFUNCS) { this.modEAWord = this.modEAWordEnabled; this.setEAWord = this.setEAWordEnabled; }
},
/**
@ -63,7 +62,7 @@ var X86Op0F = {
if (!(bModRM & 0x10)) {
if (EAFUNCS) this.modEAWord = this.modEAWordDisabled; else this.opFlags |= X86.OPFLAG.NOREAD;
}
X86Mods.aOpModsGrpWord[bModRM].call(this, X86Op0F.aOpGrp7, X86Grps.opGrpNoSrc);
this.aOpModGrpWord[bModRM].call(this, X86Op0F.aOpGrp7, X86Grps.opGrpNoSrc);
if (EAFUNCS) { this.modEAWord = this.modEAWordEnabled; this.setEAWord = this.setEAWordEnabled; }
},
/**
@ -72,7 +71,7 @@ var X86Op0F = {
* op=0x0F,0x02 (lar reg,rm)
*/
opLAR: function() {
X86Mods.aOpModsRegWord[this.getIPByte()].call(this, X86Help.opHelpLAR);
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLAR);
},
/**
* @this {X86CPU}
@ -80,7 +79,7 @@ var X86Op0F = {
* op=0x0F,0x03 (lsl reg,rm)
*/
opLSL: function() {
X86Mods.aOpModsRegWord[this.getIPByte()].call(this, X86Help.opHelpLSL);
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLSL);
},
/**
* opLOADALL()
@ -132,14 +131,14 @@ var X86Op0F = {
return;
}
X86Help.opHelpLMSW.call(this, this.getWord(0x806));
this.regDI = this.getWord(0x826);
this.regSI = this.getWord(0x828);
this.regBP = this.getWord(0x82A);
this.regSP = this.getWord(0x82C);
this.regBX = this.getWord(0x82E);
this.regDX = this.getWord(0x830);
this.regCX = this.getWord(0x832);
this.regAX = this.getWord(0x834);
this.regEDI = this.getWord(0x826);
this.regESI = this.getWord(0x828);
this.regEBP = this.getWord(0x82A);
this.regESP = this.getWord(0x82C);
this.regEBX = this.getWord(0x82E);
this.regEDX = this.getWord(0x830);
this.regECX = this.getWord(0x832);
this.regEAX = this.getWord(0x834);
this.segES.loadDesc6(0x836, this.getWord(0x824));
this.segCS.loadDesc6(0x83C, this.getWord(0x822));
this.segSS.loadDesc6(0x842, this.getWord(0x820));

File diff suppressed because it is too large Load diff

View file

@ -117,6 +117,7 @@ X86Seg.ID = {
X86Seg.loadReal = function loadReal(sel, fSuppress)
{
this.sel = sel;
this.ext = 0;
return this.base = sel << 4;
};
@ -423,14 +424,14 @@ X86Seg.switchTSS = function switchTSS(selNew, fNest)
}
cpu.setWord(addrOld + X86.TSS.TASK_IP, cpu.regIP);
cpu.setWord(addrOld + X86.TSS.TASK_PS, cpu.getPS());
cpu.setWord(addrOld + X86.TSS.TASK_AX, cpu.regAX);
cpu.setWord(addrOld + X86.TSS.TASK_CX, cpu.regCX);
cpu.setWord(addrOld + X86.TSS.TASK_DX, cpu.regDX);
cpu.setWord(addrOld + X86.TSS.TASK_BX, cpu.regBX);
cpu.setWord(addrOld + X86.TSS.TASK_SP, cpu.regSP);
cpu.setWord(addrOld + X86.TSS.TASK_BP, cpu.regBP);
cpu.setWord(addrOld + X86.TSS.TASK_SI, cpu.regSI);
cpu.setWord(addrOld + X86.TSS.TASK_DI, cpu.regDI);
cpu.setWord(addrOld + X86.TSS.TASK_AX, cpu.regEAX);
cpu.setWord(addrOld + X86.TSS.TASK_CX, cpu.regECX);
cpu.setWord(addrOld + X86.TSS.TASK_DX, cpu.regEDX);
cpu.setWord(addrOld + X86.TSS.TASK_BX, cpu.regEBX);
cpu.setWord(addrOld + X86.TSS.TASK_SP, cpu.regESP);
cpu.setWord(addrOld + X86.TSS.TASK_BP, cpu.regEBP);
cpu.setWord(addrOld + X86.TSS.TASK_SI, cpu.regESI);
cpu.setWord(addrOld + X86.TSS.TASK_DI, cpu.regEDI);
cpu.setWord(addrOld + X86.TSS.TASK_ES, cpu.segES.sel);
cpu.setWord(addrOld + X86.TSS.TASK_CS, cpu.segCS.sel);
cpu.setWord(addrOld + X86.TSS.TASK_SS, cpu.segSS.sel);
@ -439,13 +440,13 @@ X86Seg.switchTSS = function switchTSS(selNew, fNest)
var offSP = X86.TSS.TASK_SP;
cpu.setPS(cpu.getWord(addrNew + X86.TSS.TASK_PS) | (fNest? X86.PS.NT : 0));
cpu.assert(!fNest || !!(cpu.regPS & X86.PS.NT));
cpu.regAX = cpu.getWord(addrNew + X86.TSS.TASK_AX);
cpu.regCX = cpu.getWord(addrNew + X86.TSS.TASK_CX);
cpu.regDX = cpu.getWord(addrNew + X86.TSS.TASK_DX);
cpu.regBX = cpu.getWord(addrNew + X86.TSS.TASK_BX);
cpu.regBP = cpu.getWord(addrNew + X86.TSS.TASK_BP);
cpu.regSI = cpu.getWord(addrNew + X86.TSS.TASK_SI);
cpu.regDI = cpu.getWord(addrNew + X86.TSS.TASK_DI);
cpu.regEAX = cpu.getWord(addrNew + X86.TSS.TASK_AX);
cpu.regECX = cpu.getWord(addrNew + X86.TSS.TASK_CX);
cpu.regEDX = cpu.getWord(addrNew + X86.TSS.TASK_DX);
cpu.regEBX = cpu.getWord(addrNew + X86.TSS.TASK_BX);
cpu.regEBP = cpu.getWord(addrNew + X86.TSS.TASK_BP);
cpu.regESI = cpu.getWord(addrNew + X86.TSS.TASK_SI);
cpu.regEDI = cpu.getWord(addrNew + X86.TSS.TASK_DI);
cpu.segES.load(cpu.getWord(addrNew + X86.TSS.TASK_ES));
cpu.segDS.load(cpu.getWord(addrNew + X86.TSS.TASK_DS));
cpu.setCSIP(cpu.getWord(addrNew + X86.TSS.TASK_IP), cpu.getWord(addrNew + X86.TSS.TASK_CS));
@ -453,7 +454,7 @@ X86Seg.switchTSS = function switchTSS(selNew, fNest)
offSP = (this.cpl << 2) + X86.TSS.CPL0_SP;
offSS = offSP + 2;
}
cpu.regSP = cpu.getWord(addrNew + offSP);
cpu.regESP = cpu.getWord(addrNew + offSP);
cpu.segSS.load(cpu.getWord(addrNew + offSS));
cpu.segLDT.load(cpu.getWord(addrNew + X86.TSS.TASK_LDT));
if (fNest) cpu.setWord(addrNew + X86.TSS.PREV_TSS, selOld);
@ -514,13 +515,15 @@ X86Seg.prototype.loadDesc6 = function(addrDesc, sel)
{
var cpu = this.cpu;
var acc = cpu.getWord(addrDesc + 2);
var base = cpu.getWord(addrDesc + 0) | ((acc & 0xff) << 16);
var base = cpu.getWord(addrDesc) | ((acc & 0xff) << 16);
var limit = cpu.getWord(addrDesc + 4);
this.sel = sel;
this.base = base;
this.limit = limit;
this.acc = acc & X86.DESC.ACC.MASK;
this.type = (acc & X86.DESC.ACC.TYPE.MASK);
this.ext = 0;
this.addrDesc = addrDesc;
this.updateMode();
@ -554,7 +557,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
var acc = cpu.getWord(addrDesc + X86.DESC.ACC.OFFSET);
var type = (acc & X86.DESC.ACC.TYPE.MASK);
var base = cpu.getWord(addrDesc + X86.DESC.BASE.OFFSET) | ((acc & X86.DESC.ACC.BASE1623) << 16);
var ext = (DEBUG? cpu.getWord(addrDesc + X86.DESC.EXT.OFFSET) : 0);
var ext = cpu.getWord(addrDesc + X86.DESC.EXT.OFFSET);
var selMasked = sel & X86.SEL.MASK;
while (true) {
@ -589,7 +592,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
}
regSP = cpu.popWord();
cpu.segSS.load(cpu.popWord());
cpu.regSP = regSP;
cpu.regESP = regSP;
this.fStackSwitch = true;
}
fGate = false;
@ -644,7 +647,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
base = X86.ADDR_INVALID;
break;
}
regSP = cpu.regSP;
regSP = cpu.regESP;
var i = 0, nWords = (acc & 0x1f);
while (nWords--) {
this.awParms[i++] = cpu.getSOWord(cpu.segSS, regSP);
@ -653,9 +656,9 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
addrTSS = cpu.segTSS.base;
offSP = (this.cpl << 2) + X86.TSS.CPL0_SP;
offSS = offSP + 2;
regSPPrev = cpu.regSP;
regSPPrev = cpu.regESP;
regSSPrev = cpu.segSS.sel;
cpu.regSP = cpu.getWord(addrTSS + offSP);
cpu.regESP = cpu.getWord(addrTSS + offSP);
cpu.segSS.load(cpu.getWord(addrTSS + offSS));
cpu.pushWord(regSSPrev);
cpu.pushWord(regSPPrev);
@ -735,6 +738,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
this.limit = limit;
this.acc = acc;
this.type = type;
this.ext = ext;
this.addrDesc = addrDesc;
this.updateMode();
break;