Standard-mode Windows 3.0 finally runs properly
This commit is contained in:
parent
0a015b979b
commit
812c0af6b6
163 changed files with 7862 additions and 980 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue