Smoothed out PCx86 dynamic CPU speed recalculation by no longer truncating the current cycle multiplier

This commit is contained in:
Jeff Parsons 2017-08-08 19:25:08 -07:00 committed by Jeff Parsons
commit 7f973a03b9
23 changed files with 1351 additions and 1308 deletions

View file

@ -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)");
}
}
}
}
}

View file

@ -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 = [];
}
}
}
}

View file

@ -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
};