Halt (for now) on any 80386 GP fault, and prevent SPACE from scrolling the page
This commit is contained in:
parent
33d28a29de
commit
c2d9d6b25f
3 changed files with 37 additions and 24 deletions
|
|
@ -528,14 +528,18 @@ Memory.prototype = {
|
||||||
if (cpu) this.cpu = cpu;
|
if (cpu) this.cpu = cpu;
|
||||||
this.setReadAccess(Memory.afnChecked, false);
|
this.setReadAccess(Memory.afnChecked, false);
|
||||||
}
|
}
|
||||||
if (DEBUG && this.dbg) this.dbg.println("read breakpoint added to memory block " + str.toHex(this.addr));
|
if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {
|
||||||
|
this.dbg.printMessage("read breakpoint added to memory block " + str.toHex(this.addr), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.cWriteBreakpoints++ === 0) {
|
if (this.cWriteBreakpoints++ === 0) {
|
||||||
if (cpu) this.cpu = cpu;
|
if (cpu) this.cpu = cpu;
|
||||||
this.setWriteAccess(Memory.afnChecked, false);
|
this.setWriteAccess(Memory.afnChecked, false);
|
||||||
}
|
}
|
||||||
if (DEBUG && this.dbg) this.dbg.println("write breakpoint added to memory block " + str.toHex(this.addr));
|
if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {
|
||||||
|
this.dbg.printMessage("write breakpoint added to memory block " + str.toHex(this.addr), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|
@ -558,14 +562,18 @@ Memory.prototype = {
|
||||||
if (!fWrite) {
|
if (!fWrite) {
|
||||||
if (--this.cReadBreakpoints === 0) {
|
if (--this.cReadBreakpoints === 0) {
|
||||||
this.resetReadAccess();
|
this.resetReadAccess();
|
||||||
if (DEBUG && this.dbg) this.dbg.println("all read breakpoints removed from memory block " + str.toHex(this.addr));
|
if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {
|
||||||
|
this.dbg.printMessage("all read breakpoints removed from memory block " + str.toHex(this.addr), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Component.assert(this.cReadBreakpoints >= 0);
|
Component.assert(this.cReadBreakpoints >= 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (--this.cWriteBreakpoints === 0) {
|
if (--this.cWriteBreakpoints === 0) {
|
||||||
this.resetWriteAccess();
|
this.resetWriteAccess();
|
||||||
if (DEBUG && this.dbg) this.dbg.println("all write breakpoints removed from memory block " + str.toHex(this.addr));
|
if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {
|
||||||
|
this.dbg.printMessage("all write breakpoints removed from memory block " + str.toHex(this.addr), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Component.assert(this.cWriteBreakpoints >= 0);
|
Component.assert(this.cWriteBreakpoints >= 0);
|
||||||
}
|
}
|
||||||
|
|
@ -1105,9 +1113,8 @@ Memory.prototype = {
|
||||||
readShortLittleEndian: function readShortLittleEndian(off, addr) {
|
readShortLittleEndian: function readShortLittleEndian(off, addr) {
|
||||||
// DEBUG: Component.assert(off >= 0 && off < this.size - 1);
|
// DEBUG: Component.assert(off >= 0 && off < this.size - 1);
|
||||||
/*
|
/*
|
||||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
* TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read
|
||||||
* for an aligned read vs. always reading the bytes separately; it seems a safe bet
|
* vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.
|
||||||
* for longs, but it's less clear for shorts.
|
|
||||||
*/
|
*/
|
||||||
return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];
|
return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];
|
||||||
},
|
},
|
||||||
|
|
@ -1134,9 +1141,8 @@ Memory.prototype = {
|
||||||
readLongLittleEndian: function readLongLittleEndian(off, addr) {
|
readLongLittleEndian: function readLongLittleEndian(off, addr) {
|
||||||
// DEBUG: Component.assert(off >= 0 && off < this.size - 3);
|
// DEBUG: Component.assert(off >= 0 && off < this.size - 3);
|
||||||
/*
|
/*
|
||||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
* TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read
|
||||||
* for an aligned read vs. always reading the bytes separately; it seems a safe bet
|
* vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.
|
||||||
* for longs, but it's less clear for shorts.
|
|
||||||
*/
|
*/
|
||||||
return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];
|
return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];
|
||||||
},
|
},
|
||||||
|
|
@ -1190,9 +1196,8 @@ Memory.prototype = {
|
||||||
writeShortLittleEndian: function writeShortLittleEndian(off, w, addr) {
|
writeShortLittleEndian: function writeShortLittleEndian(off, w, addr) {
|
||||||
// DEBUG: Component.assert(off >= 0 && off < this.size - 1);
|
// DEBUG: Component.assert(off >= 0 && off < this.size - 1);
|
||||||
/*
|
/*
|
||||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
* TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write
|
||||||
* for an aligned write vs. always writing the bytes separately; it seems a safe bet
|
* vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.
|
||||||
* for longs, but it's less clear for shorts.
|
|
||||||
*/
|
*/
|
||||||
if (off & 0x1) {
|
if (off & 0x1) {
|
||||||
this.ab[off] = w;
|
this.ab[off] = w;
|
||||||
|
|
@ -1226,9 +1231,8 @@ Memory.prototype = {
|
||||||
writeLongLittleEndian: function writeLongLittleEndian(off, l, addr) {
|
writeLongLittleEndian: function writeLongLittleEndian(off, l, addr) {
|
||||||
// DEBUG: Component.assert(off >= 0 && off < this.size - 3);
|
// DEBUG: Component.assert(off >= 0 && off < this.size - 3);
|
||||||
/*
|
/*
|
||||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
* TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write
|
||||||
* for an aligned write vs. always writing the bytes separately; it seems a safe bet
|
* vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.
|
||||||
* for longs, but it's less clear for shorts.
|
|
||||||
*/
|
*/
|
||||||
if (off & 0x3) {
|
if (off & 0x3) {
|
||||||
this.ab[off] = l;
|
this.ab[off] = l;
|
||||||
|
|
|
||||||
|
|
@ -336,23 +336,32 @@ SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control)
|
||||||
control.onkeydown = function onKeyDownSerial(event) {
|
control.onkeydown = function onKeyDownSerial(event) {
|
||||||
/*
|
/*
|
||||||
* This is required in addition to onkeypress, because it's the only way to prevent
|
* This is required in addition to onkeypress, because it's the only way to prevent
|
||||||
* BACKSPACE from being interpreted by the browser as a "Back" operation.
|
* BACKSPACE (keyCode 8) from being interpreted by the browser as a "Back" operation;
|
||||||
|
* moreover, not all browsers generate an onkeypress notification for BACKSPACE.
|
||||||
*/
|
*/
|
||||||
event = event || window.event;
|
event = event || window.event;
|
||||||
var keyCode = event.keyCode;
|
var keyCode = event.keyCode;
|
||||||
if (keyCode === 8) {
|
if (keyCode === 8) {
|
||||||
if (event.preventDefault) event.preventDefault();
|
if (event.preventDefault) event.preventDefault();
|
||||||
serial.sendRBR([keyCode]);
|
serial.sendRBR([keyCode]);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
control.onkeypress = function onKeyPressSerial(event) {
|
control.onkeypress = function onKeyPressSerial(event) {
|
||||||
/*
|
/*
|
||||||
* Browser-independent keyCode extraction (refer to keyPress() and the other key
|
* Browser-independent keyCode extraction (refer to keyPress() and the other key
|
||||||
* event handlers in keyboard.js).
|
* event handlers in keyboard.js).
|
||||||
|
*
|
||||||
|
* The additional check for SPACE (keyCode 32) and subsequent preventDefault() call
|
||||||
|
* prevents SPACE from bubbling up to the document event handlers, where its default
|
||||||
|
* behavior is typically to scroll the entire page -- a real nuisance.
|
||||||
*/
|
*/
|
||||||
event = event || window.event;
|
event = event || window.event;
|
||||||
var keyCode = event.which || event.keyCode;
|
var keyCode = event.which || event.keyCode;
|
||||||
serial.sendRBR([keyCode]);
|
serial.sendRBR([keyCode]);
|
||||||
|
if (keyCode == 32) {
|
||||||
|
if (event.preventDefault) event.preventDefault();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3831,14 +3831,14 @@ X86.fnFaultMessage = function(nFault, nError, fHalt)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are a number of V86-mode exceptions we don't need to know about. For starters, Windows 3.00
|
* There are a number of V86-mode exceptions we don't need to know about. For starters, Windows 3.00
|
||||||
* (and other versions of enhanced-mode Windows) use an ARPL in V86-mode to switch out of V86-mode, so
|
* (and other versions of enhanced-mode Windows) use an ARPL to switch out of V86-mode, so we can ignore
|
||||||
* we can ignore those UD_FAULTs.
|
* those UD_FAULTs.
|
||||||
*
|
*
|
||||||
* Ditto for software interrupts, which will generate a GP_FAULT when the interrupt number (eg, 0x6D)
|
* Ditto for software interrupts, which will generate a GP_FAULT when the interrupt number (eg, 0x6D)
|
||||||
* exceeds the protected-mode IDT's limit (eg, a limit of 0x2FF yields a maximum interrupt number of 0x5F).
|
* exceeds the protected-mode IDT's limit (eg, a limit of 0x2FF corresponds to a maximum interrupt number
|
||||||
* Windows doesn't really care if its IDT is too small, because no matter what, it has to simulate all
|
* of 0x5F). Windows doesn't really care if its IDT is too small, because it has to simulate all software
|
||||||
* software interrupts in V86-mode (they will also generate a GP_FAULT if IOPL < 3, and even if IOPL == 3,
|
* interrupts in V86-mode regardless (they generate a GP_FAULT if IOPL < 3, and even when IOPL == 3, only
|
||||||
* only the protected-mode IDT handler gets to run).
|
* the protected-mode IDT handler gets to run).
|
||||||
*/
|
*/
|
||||||
if ((this.regPS & X86.PS.VM)) {
|
if ((this.regPS & X86.PS.VM)) {
|
||||||
if (nFault == X86.EXCEPTION.UD_FAULT && bOpcode == X86.OPCODE.ARPL ||
|
if (nFault == X86.EXCEPTION.UD_FAULT && bOpcode == X86.OPCODE.ARPL ||
|
||||||
|
|
@ -3846,7 +3846,7 @@ X86.fnFaultMessage = function(nFault, nError, fHalt)
|
||||||
fHalt = false;
|
fHalt = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (MAXDEBUG && nFault == X86.EXCEPTION.NP_FAULT && bOpcode == 0x8E) {
|
if (nFault == X86.EXCEPTION.GP_FAULT && this.model == X86.MODEL_80386 /* || nFault == X86.EXCEPTION.NP_FAULT && bOpcode == 0x8E */) {
|
||||||
fHalt = true;
|
fHalt = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue