Lots o' Debugger changes, including support for breakpoint commands and logical expressions
A new "if" command for use within breakpoint commands makes it possible to conditionally halt execution now
This commit is contained in:
parent
a9b5813303
commit
2fd9f6cfe5
4 changed files with 505 additions and 355 deletions
|
|
@ -792,18 +792,23 @@ CPU.prototype.getSpeedTarget = function()
|
|||
* @this {CPU}
|
||||
* @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)
|
||||
* @param {boolean} [fOnClick] is true if called from a click handler that might have stolen focus
|
||||
* @return {boolean} true if successful, false if not
|
||||
* @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,
|
||||
* so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls
|
||||
* setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).
|
||||
*/
|
||||
CPU.prototype.setSpeed = function(nMultiplier, fOnClick)
|
||||
{
|
||||
var fSuccess = false;
|
||||
if (nMultiplier !== undefined) {
|
||||
/*
|
||||
* If we couldn't reach at least 80% (0.8) of the current target speed,
|
||||
* then revert the multiplier back to one.
|
||||
* If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).
|
||||
*/
|
||||
if (this.aCounts.mhz / this.aCounts.mhzTarget < 0.8) nMultiplier = 1;
|
||||
if (this.aCounts.mhz / this.aCounts.mhzTarget < 0.8) {
|
||||
nMultiplier = 1;
|
||||
} else {
|
||||
fSuccess = true;
|
||||
}
|
||||
this.aCounts.nCyclesMultiplier = nMultiplier;
|
||||
var mhz = this.aCounts.mhzDefault * this.aCounts.nCyclesMultiplier;
|
||||
if (this.aCounts.mhzTarget != mhz) {
|
||||
|
|
@ -820,6 +825,7 @@ CPU.prototype.setSpeed = function(nMultiplier, fOnClick)
|
|||
this.aCounts.msStartRun = usr.getTime();
|
||||
this.aCounts.msEndThisRun = 0;
|
||||
this.calcCycles();
|
||||
return fSuccess;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -59,6 +59,48 @@ var X86 = {
|
|||
*/
|
||||
ADDR_INVALID: -1,
|
||||
|
||||
/*
|
||||
* Processor Exception Interrupts
|
||||
*
|
||||
* Of the following exceptions, all are designed to be restartable, except for 0x08 and 0x09 (and 0x0D
|
||||
* after an attempt to write to a read-only segment).
|
||||
*
|
||||
* Error codes are pushed onto the stack for 0x08 (always 0) and 0x0A through 0x0D.
|
||||
*
|
||||
* Priority: Instruction exception, TRAP, NMI, Processor Extension Segment Overrun, and finally INTR.
|
||||
*
|
||||
* All exceptions can also occur in real-mode, except where noted. A GP_FAULT in real-mode can be triggered
|
||||
* by "any memory reference instruction that attempts to reference [a] 16-bit word at offset 0FFFFH".
|
||||
*
|
||||
* Interrupts beyond 0x10 (up through 0x1F) are reserved for future exceptions.
|
||||
*
|
||||
* Implementation Detail: For any opcode we know must generate a UD_FAULT interrupt, we invoke opInvalid(),
|
||||
* NOT opUndefined(). UD_FAULT is for INVALID opcodes, Intel's choice of term "undefined" notwithstanding.
|
||||
*
|
||||
* We reserve the term "undefined" for opcodes that require more investigation, and we invoke opUndefined()
|
||||
* ONLY until an opcode's behavior has finally been defined, at which point it becomes either valid or invalid.
|
||||
* The term "illegal" seems completely superfluous; we don't need a third way of describing invalid opcodes.
|
||||
*
|
||||
* The term "undocumented" should be limited to operations that are valid but Intel simply never documented.
|
||||
*/
|
||||
EXCEPTION: {
|
||||
DIV_ERR: 0x00, // Divide Error Interrupt
|
||||
DEBUG: 0x01, // Debug (aka Single Step Trap) Interrupt
|
||||
NMI: 0x02, // Non-Maskable Interrupt
|
||||
BREAKPOINT: 0x03, // Breakpoint Interrupt
|
||||
OVERFLOW: 0x04, // INTO Overflow Interrupt (FYI, return address does NOT point to offending instruction)
|
||||
BOUND_ERR: 0x05, // BOUND Error Interrupt
|
||||
UD_FAULT: 0x06, // Invalid (aka Undefined or Illegal) Opcode (see implementation detail above)
|
||||
NM_FAULT: 0x07, // No Math Unit Available (see ESC or WAIT)
|
||||
DF_FAULT: 0x08, // Double Fault (see LIDT)
|
||||
MP_FAULT: 0x09, // Math Unit Protection Fault (see ESC)
|
||||
TS_FAULT: 0x0A, // Invalid Task State Segment Fault (protected-mode only)
|
||||
NP_FAULT: 0x0B, // Not Present Fault (protected-mode only)
|
||||
SS_FAULT: 0x0C, // Stack Fault (protected-mode only)
|
||||
GP_FAULT: 0x0D, // General Protection Fault
|
||||
PG_FAULT: 0x0E, // Page Fault
|
||||
MF_FAULT: 0x10 // Math Fault (see ESC or WAIT)
|
||||
},
|
||||
/*
|
||||
* Processor Status flag definitions (stored in regPS)
|
||||
*/
|
||||
|
|
@ -284,48 +326,6 @@ var X86 = {
|
|||
TASK_LDT: 0x60,
|
||||
TASK_IOPM: 0x64 // (not in TSS286)
|
||||
},
|
||||
/*
|
||||
* Processor Exception Interrupts
|
||||
*
|
||||
* Of the following exceptions, all are designed to be restartable, except for 0x08 and 0x09 (and 0x0D
|
||||
* after an attempt to write to a read-only segment).
|
||||
*
|
||||
* Error codes are pushed onto the stack for 0x08 (always 0) and 0x0A through 0x0D.
|
||||
*
|
||||
* Priority: Instruction exception, TRAP, NMI, Processor Extension Segment Overrun, and finally INTR.
|
||||
*
|
||||
* All exceptions can also occur in real-mode, except where noted. A GP_FAULT in real-mode can be triggered
|
||||
* by "any memory reference instruction that attempts to reference [a] 16-bit word at offset 0FFFFH".
|
||||
*
|
||||
* Interrupts beyond 0x10 (up through 0x1F) are reserved for future exceptions.
|
||||
*
|
||||
* Implementation Detail: For any opcode we know must generate a UD_FAULT interrupt, we invoke opInvalid(),
|
||||
* NOT opUndefined(). UD_FAULT is for INVALID opcodes, Intel's choice of term "undefined" notwithstanding.
|
||||
*
|
||||
* We reserve the term "undefined" for opcodes that require more investigation, and we invoke opUndefined()
|
||||
* ONLY until an opcode's behavior has finally been defined, at which point it becomes either valid or invalid.
|
||||
* The term "illegal" seems completely superfluous; we don't need a third way of describing invalid opcodes.
|
||||
*
|
||||
* The term "undocumented" should be limited to operations that are valid but Intel simply never documented.
|
||||
*/
|
||||
EXCEPTION: {
|
||||
DIV_ERR: 0x00, // Divide Error Interrupt
|
||||
DEBUG: 0x01, // Debug (aka Single Step Trap) Interrupt
|
||||
NMI: 0x02, // Non-Maskable Interrupt
|
||||
BREAKPOINT: 0x03, // Breakpoint Interrupt
|
||||
OVERFLOW: 0x04, // INTO Overflow Interrupt (FYI, return address does NOT point to offending instruction)
|
||||
BOUND_ERR: 0x05, // BOUND Error Interrupt
|
||||
UD_FAULT: 0x06, // Invalid (aka Undefined or Illegal) Opcode (see implementation detail above)
|
||||
NM_FAULT: 0x07, // No Math Unit Available (see ESC or WAIT)
|
||||
DF_FAULT: 0x08, // Double Fault (see LIDT)
|
||||
MP_FAULT: 0x09, // Math Unit Protection Fault (see ESC)
|
||||
TS_FAULT: 0x0A, // Invalid Task State Segment Fault (protected-mode only)
|
||||
NP_FAULT: 0x0B, // Not Present Fault (protected-mode only)
|
||||
SS_FAULT: 0x0C, // Stack Fault (protected-mode only)
|
||||
GP_FAULT: 0x0D, // General Protection Fault
|
||||
PG_FAULT: 0x0E, // Page Fault
|
||||
MF_FAULT: 0x10 // Math Fault (see ESC or WAIT)
|
||||
},
|
||||
ERRCODE: {
|
||||
EXT: 0x0001,
|
||||
IDT: 0x0002,
|
||||
|
|
|
|||
|
|
@ -3846,7 +3846,7 @@ X86.fnFaultMessage = function(nFault, nError, fHalt)
|
|||
fHalt = false;
|
||||
}
|
||||
} else {
|
||||
if (nFault == X86.EXCEPTION.GP_FAULT && this.model == X86.MODEL_80386 /* || nFault == X86.EXCEPTION.NP_FAULT && bOpcode == 0x8E */) {
|
||||
if (nFault == X86.EXCEPTION.SS_FAULT || nFault == X86.EXCEPTION.GP_FAULT && this.model == X86.MODEL_80386 /* || nFault == X86.EXCEPTION.NP_FAULT && bOpcode == 0x8E */) {
|
||||
fHalt = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue