v1.17.0: Widening registers
This commit is contained in:
parent
c5d9b7dfcc
commit
1ede9acf15
133 changed files with 20419 additions and 19923 deletions
|
|
@ -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(" }");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
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
9534
modules/pcjs/lib/x86modw.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue