diff --git a/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml b/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml
index a910979d1..ecc45d89f 100644
--- a/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml
+++ b/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js
index 9bf921b65..8d6883262 100644
--- a/modules/pcjs/lib/debugger.js
+++ b/modules/pcjs/lib/debugger.js
@@ -1538,13 +1538,15 @@ if (DEBUGGER) {
*/
if (this.nSuppressBreaks && fProt || !this.segDebugger) return null;
}
-
+ var seg = this.segDebugger;
if (!fProt) {
- this.segDebugger.loadReal(sel);
+ seg.loadReal(sel);
+ seg.limit = 0xffff; // although an ACTUAL real-mode segment load would not modify the limit,
+ seg.offMax = 0x10000; // proper segDebugger operation requires that we update the limit ourselves
} else {
- this.segDebugger.loadProt(sel);
+ seg.loadProt(sel);
}
- return this.segDebugger;
+ return seg;
};
/**
@@ -2929,7 +2931,7 @@ if (DEBUGGER) {
if (!fRegs || this.nStep == 1)
this.doUnassemble();
else {
- this.doRegisters(null);
+ this.doRegisters();
}
};
@@ -3841,6 +3843,7 @@ if (DEBUGGER) {
if (dbgAddrIns.addr != X86.ADDR_INVALID && dbgAddr.addr != X86.ADDR_INVALID) {
do {
sBytes += str.toHex(this.getByte(dbgAddrIns, 1), 2);
+ if (dbgAddrIns.addr == null) break;
} while (dbgAddrIns.addr != dbgAddr.addr);
}
diff --git a/modules/pcjs/lib/x86ops.js b/modules/pcjs/lib/x86ops.js
index d517291a0..0980eb12e 100644
--- a/modules/pcjs/lib/x86ops.js
+++ b/modules/pcjs/lib/x86ops.js
@@ -3079,7 +3079,7 @@ X86.opMOVBLb = function MOVBLb()
*/
X86.opMOVAHb = function MOVAHb()
{
- this.regEAX = (this.regEAX & 0xff) | (this.getIPByte() << 8);
+ this.regEAX = (this.regEAX & ~0xff00) | (this.getIPByte() << 8);
if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiMem0;
this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;
};
@@ -3091,7 +3091,7 @@ X86.opMOVAHb = function MOVAHb()
*/
X86.opMOVCHb = function MOVCHb()
{
- this.regECX = (this.regECX & 0xff) | (this.getIPByte() << 8);
+ this.regECX = (this.regECX & ~0xff00) | (this.getIPByte() << 8);
if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiMem0;
this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;
};
@@ -3103,7 +3103,7 @@ X86.opMOVCHb = function MOVCHb()
*/
X86.opMOVDHb = function MOVDHb()
{
- this.regEDX = (this.regEDX & 0xff) | (this.getIPByte() << 8);
+ this.regEDX = (this.regEDX & ~0xff00) | (this.getIPByte() << 8);
if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiMem0;
this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;
};
@@ -3115,7 +3115,7 @@ X86.opMOVDHb = function MOVDHb()
*/
X86.opMOVBHb = function MOVBHb()
{
- this.regEBX = (this.regEBX & 0xff) | (this.getIPByte() << 8);
+ this.regEBX = (this.regEBX & ~0xff00) | (this.getIPByte() << 8);
if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiMem0;
this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;
};
diff --git a/modules/pcjs/lib/x86seg.js b/modules/pcjs/lib/x86seg.js
index 8061ca10f..fcaea721b 100644
--- a/modules/pcjs/lib/x86seg.js
+++ b/modules/pcjs/lib/x86seg.js
@@ -1194,6 +1194,26 @@ X86Seg.prototype.updateMode = function(fLoad, fProt, fV86)
if (this.checkWrite == this.checkWriteProt) this.checkWrite = this.checkWriteProtDown;
this.fExpDown = true;
}
+ if (fLoad && this.id < X86Seg.ID.VER) {
+ /*
+ * We must update the descriptor's ACCESSED bit whenever the segment is "accessed" (ie,
+ * loaded); unlike the ACCESSED and DIRTY bits in PTEs, a descriptor ACCESSED bit is only
+ * updated on loads, not on every memory access.
+ *
+ * We compute address of the descriptor byte containing the ACCESSED bit (offset 0x5);
+ * note that it's perfectly normal for addrDesc to occasionally be invalid (eg, when the CPU
+ * is creating protected-mode-only segment registers like LDT and TSS, or when the CPU has
+ * transitioned from real-mode to protected-mode and new selector(s) have not been loaded yet).
+ *
+ * TODO: Note I do NOT update the ACCESSED bit for null GDT selectors, because I assume the
+ * hardware does not update it either. In fact, I've seen code that uses the null GDT descriptor
+ * for other purposes, on the assumption that that descriptor is completely unused.
+ */
+ if ((this.sel & ~X86.SEL.RPL) && this.addrDesc !== X86.ADDR_INVALID) {
+ var addrType = this.addrDesc + X86.DESC.ACC.TYPE.OFFSET;
+ this.cpu.setByte(addrType, this.cpu.getByte(addrType) | (X86.DESC.ACC.TYPE.ACCESSED >> 8));
+ }
+ }
}
/*
* TODO: For non-SEG descriptors, are there other checks or functions we should establish?
@@ -1204,24 +1224,6 @@ X86Seg.prototype.updateMode = function(fLoad, fProt, fV86)
* we're updating segment registers as part of a mode change.
*/
if (fLoad) {
- /*
- * We must update the descriptor's ACCESSED bit whenever the segment is "accessed" (ie,
- * loaded); unlike the ACCESSED and DIRTY bits in PTEs, a descriptor ACCESSED bit is only
- * updated on loads, not on every memory access.
- *
- * We compute address of the descriptor byte containing the ACCESSED bit (offset 0x5);
- * note that it's perfectly normal for addrDesc to occasionally be invalid (eg, when the CPU
- * is creating protected-mode-only segment registers like LDT and TSS, or when the CPU has
- * transitioned from real-mode to protected-mode and new selector(s) have not been loaded yet).
- *
- * TODO: Note I do NOT update the ACCESSED bit for null GDT selectors, because I assume the
- * hardware does not update it either. In fact, I've seen code that uses the null GDT descriptor
- * for other purposes, on the assumption that that descriptor is completely unused.
- */
- if ((this.sel & ~X86.SEL.RPL) && this.addrDesc !== X86.ADDR_INVALID) {
- var addrType = this.addrDesc + X86.DESC.ACC.TYPE.OFFSET;
- this.cpu.setByte(addrType, this.cpu.getByte(addrType) | (X86.DESC.ACC.TYPE.ACCESSED >> 8));
- }
this.cpl = this.sel & X86.SEL.RPL;
this.dpl = (this.acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;
if (this.cpu.model < X86.MODEL_80386 || !(this.ext & X86.DESC.EXT.BIG)) {