Smoothed out PCx86 dynamic CPU speed recalculation by no longer truncating the current cycle multiplier
This commit is contained in:
parent
591d6b85d5
commit
7f973a03b9
23 changed files with 1351 additions and 1308 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -891,8 +891,8 @@ class CPU8080 extends Component {
|
|||
*/
|
||||
this.nCyclesRecalc += this.nCyclesThisRun;
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages8080.LOG) && msRemainsThisRun) {
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.msEndThisRun + "ms");
|
||||
if (DEBUG && this.messageEnabled(Messages8080.CPU) && msRemainsThisRun) {
|
||||
this.printMessage("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.msEndThisRun + "ms");
|
||||
}
|
||||
|
||||
this.msEndThisRun += msRemainsThisRun;
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ class Debugger8080 extends Debugger {
|
|||
this.sInitCommands = parmsDbg['commands'];
|
||||
|
||||
/*
|
||||
* Make it easier to access Debugger8080 commands from an external REPL (eg, the WebStorm
|
||||
* "live" console window); eg:
|
||||
* Make it easier to access Debugger commands from an external REPL, like the WebStorm "live" console
|
||||
* window; eg:
|
||||
*
|
||||
* pc8080('r')
|
||||
* pc8080('dw 0:0')
|
||||
|
|
@ -769,7 +769,7 @@ class Debugger8080 extends Debugger {
|
|||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = Messages8080.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
/*
|
||||
* Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects,
|
||||
* but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard".
|
||||
|
|
@ -1016,8 +1016,8 @@ class Debugger8080 extends Debugger {
|
|||
sMessage += " at " + this.toHexAddr(this.newAddr(this.cpu.getPC()));
|
||||
}
|
||||
|
||||
if (this.bitsMessage & Messages8080.BUFFER) {
|
||||
this.aMessageBuffer.push(sMessage);
|
||||
if (this.bitsMessage & Messages8080.LOG) {
|
||||
this.aMessageLog.push(sMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3035,11 +3035,11 @@ class Debugger8080 extends Debugger {
|
|||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
if (bitsMessage == Messages8080.BUFFER) {
|
||||
for (var i = 0; i < this.aMessageBuffer.length; i++) {
|
||||
this.println(this.aMessageBuffer[i]);
|
||||
if (bitsMessage == Messages8080.LOG) {
|
||||
for (var i = 0; i < this.aMessageLog.length; i++) {
|
||||
this.println(this.aMessageLog[i]);
|
||||
}
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,9 +43,8 @@ var Messages8080 = {
|
|||
SERIAL: 0x00800000,
|
||||
SPEAKER: 0x02000000,
|
||||
COMPUTER: 0x04000000,
|
||||
LOG: 0x10000000,
|
||||
WARN: 0x20000000,
|
||||
BUFFER: 0x40000000,
|
||||
LOG: 0x20000000,
|
||||
WARN: 0x40000000,
|
||||
HALT: 0x80000000|0
|
||||
};
|
||||
|
||||
|
|
@ -78,16 +77,15 @@ Messages8080.CATEGORIES = {
|
|||
"serial": Messages8080.SERIAL,
|
||||
"speaker": Messages8080.SPEAKER,
|
||||
"computer": Messages8080.COMPUTER,
|
||||
"log": Messages8080.LOG,
|
||||
"warn": Messages8080.WARN,
|
||||
/*
|
||||
* Now we turn to message actions rather than message types; for example, setting "halt"
|
||||
* on or off doesn't enable "halt" messages, but rather halts the CPU on any message above.
|
||||
*
|
||||
* Similarly, "m buffer on" turns on message buffering, deferring the display of all messages
|
||||
* until "m buffer off" is issued.
|
||||
* Similarly, "m log on" turns on message logging, deferring the display of all messages
|
||||
* until "m log off" is issued.
|
||||
*/
|
||||
"buffer": Messages8080.BUFFER,
|
||||
"log": Messages8080.LOG,
|
||||
"warn": Messages8080.WARN,
|
||||
"halt": Messages8080.HALT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ class CPU extends Component {
|
|||
*/
|
||||
calcCycles()
|
||||
{
|
||||
var nMultiplier = (this.counts.mhzCurrent / this.counts.mhzBase)|0;
|
||||
var nMultiplier = this.counts.mhzCurrent / this.counts.mhzBase;
|
||||
if (!nMultiplier || nMultiplier > this.counts.nTargetMultiplier) nMultiplier = this.counts.nTargetMultiplier;
|
||||
this.counts.msPerYield = Math.round(1000 / CPU.YIELDS_PER_SECOND);
|
||||
this.counts.nCyclesPerYield = Math.floor(this.counts.nBaseCyclesPerSecond / CPU.YIELDS_PER_SECOND * nMultiplier);
|
||||
|
|
@ -713,9 +713,9 @@ class CPU extends Component {
|
|||
var fSuccess = true;
|
||||
if (nMultiplier !== undefined) {
|
||||
/*
|
||||
* If we haven't reached 80% (0.8) of the current target speed, revert to the default multiplier.
|
||||
* If we haven't reached 90% (0.9) of the current target speed, revert to the default multiplier.
|
||||
*/
|
||||
if (this.counts.mhzCurrent > 0 && this.counts.mhzCurrent / this.counts.mhzTarget < 0.8) {
|
||||
if (this.counts.mhzCurrent > 0 && this.counts.mhzCurrent < this.counts.mhzTarget * 0.9) {
|
||||
nMultiplier = this.counts.nBaseMultiplier;
|
||||
fSuccess = false;
|
||||
}
|
||||
|
|
@ -855,7 +855,7 @@ class CPU extends Component {
|
|||
|
||||
this.calcSpeed(nCycles, msElapsed);
|
||||
|
||||
if (msRemainsThisRun < 0 || this.counts.mhzCurrent < this.counts.mhzTarget) {
|
||||
if (msRemainsThisRun < 0) {
|
||||
/*
|
||||
* Try "throwing out" the effects of large anomalies, by moving the overall run start time up;
|
||||
* ordinarily, this should only happen when the someone is using an external Debugger or some other
|
||||
|
|
@ -866,14 +866,17 @@ class CPU extends Component {
|
|||
}
|
||||
/*
|
||||
* If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate
|
||||
* nCyclesActual), all we can do is yield for as little time as possible (ie, 0ms) and hope that the
|
||||
* simulation is at least usable.
|
||||
* nBaseCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope
|
||||
* that the simulation is at least usable.
|
||||
*/
|
||||
msRemainsThisRun = 0;
|
||||
}
|
||||
else if (this.counts.mhzCurrent < this.counts.mhzTarget) {
|
||||
msRemainsThisRun = 0;
|
||||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages.LOG) && msRemainsThisRun) {
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.counts.msEndThisRun + "ms");
|
||||
if (DEBUG && this.messageEnabled(Messages.CPU)) {
|
||||
this.printMessage("calcRemainingTime: sleep " + msRemainsThisRun + "ms after " + (this.counts.msEndThisRun - this.counts.msStartThisRun) + "ms burst");
|
||||
}
|
||||
|
||||
this.counts.msEndThisRun += msRemainsThisRun;
|
||||
|
|
@ -1102,9 +1105,17 @@ class CPU extends Component {
|
|||
if (timer[1] < 0) continue;
|
||||
timer[1] -= nCycles;
|
||||
if (timer[1] <= 0) {
|
||||
if (DEBUG && this.messageEnabled(Messages.CPU)) {
|
||||
this.printMessage("updateTimer(" + nCycles + "): firing " + timer[0] + " with only " + (timer[1] + nCycles) + " cycles left");
|
||||
}
|
||||
timer[1] = -1; // zero is technically an "active" value, so ensure the timer is dormant now
|
||||
timer[3](); // safe to invoke the callback function now
|
||||
if (timer[2] >= 0) this.setTimer(iTimer, timer[2]);
|
||||
if (timer[2] >= 0) {
|
||||
this.setTimer(iTimer, timer[2]);
|
||||
if (DEBUG && this.messageEnabled(Messages.CPU)) {
|
||||
this.printMessage("updateTimer(" + nCycles + "): rearming " + timer[0] + " for " + timer[2] + "ms (" + timer[1] + " cycles)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,8 +224,8 @@ class DebuggerX86 extends Debugger {
|
|||
this.sInitCommands = parmsDbg['commands'];
|
||||
|
||||
/*
|
||||
* Make it easier to access Debugger commands from an external REPL (eg, the WebStorm
|
||||
* "live" console window); eg:
|
||||
* Make it easier to access Debugger commands from an external REPL, like the WebStorm "live" console
|
||||
* window; eg:
|
||||
*
|
||||
* pcx86('r')
|
||||
* pcx86('dw 0:0')
|
||||
|
|
@ -2154,6 +2154,7 @@ class DebuggerX86 extends Debugger {
|
|||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = Messages.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageLog = [];
|
||||
/*
|
||||
* Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects,
|
||||
* but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard".
|
||||
|
|
@ -2502,6 +2503,11 @@ class DebuggerX86 extends Debugger {
|
|||
sMessage += " at " + this.toHexAddr(this.newAddr(this.cpu.getIP(), this.cpu.getCS())) + " (%" + Str.toHex(this.cpu.regLIP) + ")";
|
||||
}
|
||||
|
||||
if (this.bitsMessage & Messages.LOG) {
|
||||
this.aMessageLog.push(sMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
|
|
@ -5442,6 +5448,12 @@ class DebuggerX86 extends Debugger {
|
|||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
if (bitsMessage == Messages.LOG) {
|
||||
for (var i = 0; i < this.aMessageLog.length; i++) {
|
||||
this.println(this.aMessageLog[i]);
|
||||
}
|
||||
this.aMessageLog = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,12 +107,15 @@ Messages.CATEGORIES = {
|
|||
"computer": Messages.COMPUTER,
|
||||
"dos": Messages.DOS,
|
||||
"data": Messages.DATA,
|
||||
"log": Messages.LOG,
|
||||
"warn": Messages.WARN,
|
||||
/*
|
||||
* Now we turn to message actions rather than message types; for example, setting "halt"
|
||||
* on or off doesn't enable "halt" messages, but rather halts the CPU on any message above.
|
||||
*
|
||||
* Similarly, "m log on" turns on message logging, deferring the display of all messages
|
||||
* until "m log off" is issued.
|
||||
*/
|
||||
"log": Messages.LOG,
|
||||
"warn": Messages.WARN,
|
||||
"halt": Messages.HALT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class DebuggerPDP11 extends Debugger {
|
|||
this.afnDumpers = {};
|
||||
this.bitsMessage = this.bitsWarning = 0;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
this.messageInit(parmsDbg['messages']);
|
||||
this.sInitCommands = parmsDbg['commands'];
|
||||
|
||||
|
|
@ -847,7 +847,7 @@ class DebuggerPDP11 extends Debugger {
|
|||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = MessagesPDP11.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
/*
|
||||
* Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects,
|
||||
* but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard".
|
||||
|
|
@ -1014,8 +1014,8 @@ class DebuggerPDP11 extends Debugger {
|
|||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
if (this.bitsMessage & MessagesPDP11.BUFFER) {
|
||||
this.aMessageBuffer.push(sMessage);
|
||||
if (this.bitsMessage & MessagesPDP11.LOG) {
|
||||
this.aMessageLog.push(sMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3203,12 +3203,12 @@ class DebuggerPDP11 extends Debugger {
|
|||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
if (bitsMessage == MessagesPDP11.BUFFER) {
|
||||
var i = this.aMessageBuffer.length >= 1000? this.aMessageBuffer.length - 1000 : 0;
|
||||
while (i < this.aMessageBuffer.length) {
|
||||
this.println(this.aMessageBuffer[i++]);
|
||||
if (bitsMessage == MessagesPDP11.LOG) {
|
||||
var i = this.aMessageLog.length >= 1000? this.aMessageLog.length - 1000 : 0;
|
||||
while (i < this.aMessageLog.length) {
|
||||
this.println(this.aMessageLog[i++]);
|
||||
}
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,9 +55,8 @@ var MessagesPDP11 = {
|
|||
TIMER: 0x00200000,
|
||||
SPEAKER: 0x01000000,
|
||||
COMPUTER: 0x02000000,
|
||||
LOG: 0x10000000,
|
||||
WARN: 0x20000000,
|
||||
BUFFER: 0x40000000,
|
||||
LOG: 0x20000000,
|
||||
WARN: 0x40000000,
|
||||
HALT: 0x80000000|0
|
||||
};
|
||||
|
||||
|
|
@ -102,16 +101,15 @@ MessagesPDP11.CATEGORIES = {
|
|||
"timer": MessagesPDP11.TIMER,
|
||||
"speaker": MessagesPDP11.SPEAKER,
|
||||
"computer": MessagesPDP11.COMPUTER,
|
||||
"log": MessagesPDP11.LOG,
|
||||
"warn": MessagesPDP11.WARN,
|
||||
/*
|
||||
* Now we turn to message actions rather than message types; for example, setting "halt"
|
||||
* on or off doesn't enable "halt" messages, but rather halts the CPU on any message above.
|
||||
*
|
||||
* Similarly, "m buffer on" turns on message buffering, deferring the display of all messages
|
||||
* until "m buffer off" is issued.
|
||||
* Similarly, "m log on" turns on message logging, deferring the display of all messages
|
||||
* until "m log off" is issued.
|
||||
*/
|
||||
"buffer": MessagesPDP11.BUFFER,
|
||||
"log": MessagesPDP11.LOG,
|
||||
"warn": MessagesPDP11.WARN,
|
||||
"halt": MessagesPDP11.HALT
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -4139,9 +4139,8 @@ var Messages8080 = {
|
|||
SERIAL: 0x00800000,
|
||||
SPEAKER: 0x02000000,
|
||||
COMPUTER: 0x04000000,
|
||||
LOG: 0x10000000,
|
||||
WARN: 0x20000000,
|
||||
BUFFER: 0x40000000,
|
||||
LOG: 0x20000000,
|
||||
WARN: 0x40000000,
|
||||
HALT: 0x80000000|0
|
||||
};
|
||||
|
||||
|
|
@ -4174,16 +4173,15 @@ Messages8080.CATEGORIES = {
|
|||
"serial": Messages8080.SERIAL,
|
||||
"speaker": Messages8080.SPEAKER,
|
||||
"computer": Messages8080.COMPUTER,
|
||||
"log": Messages8080.LOG,
|
||||
"warn": Messages8080.WARN,
|
||||
/*
|
||||
* Now we turn to message actions rather than message types; for example, setting "halt"
|
||||
* on or off doesn't enable "halt" messages, but rather halts the CPU on any message above.
|
||||
*
|
||||
* Similarly, "m buffer on" turns on message buffering, deferring the display of all messages
|
||||
* until "m buffer off" is issued.
|
||||
* Similarly, "m log on" turns on message logging, deferring the display of all messages
|
||||
* until "m log off" is issued.
|
||||
*/
|
||||
"buffer": Messages8080.BUFFER,
|
||||
"log": Messages8080.LOG,
|
||||
"warn": Messages8080.WARN,
|
||||
"halt": Messages8080.HALT
|
||||
};
|
||||
|
||||
|
|
@ -7124,8 +7122,8 @@ class CPU8080 extends Component {
|
|||
*/
|
||||
this.nCyclesRecalc += this.nCyclesThisRun;
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages8080.LOG) && msRemainsThisRun) {
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.msEndThisRun + "ms");
|
||||
if (DEBUG && this.messageEnabled(Messages8080.CPU) && msRemainsThisRun) {
|
||||
this.printMessage("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.msEndThisRun + "ms");
|
||||
}
|
||||
|
||||
this.msEndThisRun += msRemainsThisRun;
|
||||
|
|
@ -18682,8 +18680,8 @@ class Debugger8080 extends Debugger {
|
|||
this.sInitCommands = parmsDbg['commands'];
|
||||
|
||||
/*
|
||||
* Make it easier to access Debugger8080 commands from an external REPL (eg, the WebStorm
|
||||
* "live" console window); eg:
|
||||
* Make it easier to access Debugger commands from an external REPL, like the WebStorm "live" console
|
||||
* window; eg:
|
||||
*
|
||||
* pc8080('r')
|
||||
* pc8080('dw 0:0')
|
||||
|
|
@ -19296,7 +19294,7 @@ class Debugger8080 extends Debugger {
|
|||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = Messages8080.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
/*
|
||||
* Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects,
|
||||
* but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard".
|
||||
|
|
@ -19543,8 +19541,8 @@ class Debugger8080 extends Debugger {
|
|||
sMessage += " at " + this.toHexAddr(this.newAddr(this.cpu.getPC()));
|
||||
}
|
||||
|
||||
if (this.bitsMessage & Messages8080.BUFFER) {
|
||||
this.aMessageBuffer.push(sMessage);
|
||||
if (this.bitsMessage & Messages8080.LOG) {
|
||||
this.aMessageLog.push(sMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -21562,11 +21560,11 @@ class Debugger8080 extends Debugger {
|
|||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
if (bitsMessage == Messages8080.BUFFER) {
|
||||
for (var i = 0; i < this.aMessageBuffer.length; i++) {
|
||||
this.println(this.aMessageBuffer[i]);
|
||||
if (bitsMessage == Messages8080.LOG) {
|
||||
for (var i = 0; i < this.aMessageLog.length; i++) {
|
||||
this.println(this.aMessageLog[i]);
|
||||
}
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -7345,12 +7345,15 @@ Messages.CATEGORIES = {
|
|||
"computer": Messages.COMPUTER,
|
||||
"dos": Messages.DOS,
|
||||
"data": Messages.DATA,
|
||||
"log": Messages.LOG,
|
||||
"warn": Messages.WARN,
|
||||
/*
|
||||
* Now we turn to message actions rather than message types; for example, setting "halt"
|
||||
* on or off doesn't enable "halt" messages, but rather halts the CPU on any message above.
|
||||
*
|
||||
* Similarly, "m log on" turns on message logging, deferring the display of all messages
|
||||
* until "m log off" is issued.
|
||||
*/
|
||||
"log": Messages.LOG,
|
||||
"warn": Messages.WARN,
|
||||
"halt": Messages.HALT
|
||||
};
|
||||
|
||||
|
|
@ -12314,7 +12317,7 @@ class CPU extends Component {
|
|||
*/
|
||||
calcCycles()
|
||||
{
|
||||
var nMultiplier = (this.counts.mhzCurrent / this.counts.mhzBase)|0;
|
||||
var nMultiplier = this.counts.mhzCurrent / this.counts.mhzBase;
|
||||
if (!nMultiplier || nMultiplier > this.counts.nTargetMultiplier) nMultiplier = this.counts.nTargetMultiplier;
|
||||
this.counts.msPerYield = Math.round(1000 / CPU.YIELDS_PER_SECOND);
|
||||
this.counts.nCyclesPerYield = Math.floor(this.counts.nBaseCyclesPerSecond / CPU.YIELDS_PER_SECOND * nMultiplier);
|
||||
|
|
@ -12457,9 +12460,9 @@ class CPU extends Component {
|
|||
var fSuccess = true;
|
||||
if (nMultiplier !== undefined) {
|
||||
/*
|
||||
* If we haven't reached 80% (0.8) of the current target speed, revert to the default multiplier.
|
||||
* If we haven't reached 90% (0.9) of the current target speed, revert to the default multiplier.
|
||||
*/
|
||||
if (this.counts.mhzCurrent > 0 && this.counts.mhzCurrent / this.counts.mhzTarget < 0.8) {
|
||||
if (this.counts.mhzCurrent > 0 && this.counts.mhzCurrent < this.counts.mhzTarget * 0.9) {
|
||||
nMultiplier = this.counts.nBaseMultiplier;
|
||||
fSuccess = false;
|
||||
}
|
||||
|
|
@ -12599,7 +12602,7 @@ class CPU extends Component {
|
|||
|
||||
this.calcSpeed(nCycles, msElapsed);
|
||||
|
||||
if (msRemainsThisRun < 0 || this.counts.mhzCurrent < this.counts.mhzTarget) {
|
||||
if (msRemainsThisRun < 0) {
|
||||
/*
|
||||
* Try "throwing out" the effects of large anomalies, by moving the overall run start time up;
|
||||
* ordinarily, this should only happen when the someone is using an external Debugger or some other
|
||||
|
|
@ -12610,14 +12613,17 @@ class CPU extends Component {
|
|||
}
|
||||
/*
|
||||
* If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate
|
||||
* nCyclesActual), all we can do is yield for as little time as possible (ie, 0ms) and hope that the
|
||||
* simulation is at least usable.
|
||||
* nBaseCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope
|
||||
* that the simulation is at least usable.
|
||||
*/
|
||||
msRemainsThisRun = 0;
|
||||
}
|
||||
else if (this.counts.mhzCurrent < this.counts.mhzTarget) {
|
||||
msRemainsThisRun = 0;
|
||||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages.LOG) && msRemainsThisRun) {
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.counts.msEndThisRun + "ms");
|
||||
if (DEBUG && this.messageEnabled(Messages.CPU)) {
|
||||
this.printMessage("calcRemainingTime: sleep " + msRemainsThisRun + "ms after " + (this.counts.msEndThisRun - this.counts.msStartThisRun) + "ms burst");
|
||||
}
|
||||
|
||||
this.counts.msEndThisRun += msRemainsThisRun;
|
||||
|
|
@ -12846,9 +12852,17 @@ class CPU extends Component {
|
|||
if (timer[1] < 0) continue;
|
||||
timer[1] -= nCycles;
|
||||
if (timer[1] <= 0) {
|
||||
if (DEBUG && this.messageEnabled(Messages.CPU)) {
|
||||
this.printMessage("updateTimer(" + nCycles + "): firing " + timer[0] + " with only " + (timer[1] + nCycles) + " cycles left");
|
||||
}
|
||||
timer[1] = -1; // zero is technically an "active" value, so ensure the timer is dormant now
|
||||
timer[3](); // safe to invoke the callback function now
|
||||
if (timer[2] >= 0) this.setTimer(iTimer, timer[2]);
|
||||
if (timer[2] >= 0) {
|
||||
this.setTimer(iTimer, timer[2]);
|
||||
if (DEBUG && this.messageEnabled(Messages.CPU)) {
|
||||
this.printMessage("updateTimer(" + nCycles + "): rearming " + timer[0] + " for " + timer[2] + "ms (" + timer[1] + " cycles)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55283,7 +55297,7 @@ class SerialPort extends Component {
|
|||
if (this.connection) {
|
||||
var exports = this.connection['exports'];
|
||||
if (exports) {
|
||||
var fnConnect = exports['connect'];
|
||||
var fnConnect = /** @function */ (exports['connect']);
|
||||
if (fnConnect) fnConnect.call(this.connection, this.fNullModem);
|
||||
this.sendData = exports['receiveData'];
|
||||
if (this.sendData) {
|
||||
|
|
@ -67050,8 +67064,8 @@ class DebuggerX86 extends Debugger {
|
|||
this.sInitCommands = parmsDbg['commands'];
|
||||
|
||||
/*
|
||||
* Make it easier to access Debugger commands from an external REPL (eg, the WebStorm
|
||||
* "live" console window); eg:
|
||||
* Make it easier to access Debugger commands from an external REPL, like the WebStorm "live" console
|
||||
* window; eg:
|
||||
*
|
||||
* pcx86('r')
|
||||
* pcx86('dw 0:0')
|
||||
|
|
@ -68980,6 +68994,7 @@ class DebuggerX86 extends Debugger {
|
|||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = Messages.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageLog = [];
|
||||
/*
|
||||
* Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects,
|
||||
* but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard".
|
||||
|
|
@ -69328,6 +69343,11 @@ class DebuggerX86 extends Debugger {
|
|||
sMessage += " at " + this.toHexAddr(this.newAddr(this.cpu.getIP(), this.cpu.getCS())) + " (%" + Str.toHex(this.cpu.regLIP) + ")";
|
||||
}
|
||||
|
||||
if (this.bitsMessage & Messages.LOG) {
|
||||
this.aMessageLog.push(sMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
|
|
@ -72268,6 +72288,12 @@ class DebuggerX86 extends Debugger {
|
|||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
if (bitsMessage == Messages.LOG) {
|
||||
for (var i = 0; i < this.aMessageLog.length; i++) {
|
||||
this.println(this.aMessageLog[i]);
|
||||
}
|
||||
this.aMessageLog = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -5176,9 +5176,8 @@ var MessagesPDP11 = {
|
|||
TIMER: 0x00200000,
|
||||
SPEAKER: 0x01000000,
|
||||
COMPUTER: 0x02000000,
|
||||
LOG: 0x10000000,
|
||||
WARN: 0x20000000,
|
||||
BUFFER: 0x40000000,
|
||||
LOG: 0x20000000,
|
||||
WARN: 0x40000000,
|
||||
HALT: 0x80000000|0
|
||||
};
|
||||
|
||||
|
|
@ -5223,16 +5222,15 @@ MessagesPDP11.CATEGORIES = {
|
|||
"timer": MessagesPDP11.TIMER,
|
||||
"speaker": MessagesPDP11.SPEAKER,
|
||||
"computer": MessagesPDP11.COMPUTER,
|
||||
"log": MessagesPDP11.LOG,
|
||||
"warn": MessagesPDP11.WARN,
|
||||
/*
|
||||
* Now we turn to message actions rather than message types; for example, setting "halt"
|
||||
* on or off doesn't enable "halt" messages, but rather halts the CPU on any message above.
|
||||
*
|
||||
* Similarly, "m buffer on" turns on message buffering, deferring the display of all messages
|
||||
* until "m buffer off" is issued.
|
||||
* Similarly, "m log on" turns on message logging, deferring the display of all messages
|
||||
* until "m log off" is issued.
|
||||
*/
|
||||
"buffer": MessagesPDP11.BUFFER,
|
||||
"log": MessagesPDP11.LOG,
|
||||
"warn": MessagesPDP11.WARN,
|
||||
"halt": MessagesPDP11.HALT
|
||||
};
|
||||
|
||||
|
|
@ -25304,7 +25302,7 @@ class DebuggerPDP11 extends Debugger {
|
|||
this.afnDumpers = {};
|
||||
this.bitsMessage = this.bitsWarning = 0;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
this.messageInit(parmsDbg['messages']);
|
||||
this.sInitCommands = parmsDbg['commands'];
|
||||
|
||||
|
|
@ -25994,7 +25992,7 @@ class DebuggerPDP11 extends Debugger {
|
|||
this.dbg = this;
|
||||
this.bitsMessage = this.bitsWarning = MessagesPDP11.WARN;
|
||||
this.sMessagePrev = null;
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
/*
|
||||
* Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects,
|
||||
* but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard".
|
||||
|
|
@ -26161,8 +26159,8 @@ class DebuggerPDP11 extends Debugger {
|
|||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
this.sMessagePrev = sMessage;
|
||||
|
||||
if (this.bitsMessage & MessagesPDP11.BUFFER) {
|
||||
this.aMessageBuffer.push(sMessage);
|
||||
if (this.bitsMessage & MessagesPDP11.LOG) {
|
||||
this.aMessageLog.push(sMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -28350,12 +28348,12 @@ class DebuggerPDP11 extends Debugger {
|
|||
else if (asArgs[2] == "off") {
|
||||
this.bitsMessage &= ~bitsMessage;
|
||||
fCriteria = false;
|
||||
if (bitsMessage == MessagesPDP11.BUFFER) {
|
||||
var i = this.aMessageBuffer.length >= 1000? this.aMessageBuffer.length - 1000 : 0;
|
||||
while (i < this.aMessageBuffer.length) {
|
||||
this.println(this.aMessageBuffer[i++]);
|
||||
if (bitsMessage == MessagesPDP11.LOG) {
|
||||
var i = this.aMessageLog.length >= 1000? this.aMessageLog.length - 1000 : 0;
|
||||
while (i < this.aMessageLog.length) {
|
||||
this.println(this.aMessageLog[i++]);
|
||||
}
|
||||
this.aMessageBuffer = [];
|
||||
this.aMessageLog = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue