Standard-mode Windows 3.0 finally runs properly

This commit is contained in:
Jeff Parsons 2015-07-30 12:50:44 -07:00
commit 812c0af6b6
163 changed files with 7862 additions and 980 deletions

View file

@ -1709,12 +1709,15 @@ if (DEBUGGER) {
{
if (dbgAddr.sel != null) {
var seg = this.getSegment(dbgAddr.sel, dbgAddr.fProt);
if (seg && (dbgAddr.off >>> 0) >= seg.offMax) {
/*
* TODO: This automatic wrap-to-zero is OK for normal segments, but for expand-down segments, not so much.
*/
dbgAddr.off = 0;
dbgAddr.addr = null;
if (seg) {
dbgAddr.off &= seg.addrMask;
if ((dbgAddr.off >>> 0) >= seg.offMax) {
/*
* TODO: This automatic wrap-to-zero is OK for normal segments, but for expand-down segments, not so much.
*/
dbgAddr.off = 0;
dbgAddr.addr = null;
}
}
}
};
@ -3468,7 +3471,7 @@ if (DEBUGGER) {
* like "LEA AX,BX", it will actually do something (on some if not all processors), so
* there's probably some diagnostic value in allowing those cases to be disassembled.
*/
sOperand = this.getModRMOperand(bModRM, type, dbgAddr);
sOperand = this.getModRMOperand(bModRM, type, cOperands, dbgAddr);
}
else if (typeMode == Debugger.TYPE_MODREG) {
/*
@ -3685,15 +3688,16 @@ if (DEBUGGER) {
};
/**
* getModRMOperand(bModRM, type, dbgAddr)
* getModRMOperand(bModRM, type, cOperands, dbgAddr)
*
* @this {Debugger}
* @param {number} bModRM
* @param {number} type
* @param {number} cOperands (if 1, memory operands are prefixed with the size; otherwise, size can be inferred)
* @param {{DbgAddr}} dbgAddr
* @return {string} operand
*/
Debugger.prototype.getModRMOperand = function(bModRM, type, dbgAddr)
Debugger.prototype.getModRMOperand = function(bModRM, type, cOperands, dbgAddr)
{
var sOperand = "";
var bMod = bModRM >> 6;
@ -3733,7 +3737,28 @@ if (DEBUGGER) {
}
}
sOperand = "[" + sOperand + "]";
if ((type & Debugger.TYPE_SIZE) == Debugger.TYPE_FARP) sOperand = "FAR " + sOperand;
if (cOperands == 1) {
var sPrefix = "";
type &= Debugger.TYPE_SIZE;
if (type == Debugger.TYPE_VWORD) {
type = (dbgAddr.fData32? Debugger.TYPE_DWORD : Debugger.TYPE_WORD);
}
switch(type) {
case Debugger.TYPE_FARP:
sPrefix = "FAR";
break;
case Debugger.TYPE_BYTE:
sPrefix = "BYTE";
break;
case Debugger.TYPE_WORD:
sPrefix = "WORD";
break;
case Debugger.TYPE_DWORD:
sPrefix = "DWORD";
break;
}
if (sPrefix) sOperand = sPrefix + ' ' + sOperand;
}
}
else {
sOperand = this.getRegOperand(bRM, type, dbgAddr);

View file

@ -3437,6 +3437,7 @@ X86.fnXCHGrb = function XCHGRb(dst, src)
/*
* Decode which register was src
*/
this.assert(!(dst & ~0xff)); // confirm that dst contains only 8 bits
switch (this.bModRM & 0x7) {
case 0x0: // AL
this.regEAX = (this.regEAX & ~0xff) | dst;
@ -3451,16 +3452,16 @@ X86.fnXCHGrb = function XCHGRb(dst, src)
this.regEBX = (this.regEBX & ~0xff) | dst;
break;
case 0x4: // AH
this.regEAX = (this.regEAX & 0xff) | (dst << 8);
this.regEAX = (this.regEAX & ~0xff00) | (dst << 8);
break;
case 0x5: // CH
this.regECX = (this.regECX & 0xff) | (dst << 8);
this.regECX = (this.regECX & ~0xff00) | (dst << 8);
break;
case 0x6: // DH
this.regEDX = (this.regEDX & 0xff) | (dst << 8);
this.regEDX = (this.regEDX & ~0xff00) | (dst << 8);
break;
case 0x7: // BH
this.regEBX = (this.regEBX & 0xff) | (dst << 8);
this.regEBX = (this.regEBX & ~0xff00) | (dst << 8);
break;
default:
break; // there IS no other case, but JavaScript inspections don't know that
@ -3501,30 +3502,31 @@ X86.fnXCHGrw = function XCHGRw(dst, src)
/*
* Decode which register was src
*/
this.assert(!(dst & ~this.dataMask)); // confirm that dst contains only 16 or 32 bits
switch (this.bModRM & 0x7) {
case 0x0: // AX
this.regEAX = dst;
case 0x0: // [E]AX
this.regEAX = (this.regEAX & ~this.dataMask) | dst;
break;
case 0x1: // CX
this.regECX = dst;
case 0x1: // [E]CX
this.regECX = (this.regECX & ~this.dataMask) | dst;
break;
case 0x2: // DX
this.regEDX = dst;
case 0x2: // [E]DX
this.regEDX = (this.regEDX & ~this.dataMask) | dst;
break;
case 0x3: // BX
this.regEBX = dst;
case 0x3: // [E]BX
this.regEBX = (this.regEBX & ~this.dataMask) | dst;
break;
case 0x4: // SP
this.setSP(dst);
case 0x4: // [E]SP
this.setSP((this.getSP() & ~this.dataMask) | dst);
break;
case 0x5: // BP
this.regEBP = dst;
case 0x5: // [E]BP
this.regEBP = (this.regEBX & ~this.dataMask) | dst;
break;
case 0x6: // SI
this.regESI = dst;
case 0x6: // [E]SI
this.regESI = (this.regESI & ~this.dataMask) | dst;
break;
case 0x7: // DI
this.regEDI = dst;
case 0x7: // [E]DI
this.regEDI = (this.regEDI & ~this.dataMask) | dst;
break;
default:
break; // there IS no other case, but JavaScript inspections don't know that