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

File diff suppressed because it is too large Load diff

View file

@ -117,14 +117,14 @@ l.kc=function(a,b,c,d){this.pa=a;this.na=b;this.Da=d;for(b=0;b<Ec.length;b++)(d=
l.Rb=function(a,b){if(!b){if(a&&this.restore){Ic(this);if(!this.restore(a))return!1;Jc(this)}else this.reset();this.tb("No debugger detected")}Lc(this);return!0};l.Qb=function(a,b){var c=this.X.cb;b&&Mc(this);return a?this.save(c):!0};l.Fd=function(){return this.X.cb?!0:this.X.Fd||void 0===this.ia.run?Nc(this):!1};l.li=function(){return 0};
function Jc(a){void 0===a.V.If&&(a.V.If=0);void 0===a.V.Ke&&(a.V.Ke=-1);void 0===a.V.Le&&(a.V.Le=-1);a.X.zf=0<=a.V.If&&0<a.V.Ke;a.X.zf&&(a.V.Hf=0,a.V.se=a.V.If-a.Ic)}
l.Ab=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.ia[b]=c;a=!0;break;case "run":this.ia[b]=c;c.onclick=function(){var a=d.X.cb,b;if(b=d.pa)if(b=d.pa,b.X.Xd&&(b.X.Xd=!1,b.X.Ie&&!b.X.Sb&&b.ue(Oc)),b.X.Sb)b=!0;else{var c=null,h,k=db(b.id);for(h=0;h<k.length&&(c=k[h],c===b||c.X.ready);h++);if(h==k.length)for(h=0;h<k.length&&(c=k[h],c===b||c.X.Sb);h++);h==k.length&&(c=b);q("The "+c.type+" component ("+c.id+") is not "+(c.X.ready?"powered yet":"ready yet"+(c.Df?" (waiting for notification)":
""))+".");b=!1}b&&a==d.X.cb&&(d.X.cb?Mc(d,!0):Nc(d,!0))};a=!0;break;case "speed":this.ia[b]=c;a=!0;break;case "setSpeed":this.ia[b]=c,c.onclick=function(){Pc(d,d.V.md<<1,!0)},c.textContent=this.V.re.toFixed(2)+"Mhz",a=!0}return a};function Qc(a,b){a.X.cb&&(b=a.A-b,a.A-=b,a.Sc-=b)}function Rc(a){var b=a.V.hd/a.V.Gf|0;if(!b||b>a.V.md)b=a.V.md;a.V.yi=Math.round(1E3/Hc);a.V.Ml=Math.floor(a.V.xd/Hc*b);a.V.rg=b}
""))+".");b=!1}b&&a==d.X.cb&&(d.X.cb?Mc(d,!0):Nc(d,!0))};a=!0;break;case "speed":this.ia[b]=c;a=!0;break;case "setSpeed":this.ia[b]=c,c.onclick=function(){Pc(d,d.V.md<<1,!0)},c.textContent=this.V.re.toFixed(2)+"Mhz",a=!0}return a};function Qc(a,b){a.X.cb&&(b=a.A-b,a.A-=b,a.Sc-=b)}function Rc(a){var b=a.V.hd/a.V.Gf;if(!b||b>a.V.md)b=a.V.md;a.V.yi=Math.round(1E3/Hc);a.V.Ml=Math.floor(a.V.xd/Hc*b);a.V.rg=b}
function Sc(a,b){var c=a.Ic+a.Tc+a.Sc-a.A;b&&1<a.V.md&&a.V.hd>a.V.Gf&&(c=Math.round(c/a.V.md));return c}function Ic(a){a.Ic=a.Tc=a.Sc=a.A=0;Jc(a);Pc(a,a.V.zi)}
function Pc(a,b,c){if(void 0!==b){0<a.V.hd&&.8>a.V.hd/a.V.re&&(b=a.V.zi);a.V.hd=0;a.V.md=b;b=a.V.Gf*a.V.md;if(a.V.re!=b){a.V.re=b;b=a.V.re.toFixed(2)+"Mhz";var d=a.ia.setSpeed;d&&(d.textContent=b);a.tb("target speed: "+b)}c&&a.pa&&Tc(a.pa)}a.Ic+=a.Tc;a.Tc=0;a.V.Zc=a.V.Nd=0;Rc(a);for(c=a.qa.length-1;0<=c;c--)b=a.qa[c],0<=b[2]&&Uc(a,c,b[2],!0)}function Gc(a,b,c,d){d=void 0===d?-1:d;var e=a.qa.length;a.qa.push([b,-1,d,c]);0<=d&&Uc(a,e,d)}
function Pc(a,b,c){if(void 0!==b){0<a.V.hd&&a.V.hd<.9*a.V.re&&(b=a.V.zi);a.V.hd=0;a.V.md=b;b=a.V.Gf*a.V.md;if(a.V.re!=b){a.V.re=b;b=a.V.re.toFixed(2)+"Mhz";var d=a.ia.setSpeed;d&&(d.textContent=b);a.tb("target speed: "+b)}c&&a.pa&&Tc(a.pa)}a.Ic+=a.Tc;a.Tc=0;a.V.Zc=a.V.Nd=0;Rc(a);for(c=a.qa.length-1;0<=c;c--)b=a.qa[c],0<=b[2]&&Uc(a,c,b[2],!0)}function Gc(a,b,c,d){d=void 0===d?-1:d;var e=a.qa.length;a.qa.push([b,-1,d,c]);0<=d&&Uc(a,e,d)}
function Uc(a,b,c,d){0<=b&&b<a.qa.length&&(b=a.qa[b],d||0>b[1])&&(c=a.V.xd*a.V.rg/1E3*c|0,a.X.cb&&(c+=Vc(a)),b[1]=c)}function Wc(a){for(var b=[],c=0;c<a.qa.length;c++){var d=a.qa[c];b.push([d[0],d[1],d[2]])}return b}function Vc(a,b){var c=a.Sc-=a.A;a.A=0;b&&(a.Sc=0);return c}
l.kn=function(){if(this.X.cb){Rc(this);this.V.Jf=0;this.V.Je=ua();this.V.Zc||(this.V.Zc=this.V.Je);if(this.V.Nd){var a=this.V.Je-this.V.Nd;a>this.V.yi&&(this.V.Zc+=a,this.V.Zc>this.V.Je&&(this.V.Zc=this.V.Je))}try{this.X.Zf=!1;do{for(var b,c=this.X.zf?1:this.V.xd*this.V.rg|0,d=this.qa.length-1;0<=d;d--){var e=this.qa[d];0>e[1]||c>e[1]&&(c=e[1])}b=c;if(this.U){Xc(this.U);var f=this.U,a=b,g=f.qa[0];if(g.Kd){var h=(Sc(f.R,f.N)-g.jd)/f.Aa|0,k=Yc(f,0)-h;g.mode==Zc&&(k-=h);var m=k*f.Aa|0;g.mode==Zc&&(m>>=
1);a>m&&(a=m)}b=a;var r=this.U,a=b;if(r.A&&r.A[$c]&ad){var y=r.W-Sc(r.R,r.N);0<y&&a>y&&(a=y)}b=a}try{this.th(b)}catch(N){if("number"!=typeof N)throw N;}b=Vc(this,!0);this.V.Jf+=b;this.Tc+=b;a=b;if(this.X.zf){var t=!1;this.V.Hf=this.V.Hf+this.li()|0;this.V.se-=a;0>=this.V.se&&(this.V.se+=this.V.Ke,t=!0);0<=this.V.Le&&this.V.Le<=Sc(this)&&(this.V.Ke=this.V.Le=-1,Jc(this),Mc(this),t=!0);t&&this.tb(Sc(this)+" cycles: checksum="+ia(this.V.Hf))}for(var a=b,z=this.qa.length-1;0<=z;z--){var B=this.qa[z];
0>B[1]||(B[1]-=a,0>=B[1]&&(B[1]=-1,B[3](),0<=B[2]&&Uc(this,z,B[2])))}}while(this.X.cb&&!this.X.Zf)}catch(N){Mc(this);Lc(this);this.pa&&this.pa.stop(ua(),Sc(this));mb(this,N.stack||N.message);return}if(this.X.cb){b=setTimeout;c=this.pi;this.V.Nd=ua();d=this.V.yi;this.V.Jf&&(d=Math.round(d*this.V.Jf/this.V.Ml));d-=this.V.Nd-this.V.Je;if(e=this.V.Nd-this.V.Zc)this.V.hd=Math.round(this.Tc/(10*e))/100,864E5<=e&&(this.Ic=0,this.U&&Xc(this.U,!0),Pc(this));if(0>d||this.V.hd<this.V.re)-1E3>d&&(this.V.Zc-=
d),d=0;this.V.Nd+=d;b(c,d)}}};function Nc(a,b){var c;a.X.error?(a.tb(a.toString()+" error"),c=!0):c=!1;if(c)return!1;if(a.X.cb)return a.tb(a.toString()+" busy"),!1;Pc(a);a.X.cb=!0;a.X.Pj=!0;a.U&&a.U.start();if(c=a.ia.run)c.textContent="Halt";a.pa&&(bd(a.pa,!0),b&&Tc(a.pa,!0),a.pa.start(a.V.Zc,Sc(a)));setTimeout(a.pi,0);return!0}l.th=function(){return 0};
0>B[1]||(B[1]-=a,0>=B[1]&&(B[1]=-1,B[3](),0<=B[2]&&Uc(this,z,B[2])))}}while(this.X.cb&&!this.X.Zf)}catch(N){Mc(this);Lc(this);this.pa&&this.pa.stop(ua(),Sc(this));mb(this,N.stack||N.message);return}if(this.X.cb){b=setTimeout;c=this.pi;this.V.Nd=ua();d=this.V.yi;this.V.Jf&&(d=Math.round(d*this.V.Jf/this.V.Ml));d-=this.V.Nd-this.V.Je;if(e=this.V.Nd-this.V.Zc)this.V.hd=Math.round(this.Tc/(10*e))/100,864E5<=e&&(this.Ic=0,this.U&&Xc(this.U,!0),Pc(this));0>d?(-1E3>d&&(this.V.Zc-=d),d=0):this.V.hd<this.V.re&&
(d=0);this.V.Nd+=d;b(c,d)}}};function Nc(a,b){var c;a.X.error?(a.tb(a.toString()+" error"),c=!0):c=!1;if(c)return!1;if(a.X.cb)return a.tb(a.toString()+" busy"),!1;Pc(a);a.X.cb=!0;a.X.Pj=!0;a.U&&a.U.start();if(c=a.ia.run)c.textContent="Halt";a.pa&&(bd(a.pa,!0),b&&Tc(a.pa,!0),a.pa.start(a.V.Zc,Sc(a)));setTimeout(a.pi,0);return!0}l.th=function(){return 0};
function Mc(a,b){if(a.X.cb){Vc(a);a.Ic+=a.Tc;a.Tc=0;a.X.cb=!1;a.U&&a.U.stop();var c=a.ia.run;c&&(c.textContent="Run");a.pa&&(a.pa.stop(Date.now()||+new Date,Sc(a)),bd(a.pa,!0));a.Da||a.status("Stopped")}a.X.complete=b}function Lc(a){a.pa&&bd(a.pa,void 0)}var Hc=30,Ec=["power","reset"];
function cd(a,b,c,d){this.A=a;this.Da=a.Da;this.id=b;this.Xf=c||"";this.ha=0;this.jb=65535;this.C=this.jb+1;this.rb=this.jc=this.ext=this.nb=this.type=this.va=0;this.cc=-1;this.T=this.Jc=2;this.O=this.sa=65535;this.J=this.wi;this.I=this.H=this.xf;this.B={ha:-1,va:0,jb:0,nb:0,type:0,ext:0,cc:-1};1==this.id&&(this.Xe=0,this.D=null,this.ne=!1,this.G=Array(32),this.F=[]);dd(this,!0,d);this.id||(this.Jb=this.qb=this.ai)}l=cd.prototype;l.wi=function(a){this.ha=a&65535;return this.va=this.ha<<4};
l.Ff=function(a,b){var c,d,e=this.A;a&=65535;a&4?(c=e.mc.va,d=c+e.mc.jb|0):(c=e.Ob,d=e.Oc);if(c){c=c+(a&65528)|0;if(d-c|0)return e.A-=15,ed(this,c,a,b);this.id<fd&&w.call(e,b&&this.id==gd?10:13,a&65532)}return-1};l.Gl=function(a){var b=this.A;a=b.Xb+(a<<2);var c=b.ga(a);b.N&=-769;return this.load(b.ga(a+2))+c|0};l.Fl=function(a){var b=this.A;a<<=3;var c=b.Xb+a|0;if(7<=(b.Qc-c|0))return this.D=!0,a=ed(this,c,a),-1!==a&&(a+=this.Xe),a;w.call(b,13,a|2);return-1};l.ai=function(a){return this.va+a|0};

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

@ -67,7 +67,7 @@ var mb=window?window.PCjs.Machines:{},kb=window?window.PCjs.Components:[],zb=win
Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){b=b||0;for(var c=this.length;b<c;b++)if(this[b]===a)return b;return-1});Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});
Function.prototype.bind||(Function.prototype.bind=function(a){function b(){return e.apply(this instanceof c&&a?this:a,d.concat(Array.prototype.slice.call(arguments)))}function c(){}if("function"!=typeof this)throw new TypeError("Function.prototype.bind: non-callable object");var d=Array.prototype.slice.call(arguments,1),e=this;c.prototype=this.prototype;b.prototype=new c;return b});
var Mb="undefined"!==typeof ArrayBuffer,Nb=[1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,
0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1],Ob={cpu:1,bus:64,mem:128,port:256,nvr:16384,chipset:32768,keyboard:65536,key:131072,video:262144,fdc:524288,disk:2097152,serial:8388608,speaker:33554432,computer:67108864,log:268435456,warn:536870912,buffer:1073741824,halt:-2147483648};function Pb(a){u.call(this,"Panel",a)}aa(Pb,u);
0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1],Ob={cpu:1,bus:64,mem:128,port:256,nvr:16384,chipset:32768,keyboard:65536,key:131072,video:262144,fdc:524288,disk:2097152,serial:8388608,speaker:33554432,computer:67108864,log:536870912,warn:1073741824,halt:-2147483648};function Pb(a){u.call(this,"Panel",a)}aa(Pb,u);
Pb.prototype.da=function(a,b,c,d){return this.R&&this.R.da(a,b,c,d)||this.w&&this.w.da(a,b,c,d)||this.B&&this.B.da(a,b,c,d)||this.K&&this.K.da(a,b,c,d)?!0:u.prototype.da.call(this,a,b,c,d)};Pb.prototype.Fa=function(a,b,c,d){this.R=a;this.I=b;this.w=c;this.K=d;this.B=Qb(a,"Keyboard")};Pb.prototype.va=function(a,b){b||Tb();return!0};Pb.prototype.ua=function(){return!0};
function Tb(){for(var a=!1,b=sb(document,"pc8080","panel"),c=0;c<b.length;c++){var d=b[c],e=tb(d),f=vb(e.id);f||(a=!0,f=new Pb(e));rb(f,d);a&&Gb(f)}}Za(Tb);
function Ub(a,b,c){u.call(this,"Bus",a);this.w=b;this.K=c;this.M=a.busWidth||16;this.N=Math.pow(2,this.M);this.C=this.N-1|0;this.g=(this.M>>1)+2;10>this.g&&(this.g=10);15<this.g&&(this.g=15);this.u=1<<this.g;this.O=this.u>>2;this.j=this.u-1;this.L=this.N/this.u|0;this.H=this.L-1;this.A=[];this.B=[];this.F=this.G=!1;this.S=[];this.T=[];a=new A;Vb(a,this.K);this.b=Array(this.L);for(b=0;b<this.L;b++)this.b[b]=a;Gb(this)}aa(Ub,u);Ub.prototype.reset=function(){};
@ -221,11 +221,11 @@ l.da=function(a,b,c){var d=this;switch(b){case "debugInput":return this.V=this.P
"";Tc(d,a,!0);return!0}return!1}),!0;case "step":return this.P[b]=c,Xa(c,function(a){var b=!1;Hb(d,!0)||(Ib(d,!0),b=Cg(d,a?1:0),Ib(d,!1));return b}),!0}return!1};l.Xa=function(){this.V&&this.V.focus()};function Ag(a){a=a&&a.J;null==a&&(a=-1);return a}l.Ga=function(a,b){var c=255,d=Ag(a);-1!==d&&(c=ac(this.I,d),b&&ah(a,b));return c};l.Eb=function(a,b){var c=65535,d=Ag(a);-1!==d&&(c=cc(this.I,d),b&&ah(a,b));return c};l.Xb=function(a,b,c){var d=Ag(a);-1!==d&&(dc(this.I,d,b),c&&ah(a,c),Uc(this.w,!0))};
l.Qc=function(a,b,c){var d=Ag(a);if(-1!==d){var e=this.I,f=d&e.j,g=(d&e.C)>>>e.g;f!=e.j?e.b[g].Sb(f,b&65535,d):(e.b[g++].ob(f,b&255,d),e.b[g&e.H].ob(0,b>>8&255,d+1));c&&ah(a,c);Uc(this.w,!0)}};function vg(a){return{J:a,Ea:!1}}function ch(a){return[a.J,a.Ea]}function dh(a){return{J:a[0],Ea:a[1]}}
function Bg(a,b,c){var d;c=(c?a.L:a.sa).J;if(void 0!==b){d=b=rg(a,b)||b;var e;if(d.match(/^[a-z_][a-z0-9_]*$/i))for(d=d.toUpperCase(),c=0;c<a.C.length;c++){var f=a.C[c].ra[d];if(void 0!==f){d=f.o;void 0!==d&&(e=vg(d));break}}if(d=e)return d;c=pg(a,b)}null!=c&&(d=vg(c));return d}function eh(a,b,c){c&&(c=c.match(/(['"])(.*?)\1/))&&(b.td=a.yb(b.Jc=c[2]))}function ah(a,b){null!=a.J&&(a.J+=b||1)}function fh(a){return n(a,4)}
function gh(a,b,c){var d="";for(c=c||256;d.length<c;){var e=a.Ga(b,1);if(!e||36==e||127<=e)break;d+=32<=e?String.fromCharCode(e):"."}return d}function yg(a,b){a.K=a;a.ha=a.xd=536870912;a.Y=null;a.Z=[];b=a.yb(b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(b.length)for(var c in Ob)0<=Ia(b,c)&&(a.ha|=Ob[c],a.i(c+" messages enabled"))}function fe(a,b,c){for(var d in Ob)if(b==Ob[d]){a.la[d]=c;break}}
function gh(a,b,c){var d="";for(c=c||256;d.length<c;){var e=a.Ga(b,1);if(!e||36==e||127<=e)break;d+=32<=e?String.fromCharCode(e):"."}return d}function yg(a,b){a.K=a;a.ha=a.xd=1073741824;a.Y=null;a.Z=[];b=a.yb(b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(b.length)for(var c in Ob)0<=Ia(b,c)&&(a.ha|=Ob[c],a.i(c+" messages enabled"))}function fe(a,b,c){for(var d in Ob)if(b==Ob[d]){a.la[d]=c;break}}
l.Jb=function(a,b){var c;a=a.toUpperCase();null==b?c=Ia(hh,a):(c=Ia(hh,a.substr(b,2)),0>c&&(c=Ia(hh,a.substr(b,1))));return c};function ih(a,b){var c=0;a=a.Kb(b);if(void 0!==a)switch(b){case jh:case kh:case lh:case mh:case nh:case oh:case ph:case qh:c=2;break;case rh:case sh:case th:case uh:case vh:case wh:case xh:c=4}return c?n(a,c):"??"}
l.Kb=function(a){var b;if(0<=a){var c=this.w;switch(a){case jh:b=c.g;break;case kh:b=c.u;break;case lh:b=c.A;break;case rh:b=Ad(c);break;case mh:b=c.B;break;case nh:b=c.C;break;case sh:b=Cd(c);break;case oh:b=c.F;break;case ph:b=c.G;break;case th:b=D(c);break;case qh:b=E(c,D(c));break;case uh:b=c.M;break;case vh:b=c.j;break;case wh:b=yd(c);break;case xh:b=yd(c)&255|c.g<<8}}return b};
function yh(a,b){b=rg(a,b)||b;for(var c=0,d,e;0<=(c=b.indexOf("@",c));)e=a.Jb(b,c+1),0<=e&&(b=b.substr(0,c)+ih(a,e)+b.substr(c+1+hh[e].length)),c++;for(c=0;0<=(c=b.indexOf("#",c));)e=b.substr(c+1,2),d=la(e,16),null!=d&&32<=d&&128>d?(d=e+" '"+String.fromCharCode(d)+"'",b=b.replace("#"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("$",c));)e=b.substr(c+1,9),(d=Bg(a,e))?(d=e+' "'+gh(a,d)+'"',b=b.replace("$"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("^",c));)e=b.substr(c+1,9),(d=Bg(a,e))?(ah(d),d=
e+' "'+gh(a,d,11)+'"',b=b.replace("^"+e,d),c+=d.length):c++;return b}l.message=function(a,b){b&&(a+=" at "+fh(vg(this.w.j).J));this.ha&1073741824?this.Z.push(a):this.Y&&a==this.Y||(this.Y=a,this.ha&-2147483648&&(this.ea(),a+=" (cpu halted)"),this.i(a),this.w&&(a=this.w,cd(a),a.ta=0,Uc(a)))};
e+' "'+gh(a,d,11)+'"',b=b.replace("^"+e,d),c+=d.length):c++;return b}l.message=function(a,b){b&&(a+=" at "+fh(vg(this.w.j).J));this.ha&536870912?this.Z.push(a):this.Y&&a==this.Y||(this.Y=a,this.ha&-2147483648&&(this.ea(),a+=" (cpu halted)"),this.i(a),this.w&&(a=this.w,cd(a),a.ta=0,Uc(a)))};
function Lb(a,b,c,d,e,f,g,h){h|=256;null!=f&&(a.ha&h)!=h||a.message(b.Gb+"."+(null!=d?"outPort":"inPort")+"("+q(c)+","+(f?f:"unknown")+(null!=d?","+na(d):"")+")"+(null!=g?": "+na(g):"")+(null!=e?" at "+fh(e):""))}
function xg(a){var b;if(Yd(a)){if(!a.H||!a.H.length){a.H=Array(zh);for(b=0;b<a.H.length;b++)a.H[b]=vg();a.W=0;a.i("instruction history buffer allocated")}if(!a.F||!a.F.length)for(a.F=Array(256),b=0;b<a.F.length;b++)a.F[b]=[b,0]}else a.H&&a.H.length&&a.i("instruction history buffer freed"),a.W=0,a.H=[],a.F=[]}function Ah(a,b){if(!Bh(a))return!1;a.w.rb(b);return!0}
function Cg(a,b,c,d){if(!Bh(a))return!1;a.G=0;b||Yd(a)&&Zd(a,a.w.j,0);try{var e=a.w.Cb(b);0<e&&(a.G+=e,Yc(a.w,e,!0),Vc(a.w,e),a.S++)}catch(f){"number"!=typeof f&&(a.G=0,Eb(a.w,f.stack||f.message))}!1!==d&&Uc(a.w);Sc(a,c||!1);return 0<a.G}l.ea=function(a){this.w&&this.w.ea(a)};function Sc(a,b){void 0===b&&(b=!0);a.L=vg(a.w.j);b&&1!=a.O?Ch(a):Dh(a)}
@ -263,11 +263,10 @@ a.i("\teb [a] [...] edit bytes at address a"),a.i("\tew [a] [...] edit words a
eh(a,ye,Si);a.Oa(a.j,ye,!0)}Ah(a,!0)||c||a.i("cpu busy or unavailable, run command ignored")}break;case "h":a:{var ze;if(a.D.ka)ze="halting",a.ea();else{if(Hb(a,!0))break a;ze="already halted"}c||a.i(ze)}break;case "i":if("if"==f[0]){var Ae;var tc=b.substr(2),tc=xa(tc);pg(a,tc)?(c||a.i("true: "+tc),Ae=!0):(c||a.i("false: "+tc),Ae=!1);Ae||(d=!1);break}if("int"==f[0]){var nd;var Ti=f[1];if(a.w.N&512){var Be=pg(a,Ti);null==Be?nd=!1:(a.i("requesting interrupt level "+Be),Xd(a.w,Be),nd=!0)}else a.i("interrupts disabled (use rif=1 to enable)"),
nd=!1;nd||(d=!1);break}var Ce=f[1];if(Ce&&"?"!=Ce){var De=jg(a,Ce);if(void 0!==De){var Ui=ic(a.I,De);a.i(q(De)+": "+na(Ui))}}else a.i("input commands:"),a.i("\ti [p]\tread port [p]"),a.i("warning: port accesses can affect hardware state");break;case "k":var Vi=f[0];if("?"==f[1])a.i("stack trace commands:"),a.i("\tk\tshow frame addresses"),a.i("\tks\tshow symbol information");else{var Ee=0,Ug=vg(),uc=vg(a.w.M);for(a.i("stack trace for "+fh(uc.J));10>Ee;){for(var xb=null,Wi=256;65536>uc.J>>>0;){Ug.J=
a.Eb(uc,2);if(null==uc.J||!Wi--)break;for(var Xi=a,od=Ug,Vg=null,vc=od.J,Wg=vc,Fe=1;6>=Fe&&vc;Fe++){if(2<Fe){od.J=vc;var pd=Jh(Xi,od);if(0<=pd.indexOf("CALL")){var Xg=pd.indexOf(" ");if(vc+(pd.indexOf(" ",Xg+1)-Xg-1)/2==Wg){Vg=pd;break}}}vc--}od.J=Wg;if(xb=Vg)break}if(!xb||null==xb)break;var Yg=null;if("ks"==Vi){var Zg=xb.match(/[0-9A-F]+$/);Zg&&(Yg=gi(a,Zg[0]))}xb=wa(xb,50)+" ;"+(Yg||"stack="+fh(uc.J));a.i(xb);Ee++}Ee||a.i("no return addresses found")}break;case "l":"ln"==f[0]&&gi(a,f[1],!0);break;
case "m":a:{var cb,db=null,ba=f[1];"?"==ba&&(ba=void 0);if(void 0!==ba){var ob=0;if("all"==ba)ob=1878917119,ba=null;else if("on"==ba)db=!0,ba=null;else if("off"==ba)db=!1,ba=null;else{"keys"==ba&&(ba="key");"kbd"==ba&&(ba="keyboard");for(cb in Ob)if(ba==cb){ob=Ob[cb];db=!!(a.ha&ob);break}if(!ob){a.i("unknown message category: "+ba);break a}}if(ob)if("on"==f[2])a.ha|=ob,db=!0;else if("off"==f[2]&&(a.ha&=~ob,db=!1,1073741824==ob)){for(var Ge=0;Ge<a.Z.length;Ge++)a.i(a.Z[Ge]);a.Z=[]}}var Yi=0,wc="";
for(cb in Ob)if(!ba||ba==cb){var Zi=!!(a.ha&Ob[cb]);if(null===db||db==Zi)wc&&(wc+=","),++Yi%10||(wc+="\n\t"),"key"==cb&&(cb="keys"),wc+=cb}void 0===ba&&a.i("message commands:\n\tm [category] [on|off]\tturn categories on/off");a.i((null!==db?db?"messages on: ":"messages off: ":"message categories:\n\t")+(wc||"none"));xg(a)}break;case "o":var He=f[1],$i=f[2];if(He&&"?"!=He){var Ie=jg(a,He,"port #"),Je=jg(a,$i);void 0!==Ie&&void 0!==Je&&(mc(a.I,Ie,Je),a.i(q(Ie)+": "+na(Je)))}else a.i("output commands:"),
a.i("\to [p] [b]\twrite byte [b] to port [p]"),a.i("warning: port accesses can affect hardware state");break;case "p":if("print"==f[0]){ii(a,b.substr(5));break}var $g="pr"==f[0]?1:0,aj=1+$g;if(a.O)a.i("step in progress");else{var Ke=vg(a.w.j);switch(a.Ga(Ke)){case 205:a.O=aj,ah(Ke,3)}a.O?(a.Oa(a.j,Ke,!0),Ah(a)||(a.R&&a.R.Xa(),a.O=0)):ji(a,$g?"tr":"t")}break;case "r":if("reset"==b){a.R&&a.R.reset();break}Ch(a,f);break;case "s":hi(a,f);break;case "t":ji(a,f[0],f[1]);break;case "u":Dh(a,f[1],f[2],8);
break;case "v":if("var"==f[0]){fi(a,b.substr(3))||(d=!1);break}a.i("PC8080 version 1.36.1 ("+a.w.vb+",RELEASE"+(Mb?",TYPEDARRAYS":",LONGARRAYS")+")");a.i(La());break;case "?":if(f[1]){ii(a,b.substr(1));break}var Le="commands:",Me;for(Me in li)Le+="\n"+wa(Me,9)+li[Me];Yd(a)||(Le+="\nnote: frequency/history disabled if no exec breakpoints");a.i(Le);break;default:a.i("unknown command: "+b),d=!1}}}catch(bh){a.i("debugger error: "+(bh.stack||bh.message)),d=!1}return d}
function Tc(a,b,c){b=a.yb(b,c);for(var d in b)if(!Ih(a,b[+d]))return!1;return!0}
case "m":a:{var cb,db=null,ba=f[1];"?"==ba&&(ba=void 0);if(void 0!==ba){var ob=0;if("all"==ba)ob=1610481663,ba=null;else if("on"==ba)db=!0,ba=null;else if("off"==ba)db=!1,ba=null;else{"keys"==ba&&(ba="key");"kbd"==ba&&(ba="keyboard");for(cb in Ob)if(ba==cb){ob=Ob[cb];db=!!(a.ha&ob);break}if(!ob){a.i("unknown message category: "+ba);break a}}if(ob)if("on"==f[2])a.ha|=ob,db=!0;else if("off"==f[2]&&(a.ha&=~ob,db=!1,536870912==ob)){for(var Ge=0;Ge<a.Z.length;Ge++)a.i(a.Z[Ge]);a.Z=[]}}var Yi=0,wc="";for(cb in Ob)if(!ba||
ba==cb){var Zi=!!(a.ha&Ob[cb]);if(null===db||db==Zi)wc&&(wc+=","),++Yi%10||(wc+="\n\t"),"key"==cb&&(cb="keys"),wc+=cb}void 0===ba&&a.i("message commands:\n\tm [category] [on|off]\tturn categories on/off");a.i((null!==db?db?"messages on: ":"messages off: ":"message categories:\n\t")+(wc||"none"));xg(a)}break;case "o":var He=f[1],$i=f[2];if(He&&"?"!=He){var Ie=jg(a,He,"port #"),Je=jg(a,$i);void 0!==Ie&&void 0!==Je&&(mc(a.I,Ie,Je),a.i(q(Ie)+": "+na(Je)))}else a.i("output commands:"),a.i("\to [p] [b]\twrite byte [b] to port [p]"),
a.i("warning: port accesses can affect hardware state");break;case "p":if("print"==f[0]){ii(a,b.substr(5));break}var $g="pr"==f[0]?1:0,aj=1+$g;if(a.O)a.i("step in progress");else{var Ke=vg(a.w.j);switch(a.Ga(Ke)){case 205:a.O=aj,ah(Ke,3)}a.O?(a.Oa(a.j,Ke,!0),Ah(a)||(a.R&&a.R.Xa(),a.O=0)):ji(a,$g?"tr":"t")}break;case "r":if("reset"==b){a.R&&a.R.reset();break}Ch(a,f);break;case "s":hi(a,f);break;case "t":ji(a,f[0],f[1]);break;case "u":Dh(a,f[1],f[2],8);break;case "v":if("var"==f[0]){fi(a,b.substr(3))||
(d=!1);break}a.i("PC8080 version 1.36.1 ("+a.w.vb+",RELEASE"+(Mb?",TYPEDARRAYS":",LONGARRAYS")+")");a.i(La());break;case "?":if(f[1]){ii(a,b.substr(1));break}var Le="commands:",Me;for(Me in li)Le+="\n"+wa(Me,9)+li[Me];Yd(a)||(Le+="\nnote: frequency/history disabled if no exec breakpoints");a.i(Le);break;default:a.i("unknown command: "+b),d=!1}}}catch(bh){a.i("debugger error: "+(bh.stack||bh.message)),d=!1}return d}function Tc(a,b,c){b=a.yb(b,c);for(var d in b)if(!Ih(a,b[+d]))return!1;return!0}
var li={"?":"help/print","a [#]":"assemble","b [#]":"breakpoint",c:"clear output","d [#]":"dump memory","e [#]":"edit memory",f:"frequencies","g [#]":"go [to #]",h:"halt","i [#]":"input port #","if":"eval expression","int [#]":"request interrupt",k:"stack trace",ln:"list nearest symbol(s)",m:"messages","o [#]":"output port #",p:"step over",print:"print expression",r:"dump/set registers",reset:"reset machine",s:"set options","t [#]":"trace","u [#]":"unassemble",v:"print version","var":"assign variable"},
ug=8080,Kh=8086,Lh="NONE ACI ADC ADD ADI ANA ANI CALL CC CM CNC CNZ CP CPE CPO CZ CMA CMC CMP CPI DAA DAD DCR DCX DI EI HLT IN INR INX JMP JC JM JNC JNZ JP JPE JPO JZ LDA LDAX LHLD LXI MOV MVI NOP ORA ORI OUT PCHL POP PUSH RAL RAR RET RC RM RNC RNZ RP RPE RPO RZ RLC RRC RST SBB SBI SHLD SPHL STA STAX STC SUB SUI XCHG XRA XRI XTHL".split(" "),Mh="NONE ADC ADC ADD ADD AND AND CALL CALLC CALLS CALLNC CALLNZ CALLNS CALLP CALLNP CALLZ NOT CMC CMP CMP DAA ADD DEC DEC CLI STI HLT IN INC INC JMP JC JS JNC JNZ JNS JP JNP JZ MOV MOV MOV MOV MOV MOV NOP OR OR OUT JMP POP PUSH RCL RCR RET RETC RETS RETNC RETNZ RETNS RETP RETNP RETZ ROL ROR RST SBB SBB MOV MOV MOV MOV STC SUB SUB XCHG XOR XOR XCHG".split(" "),
kh=0,lh=1,mh=2,nh=3,oh=4,ph=5,qh=6,jh=7,rh=8,sh=9,th=10,uh=11,vh=12,wh=13,xh=14,hh="B C D E H L M A BC DE HL SP PC PS PSW".split(" "),Ph=15,Oh=240,Xh=3840,Qh=61440,Nh=0,Q=1,Th=2,Uh=3,Wh=16,P=32,Vh=64,Yh=128,R=jh<<8|Wh|Q,S=kh<<8|Wh|Q,U=lh<<8|Wh|Q,V=mh<<8|Wh|Q,W=nh<<8|Wh|Q,X=oh<<8|Wh|Q,Y=ph<<8|Wh|Q,Z=qh<<8|Wh|Q|Vh,mi=rh<<8|Wh|Uh,ni=sh<<8|Wh|Uh,oi=th<<8|Wh|Uh,pi=uh<<8|Wh|Uh,qi=xh<<8|Wh|Uh,Sh=4096,Rh=8192,O=16384,Zh=32768,zg=[[45],[42,mi,P],[71,mi|Vh,R|O],[29,mi],[28,S],[22,S],[44,S,P],[63],[45,Zh],[21,

File diff suppressed because one or more lines are too long

View file

@ -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 it is too large Load diff

File diff suppressed because one or more lines are too long

View file

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

View file

@ -117,14 +117,14 @@ l.kc=function(a,b,c,d){this.pa=a;this.na=b;this.Da=d;for(b=0;b<Ec.length;b++)(d=
l.Rb=function(a,b){if(!b){if(a&&this.restore){Ic(this);if(!this.restore(a))return!1;Jc(this)}else this.reset();this.tb("No debugger detected")}Lc(this);return!0};l.Qb=function(a,b){var c=this.X.cb;b&&Mc(this);return a?this.save(c):!0};l.Fd=function(){return this.X.cb?!0:this.X.Fd||void 0===this.ia.run?Nc(this):!1};l.li=function(){return 0};
function Jc(a){void 0===a.V.If&&(a.V.If=0);void 0===a.V.Ke&&(a.V.Ke=-1);void 0===a.V.Le&&(a.V.Le=-1);a.X.zf=0<=a.V.If&&0<a.V.Ke;a.X.zf&&(a.V.Hf=0,a.V.se=a.V.If-a.Ic)}
l.Ab=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.ia[b]=c;a=!0;break;case "run":this.ia[b]=c;c.onclick=function(){var a=d.X.cb,b;if(b=d.pa)if(b=d.pa,b.X.Xd&&(b.X.Xd=!1,b.X.Ie&&!b.X.Sb&&b.ue(Oc)),b.X.Sb)b=!0;else{var c=null,h,k=db(b.id);for(h=0;h<k.length&&(c=k[h],c===b||c.X.ready);h++);if(h==k.length)for(h=0;h<k.length&&(c=k[h],c===b||c.X.Sb);h++);h==k.length&&(c=b);q("The "+c.type+" component ("+c.id+") is not "+(c.X.ready?"powered yet":"ready yet"+(c.Df?" (waiting for notification)":
""))+".");b=!1}b&&a==d.X.cb&&(d.X.cb?Mc(d,!0):Nc(d,!0))};a=!0;break;case "speed":this.ia[b]=c;a=!0;break;case "setSpeed":this.ia[b]=c,c.onclick=function(){Pc(d,d.V.md<<1,!0)},c.textContent=this.V.re.toFixed(2)+"Mhz",a=!0}return a};function Qc(a,b){a.X.cb&&(b=a.A-b,a.A-=b,a.Sc-=b)}function Rc(a){var b=a.V.hd/a.V.Gf|0;if(!b||b>a.V.md)b=a.V.md;a.V.yi=Math.round(1E3/Hc);a.V.Ml=Math.floor(a.V.xd/Hc*b);a.V.rg=b}
""))+".");b=!1}b&&a==d.X.cb&&(d.X.cb?Mc(d,!0):Nc(d,!0))};a=!0;break;case "speed":this.ia[b]=c;a=!0;break;case "setSpeed":this.ia[b]=c,c.onclick=function(){Pc(d,d.V.md<<1,!0)},c.textContent=this.V.re.toFixed(2)+"Mhz",a=!0}return a};function Qc(a,b){a.X.cb&&(b=a.A-b,a.A-=b,a.Sc-=b)}function Rc(a){var b=a.V.hd/a.V.Gf;if(!b||b>a.V.md)b=a.V.md;a.V.yi=Math.round(1E3/Hc);a.V.Ml=Math.floor(a.V.xd/Hc*b);a.V.rg=b}
function Sc(a,b){var c=a.Ic+a.Tc+a.Sc-a.A;b&&1<a.V.md&&a.V.hd>a.V.Gf&&(c=Math.round(c/a.V.md));return c}function Ic(a){a.Ic=a.Tc=a.Sc=a.A=0;Jc(a);Pc(a,a.V.zi)}
function Pc(a,b,c){if(void 0!==b){0<a.V.hd&&.8>a.V.hd/a.V.re&&(b=a.V.zi);a.V.hd=0;a.V.md=b;b=a.V.Gf*a.V.md;if(a.V.re!=b){a.V.re=b;b=a.V.re.toFixed(2)+"Mhz";var d=a.ia.setSpeed;d&&(d.textContent=b);a.tb("target speed: "+b)}c&&a.pa&&Tc(a.pa)}a.Ic+=a.Tc;a.Tc=0;a.V.Zc=a.V.Nd=0;Rc(a);for(c=a.qa.length-1;0<=c;c--)b=a.qa[c],0<=b[2]&&Uc(a,c,b[2],!0)}function Gc(a,b,c,d){d=void 0===d?-1:d;var e=a.qa.length;a.qa.push([b,-1,d,c]);0<=d&&Uc(a,e,d)}
function Pc(a,b,c){if(void 0!==b){0<a.V.hd&&a.V.hd<.9*a.V.re&&(b=a.V.zi);a.V.hd=0;a.V.md=b;b=a.V.Gf*a.V.md;if(a.V.re!=b){a.V.re=b;b=a.V.re.toFixed(2)+"Mhz";var d=a.ia.setSpeed;d&&(d.textContent=b);a.tb("target speed: "+b)}c&&a.pa&&Tc(a.pa)}a.Ic+=a.Tc;a.Tc=0;a.V.Zc=a.V.Nd=0;Rc(a);for(c=a.qa.length-1;0<=c;c--)b=a.qa[c],0<=b[2]&&Uc(a,c,b[2],!0)}function Gc(a,b,c,d){d=void 0===d?-1:d;var e=a.qa.length;a.qa.push([b,-1,d,c]);0<=d&&Uc(a,e,d)}
function Uc(a,b,c,d){0<=b&&b<a.qa.length&&(b=a.qa[b],d||0>b[1])&&(c=a.V.xd*a.V.rg/1E3*c|0,a.X.cb&&(c+=Vc(a)),b[1]=c)}function Wc(a){for(var b=[],c=0;c<a.qa.length;c++){var d=a.qa[c];b.push([d[0],d[1],d[2]])}return b}function Vc(a,b){var c=a.Sc-=a.A;a.A=0;b&&(a.Sc=0);return c}
l.kn=function(){if(this.X.cb){Rc(this);this.V.Jf=0;this.V.Je=ua();this.V.Zc||(this.V.Zc=this.V.Je);if(this.V.Nd){var a=this.V.Je-this.V.Nd;a>this.V.yi&&(this.V.Zc+=a,this.V.Zc>this.V.Je&&(this.V.Zc=this.V.Je))}try{this.X.Zf=!1;do{for(var b,c=this.X.zf?1:this.V.xd*this.V.rg|0,d=this.qa.length-1;0<=d;d--){var e=this.qa[d];0>e[1]||c>e[1]&&(c=e[1])}b=c;if(this.U){Xc(this.U);var f=this.U,a=b,g=f.qa[0];if(g.Kd){var h=(Sc(f.R,f.N)-g.jd)/f.Aa|0,k=Yc(f,0)-h;g.mode==Zc&&(k-=h);var m=k*f.Aa|0;g.mode==Zc&&(m>>=
1);a>m&&(a=m)}b=a;var r=this.U,a=b;if(r.A&&r.A[$c]&ad){var y=r.W-Sc(r.R,r.N);0<y&&a>y&&(a=y)}b=a}try{this.th(b)}catch(N){if("number"!=typeof N)throw N;}b=Vc(this,!0);this.V.Jf+=b;this.Tc+=b;a=b;if(this.X.zf){var t=!1;this.V.Hf=this.V.Hf+this.li()|0;this.V.se-=a;0>=this.V.se&&(this.V.se+=this.V.Ke,t=!0);0<=this.V.Le&&this.V.Le<=Sc(this)&&(this.V.Ke=this.V.Le=-1,Jc(this),Mc(this),t=!0);t&&this.tb(Sc(this)+" cycles: checksum="+ia(this.V.Hf))}for(var a=b,z=this.qa.length-1;0<=z;z--){var B=this.qa[z];
0>B[1]||(B[1]-=a,0>=B[1]&&(B[1]=-1,B[3](),0<=B[2]&&Uc(this,z,B[2])))}}while(this.X.cb&&!this.X.Zf)}catch(N){Mc(this);Lc(this);this.pa&&this.pa.stop(ua(),Sc(this));mb(this,N.stack||N.message);return}if(this.X.cb){b=setTimeout;c=this.pi;this.V.Nd=ua();d=this.V.yi;this.V.Jf&&(d=Math.round(d*this.V.Jf/this.V.Ml));d-=this.V.Nd-this.V.Je;if(e=this.V.Nd-this.V.Zc)this.V.hd=Math.round(this.Tc/(10*e))/100,864E5<=e&&(this.Ic=0,this.U&&Xc(this.U,!0),Pc(this));if(0>d||this.V.hd<this.V.re)-1E3>d&&(this.V.Zc-=
d),d=0;this.V.Nd+=d;b(c,d)}}};function Nc(a,b){var c;a.X.error?(a.tb(a.toString()+" error"),c=!0):c=!1;if(c)return!1;if(a.X.cb)return a.tb(a.toString()+" busy"),!1;Pc(a);a.X.cb=!0;a.X.Pj=!0;a.U&&a.U.start();if(c=a.ia.run)c.textContent="Halt";a.pa&&(bd(a.pa,!0),b&&Tc(a.pa,!0),a.pa.start(a.V.Zc,Sc(a)));setTimeout(a.pi,0);return!0}l.th=function(){return 0};
0>B[1]||(B[1]-=a,0>=B[1]&&(B[1]=-1,B[3](),0<=B[2]&&Uc(this,z,B[2])))}}while(this.X.cb&&!this.X.Zf)}catch(N){Mc(this);Lc(this);this.pa&&this.pa.stop(ua(),Sc(this));mb(this,N.stack||N.message);return}if(this.X.cb){b=setTimeout;c=this.pi;this.V.Nd=ua();d=this.V.yi;this.V.Jf&&(d=Math.round(d*this.V.Jf/this.V.Ml));d-=this.V.Nd-this.V.Je;if(e=this.V.Nd-this.V.Zc)this.V.hd=Math.round(this.Tc/(10*e))/100,864E5<=e&&(this.Ic=0,this.U&&Xc(this.U,!0),Pc(this));0>d?(-1E3>d&&(this.V.Zc-=d),d=0):this.V.hd<this.V.re&&
(d=0);this.V.Nd+=d;b(c,d)}}};function Nc(a,b){var c;a.X.error?(a.tb(a.toString()+" error"),c=!0):c=!1;if(c)return!1;if(a.X.cb)return a.tb(a.toString()+" busy"),!1;Pc(a);a.X.cb=!0;a.X.Pj=!0;a.U&&a.U.start();if(c=a.ia.run)c.textContent="Halt";a.pa&&(bd(a.pa,!0),b&&Tc(a.pa,!0),a.pa.start(a.V.Zc,Sc(a)));setTimeout(a.pi,0);return!0}l.th=function(){return 0};
function Mc(a,b){if(a.X.cb){Vc(a);a.Ic+=a.Tc;a.Tc=0;a.X.cb=!1;a.U&&a.U.stop();var c=a.ia.run;c&&(c.textContent="Run");a.pa&&(a.pa.stop(Date.now()||+new Date,Sc(a)),bd(a.pa,!0));a.Da||a.status("Stopped")}a.X.complete=b}function Lc(a){a.pa&&bd(a.pa,void 0)}var Hc=30,Ec=["power","reset"];
function cd(a,b,c,d){this.A=a;this.Da=a.Da;this.id=b;this.Xf=c||"";this.ha=0;this.jb=65535;this.C=this.jb+1;this.rb=this.jc=this.ext=this.nb=this.type=this.va=0;this.cc=-1;this.T=this.Jc=2;this.O=this.sa=65535;this.J=this.wi;this.I=this.H=this.xf;this.B={ha:-1,va:0,jb:0,nb:0,type:0,ext:0,cc:-1};1==this.id&&(this.Xe=0,this.D=null,this.ne=!1,this.G=Array(32),this.F=[]);dd(this,!0,d);this.id||(this.Jb=this.qb=this.ai)}l=cd.prototype;l.wi=function(a){this.ha=a&65535;return this.va=this.ha<<4};
l.Ff=function(a,b){var c,d,e=this.A;a&=65535;a&4?(c=e.mc.va,d=c+e.mc.jb|0):(c=e.Ob,d=e.Oc);if(c){c=c+(a&65528)|0;if(d-c|0)return e.A-=15,ed(this,c,a,b);this.id<fd&&w.call(e,b&&this.id==gd?10:13,a&65532)}return-1};l.Gl=function(a){var b=this.A;a=b.Xb+(a<<2);var c=b.ga(a);b.N&=-769;return this.load(b.ga(a+2))+c|0};l.Fl=function(a){var b=this.A;a<<=3;var c=b.Xb+a|0;if(7<=(b.Qc-c|0))return this.D=!0,a=ed(this,c,a),-1!==a&&(a+=this.Xe),a;w.call(b,13,a|2);return-1};l.ai=function(a){return this.va+a|0};

File diff suppressed because one or more lines are too long

View file

@ -76,7 +76,7 @@ var Kb="undefined"!==typeof ArrayBuffer,y="pdp11",Lb="PDPjs",Mb=!1,Nb=Kb,Ob=!0,P
dc:61438,Ta:3967,na:{xa:1,Ib:4}},bf:{rd:15,gd:16,$b:8160,rb:57344,na:{gd:4,$b:5,rb:13}},xa:{Ee:0,fc:2,sb:4,vd:6,Jc:8,Ve:10,Ke:12,pk:14}},Sb={qd:5,ud:112,Zc:4,Te:"DY",hf:{Fa:1,xa:14,Ya:48,Hb:64,Za:128,rb:768,Rd:15360,gj:16384,gb:32768,Fi:16254,bk:128,dc:65535,Ta:1022,na:{xa:1,Ya:4,rb:8}},ff:{Ta:65534},jf:{sf:1,tf:4,uf:16,$j:65408,ae:63,Ic:64,ec:65408,Me:3,sj:8,na:{Ic:6,ec:7}},Hc:{Pe:{Fj:0,ek:1,Di:2,Gj:3,Jc:4,Re:5,jk:6,dk:7},Sd:8,Oe:16,pj:32,rj:64,Ne:128,qj:256,vj:512,xj:1024,uj:2048,tj:4096,yj:8192,
oj:16384,wj:32768},gf:{ab:63},Rd:{Rj:1024,fj:2048,ge:2048,Aj:3072,Ie:4096,$a:5120,cc:8192,Ij:9216},xa:{Kj:0,vd:2,vf:4,Jc:6,Ze:8,xf:10,We:12,Wj:14}},Tb={qd:5,ud:180,Zc:2,Te:"DX",lf:{bc:1,xa:14,td:16,DONE:32,Hb:64,bb:128,INIT:16384,gb:32768,Jb:16128,dc:32992,Ta:16479},Xj:{},pf:{ab:127},nf:{ab:31},mf:{Nd:1,Xd:2,jd:4,ac:64,Fa:128},xa:{ad:0,EMPTY:2,fc:4,sb:6,Jb:8,Ye:10,Kc:12,Xe:14},ERROR:{ed:8,fd:16,zi:24,Se:32,mj:40,ak:48,pd:56,Pj:72,Oj:80,Nj:88,Hi:96,Bi:104,Mj:112,od:120,Gi:128,Ai:136}},Ub={48:"DL11R",
52:"DL11X",56:"PC11R",60:"PC11X",64:"KW11",112:"RL11",144:"RK11",180:"RX11"};Tb.kf=["DX",77,1,26,128,1,0,0,128,0];Rb.Fc=["RK",203,2,12,512,0,0,0,512,Rb.Gc.Fc|Rb.Gc.de|Rb.Gc.$d];Sb.df=["RL",512,2,40,256,0,0,0,256,Sb.Hc.Pe.Re|Sb.Hc.Sd|Sb.Hc.Oe];
var y="pdp11",Lb="PDPjs",Mb=!1,Nb=Kb,Pb=Ob=!0,Vb={cpu:1,trap:2,fault:4,"int":8,bus:16,memory:32,mmu:64,rom:128,device:256,panel:512,keyboard:1024,key:2048,pc11:4096,paper:4096,disk:8192,read:16384,write:32768,rk11:65536,rl11:131072,rx11:262144,dl11:1048576,serial:1048576,kw11:2097152,timer:2097152,speaker:16777216,computer:33554432,log:268435456,warn:536870912,buffer:1073741824,halt:-2147483648};
var y="pdp11",Lb="PDPjs",Mb=!1,Nb=Kb,Pb=Ob=!0,Vb={cpu:1,trap:2,fault:4,"int":8,bus:16,memory:32,mmu:64,rom:128,device:256,panel:512,keyboard:1024,key:2048,pc11:4096,paper:4096,disk:8192,read:16384,write:32768,rk11:65536,rl11:131072,rx11:262144,dl11:1048576,serial:1048576,kw11:2097152,timer:2097152,speaker:16777216,computer:33554432,log:536870912,warn:1073741824,halt:-2147483648};
function Wb(a,b){x.call(this,"Panel",a,512);this.j=this.u=0;this.M=b;this.ga=this.g=this.Wa=this.Db=0;this.B=this.C=-1;this.G=this.I=this.w=!1;this.K=Xb;this.i={};this.b={START:[1,1,!0,!1,this.Uf],STEP:[1,1,!1,!1,this.Vf],ENABLE:[1,1,!1,!1,this.Pf],CONT:[1,1,!0,!1,this.Nf],DEP:[0,0,!0,!1,this.Of],EXAM:[1,1,!0,!1,this.Qf],LOAD:[1,1,!0,!1,this.Sf],TEST:[0,0,!0,!1,this.Rf]};for(a=0;22>a;a++)this.b["S"+a]=[0,0,!1,!1,this.Tf,a];this.D=this.f=this.F=this.J=null;this.exports={hold:this.If,toggle:this.nh,
reset:this.hh,set:this.mh};D(this)}p(Wb,x);function Yb(a,b){return ec(a,a.Db=b)}h=Wb.prototype;h.reset=function(a){this.stop();a&&Yb(this,0)};
h.wa=function(a,b,c,d){if(this.J&&this.J.wa(a,b,c,d)||this.f&&this.f.wa(a,b,c,d)||this.D&&this.D.wa(a,b,c,d))return!0;switch(b){case "R0":case "R1":case "R2":case "R3":case "R4":case "R5":case "R6":case "R7":case "NF":case "ZF":case "VF":case "CF":case "PS":return this.H[b]=c,this.u++,!0;default:return"led"==a||"rled"==a?(this.H[b]=c,this.i[b]=d?1:0,this.u++,!0):"switch"==a?(void 0===this.b[b]&&(this.b[b]=[d?1:0,d?1:0]),this.H[b]=c,a=c.parentElement||c,a=a.parentElement||a,a.onmousedown=function(a,
@ -314,10 +314,10 @@ h.Sa=function(a,b){var c=65535,d=Vj(a);-1!==d&&(c=a.Na||65535<d?Gc(this.F,Se(thi
function ak(a,b,c){var d;c=(c?a.I:a.Ga).L;var e,f;if(void 0!==b){a:{var g;d=a.O[0];c=a.O[1];g="("==d||"{"==d||"["==d?"\\":"";for(var k="["==d?"\\":"",k=new RegExp(g+d+"([^"+k+d+k+c+"]+)"+g+c);g=b.match(k);){var l=Nj(a,g[1]);if(void 0===l){b=void 0;break a}b=b.replace(d+g[1]+c,null!=l?K(a,l):"undefined")}if(a.ka.length)for(d=a.ka[0],c=a.ka[1],g="("==d||"{"==d||"["==d?"\\":"",k="["==d?"\\":"",k=new RegExp(g+d+"([^"+k+d+k+c+"]+)"+g+c);g=b.match(k);)b=b.replace("["+g[1]+"]","unimplemented");for(;d=b.match(/\$([a-z]+)/i);){c=
null;switch(d[1].toLowerCase()){case "ops":c=0}if(null==c)break;b=b.replace(d[0],c.toString())}}"%"==b.charAt(0)&&(e=!0,b=b.substr(1));d=b;var m,n;a:{c=a.F;g=d.toUpperCase();for(n in c.Qa)if(k=+n,c.Qa[k][4]==g){n=c.B+k;break a}n=null}if(null==n&&d.match(/^[a-z_][a-z0-9_]*$/i))for(d=d.toUpperCase(),c=0;c<a.C.length;c++)if(g=a.C[c].ia[d],null!=g){n=g.o;break}null!=n&&(m=X(n));if(d=m)return d;0<=b.indexOf("0x")?f=16:0<=b.indexOf("0o")?f=8:0<=b.indexOf(".")&&(f=10);c=Nj(a,b)}null!=c&&(d=X(c,e,f));return d}
function ck(a,b,c){c&&(c=c.match(/(['"])(.*?)\1/))&&(b.he=Ej(a,b.Oc=c[2]))}function bk(a,b){null!=a.L&&(a.L+=b||1)}function dk(a,b){return(b.Na?"%":"")+K(a,b.L)}
function Tj(a,b){a.D=a;a.ja=a.ke=536870912;a.U=null;a.N=[];b=Ej(a,b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(b.length)for(var c in Vb){var d;a:if(d=void 0,Array.prototype.indexOf)d=b.indexOf(c,d);else{d=d||0;0>d&&(d+=b.length);0>d&&(d=0);for(var e=b.length;d<e;d++)if(d in b&&b[d]===c)break a;d=-1}0<=d&&(a.ja|=Vb[c],a.v(c+" messages enabled"))}}function vd(a,b,c){for(var d in Vb)if(b==Vb[d]){a.ma[d]=c;break}}
function Tj(a,b){a.D=a;a.ja=a.ke=1073741824;a.U=null;a.N=[];b=Ej(a,b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(b.length)for(var c in Vb){var d;a:if(d=void 0,Array.prototype.indexOf)d=b.indexOf(c,d);else{d=d||0;0>d&&(d+=b.length);0>d&&(d=0);for(var e=b.length;d<e;d++)if(d in b&&b[d]===c)break a;d=-1}0<=d&&(a.ja|=Vb[c],a.v(c+" messages enabled"))}}function vd(a,b,c){for(var d in Vb)if(b==Vb[d]){a.ma[d]=c;break}}
h.re=function(a){a=a.toUpperCase();var b=ek[a];null==b&&(b=-1,"R"==a.charAt(0)&&(b=+a.charAt(1),0>b||7<b))&&(b=-1);return b};function fk(a,b){var c;if(b<gk||a.g)c=hk[b];return c||""}
h.Ad=function(a){var b;if(0<=a)if(8>a)b=this.f.g[a];else if(16>a)b=this.f.ua[a-8];else if(20>a)b=this.f.Y[a-16];else{var c=this.f,d=this.g;switch(a){case ik:b=Ed(this.f);break;case jk:b=c.nb;break;case kk:b=c.P;break;case lk:b=c.Ga&65280;break;case mk:b=yd(c);break;case nk:b=Ad(c);break;case ok:b=Bd(c);break;case pk:b=c.X;break;case gk:d&&(b=d.ga);break;case qk:d&&(b=d.Db);break;case rk:d&&(b=d.Wa)}}return b};
h.message=function(a,b){b&&(a+=" @"+dk(this,X(this.f.O&65535)));if(!this.U||a!=this.U)if(this.U=a,this.ja&1073741824)this.N.push(a);else{var c;if(this.ja&-2147483648&&this.f&&(c=this.f.A.V)||Ib(this,!0))this.da(),c&&(a+=" (cpu halted)");this.v(a);this.f&&(a=this.f,ve(a),a.zb=0,a.J&&H(a.J,void 0))}};
h.message=function(a,b){b&&(a+=" @"+dk(this,X(this.f.O&65535)));if(!this.U||a!=this.U)if(this.U=a,this.ja&536870912)this.N.push(a);else{var c;if(this.ja&-2147483648&&this.f&&(c=this.f.A.V)||Ib(this,!0))this.da(),c&&(a+=" (cpu halted)");this.v(a);this.f&&(a=this.f,ve(a),a.zb=0,a.J&&H(a.J,void 0))}};
function Sj(a){var b;if(!ff(a))a.j&&a.j.length&&a.v("instruction history buffer freed"),a.S=0,a.j=[];else if(!a.j||!a.j.length){a.j=Array(sk);for(b=0;b<a.j.length;b++)a.j[b]=X();a.S=0;a.v("instruction history buffer allocated")}}function tk(a,b,c){if(!uk(a,c))return!1;yc(a.f,b);return!0}
function zc(a,b,c,d){if(!uk(a))return!1;var e="";null===c&&(e=(c=!a.ua||"tr"==a.ua)?"tr":"t");a.B=0;b||ff(a)&&Cf(a,a.f.g[7],0);try{b=we(a.f,b);var f=a.f.Ac(b);0<f&&(Ac(a.f,f),a.B+=f,Bc(a.f,f,!0),Cc(a.f,f),a.Z++)}catch(g){"number"!=typeof g&&(a.B=0,Fb(a.f,g.stack||g.message))}!1!==d&&(a.g&&a.g.stop(),H(a.J,-1));ne(a,c||!1,e);return 0<a.B}h.da=function(a){this.f&&this.f.da(a)};
function ne(a,b,c){if(a.Ha){void 0===b&&(b=!0);c&&a.v(vk+c);c=a.f;if(c=c.i&128?c.Cc|c.Bc<<8:0){var d=c>>8;a.v("trapped to "+K(a,c&255,8)+" ("+(0>d?Qb[-d]:K(a,d))+")")}a.I=X(a.f.g[7]);b&&1!=a.K?wk(a):xk(a)}}function uk(a,b){var c;(c=!a.f||!Hb(a.f))||(c=a.f,c.A.ca?c=!0:(c.v(c.toString()+" not powered"),c=!1),c=!c);return c||a.f.A.V?(b||a.v("cpu busy or unavailable, command ignored"),!1):!Gb(a.f)}h.Da=function(a,b){return!b&&(this.reset(!0),a)?this.restore(a):!0};
@ -355,8 +355,8 @@ lb?1:2,Od=yb*xb||128,nf=mf?16:a.W,Bl=(Od+nf-1)/nf|0||1,zb="";Bl--&&0<Od;){for(va
a.W=Al}}}}break;case "e":if("else"==g[0])break;var cc,qf,rf,sf,tf=g[0],uf=g[1];"eb"==tf?(cc=1,qf=255,rf=a.Pd,sf=a.Qd):"e"==tf||"ew"==tf?(cc=2,qf=65535,rf=a.Sa,sf=a.Le):uf=null;if(null==uf)a.v("edit memory commands:"),a.v("\teb [a] [...] edit bytes at address a"),a.v("\tew [a] [...] edit words at address a");else{var Rd=ak(a,uf);if(Rd)for(var Sd=2;Sd<g.length;Sd++){var Rc=Nj(a,g[Sd]);if(void 0===Rc){a.v("unrecognized value: "+g[Sd]);break}Rc&~qf&&a.v("warning: "+v(Rc)+" exceeds "+cc+"-byte value");
a.v("changing "+dk(a,Rd)+(E(a,16)?"":" from "+K(a,rf.call(a,Rd),cc<<3))+" to "+K(a,Rc,cc<<3));sf.call(a,Rd,Rc,cc)}}break;case "g":a:{var Mi=g[1],Cl=b;if(void 0!==Mi){var vf=ak(a,Mi,!0);if(!vf)break a;ck(a,vf,Cl);a.Ab(a.b,vf,!0)}tk(a,!0,c)}break;case "h":a.A.V?(c||a.v("halting"),a.da()):Ib(a,!0)||c||a.v("already halted");break;case "i":if("if"==g[0]){var wf;var Sc=b.substr(2),Sc=za(Sc);Nj(a,Sc)?(c||a.v("true: "+Sc),wf=!0):(c||a.v("false: "+Sc),wf=!1);wf||(d=!1);break}f=!0;break;case "k":var Dl=g[0];
if("?"==g[1])a.v("stack trace commands:"),a.v("\tk\tshow frame addresses"),a.v("\tks\tshow symbol information");else{var xf=0,yf=X(),Tc=X(a.f.g[6]);for(a.v("stack trace for "+dk(a,Tc));10>xf;){for(var Bb=null,El=256;65536>Tc.L>>>0;){yf.L=a.Sa(Tc,2);if(null==Tc.L||!El--)break;if(!(yf.L&1)){for(var Fl=a,Td=yf,Ni=null,Uc=Td.L,Oi=Uc,zf=1;6>=zf&&Uc;zf++){if(2<zf){Td.L=Uc;var Ud=Ek(Fl,Td);if(0<=Ud.indexOf("JSR")){var Pi=Ud.indexOf(" ");if(Uc+(Ud.indexOf(" ",Pi+1)-Pi-1)/2==Oi){Ni=Ud;break}}}Uc-=2}Td.L=Oi;
if(Bb=Ni)break}}if(!Bb||null==Bb)break;var Qi=null;if("ks"==Dl){var Ri=Bb.match(/[0-9A-F]+$/);Ri&&(Qi=Wk(a,Ri[0]))}Bb=ya(Bb,50)+" ;"+(Qi||"stack="+dk(a,Tc));a.v(Bb);xf++}xf||a.v("no return addresses found")}break;case "l":if("ln"==g[0]){Wk(a,g[1],!0);break}f=!0;break;case "m":a:{var Wa,Xa=null,T=g[1];"?"==T&&(T=void 0);if(void 0!==T){var nb=0;if("all"==T)nb=1879046143,T=null;else if("on"==T)Xa=!0,T=null;else if("off"==T)Xa=!1,T=null;else{"keys"==T&&(T="key");"kbd"==T&&(T="keyboard");for(Wa in Vb)if(T==
Wa){nb=Vb[Wa];Xa=!!(a.ja&nb);break}if(!nb){a.v("unknown message category: "+T);break a}}if(nb)if("on"==g[2])a.ja|=nb,Xa=!0;else if("off"==g[2]&&(a.ja&=~nb,Xa=!1,1073741824==nb)){for(var Si=1E3<=a.N.length?a.N.length-1E3:0;Si<a.N.length;)a.v(a.N[Si++]);a.N=[]}}var Gl=0,Vc="";for(Wa in Vb)if(!T||T==Wa){var Hl=!!(a.ja&Vb[Wa]);if(null===Xa||Xa==Hl)Vc&&(Vc+=","),++Gl%10||(Vc+="\n\t"),"key"==Wa&&(Wa="keys"),Vc+=Wa}void 0===T&&a.v("message commands:\n\tm [category] [on|off]\tturn categories on/off");a.v((null!==
if(Bb=Ni)break}}if(!Bb||null==Bb)break;var Qi=null;if("ks"==Dl){var Ri=Bb.match(/[0-9A-F]+$/);Ri&&(Qi=Wk(a,Ri[0]))}Bb=ya(Bb,50)+" ;"+(Qi||"stack="+dk(a,Tc));a.v(Bb);xf++}xf||a.v("no return addresses found")}break;case "l":if("ln"==g[0]){Wk(a,g[1],!0);break}f=!0;break;case "m":a:{var Wa,Xa=null,T=g[1];"?"==T&&(T=void 0);if(void 0!==T){var nb=0;if("all"==T)nb=1610610687,T=null;else if("on"==T)Xa=!0,T=null;else if("off"==T)Xa=!1,T=null;else{"keys"==T&&(T="key");"kbd"==T&&(T="keyboard");for(Wa in Vb)if(T==
Wa){nb=Vb[Wa];Xa=!!(a.ja&nb);break}if(!nb){a.v("unknown message category: "+T);break a}}if(nb)if("on"==g[2])a.ja|=nb,Xa=!0;else if("off"==g[2]&&(a.ja&=~nb,Xa=!1,536870912==nb)){for(var Si=1E3<=a.N.length?a.N.length-1E3:0;Si<a.N.length;)a.v(a.N[Si++]);a.N=[]}}var Gl=0,Vc="";for(Wa in Vb)if(!T||T==Wa){var Hl=!!(a.ja&Vb[Wa]);if(null===Xa||Xa==Hl)Vc&&(Vc+=","),++Gl%10||(Vc+="\n\t"),"key"==Wa&&(Wa="keys"),Vc+=Wa}void 0===T&&a.v("message commands:\n\tm [category] [on|off]\tturn categories on/off");a.v((null!==
Xa?Xa?"messages on: ":"messages off: ":"message categories:\n\t")+(Vc||"none"));Sj(a)}break;case "p":if("print"==g[0]){Xk(a,b.substr(5));break}var Il=g[0];if("?"==g[1])a.v("step commands:"),a.v("\tp\tstep over instruction"),a.v("\tpr\tstep over instruction with register update");else{var Ti="pr"==Il?1:0,Ui=1+Ti;if(a.K)a.v("step in progress");else{var Vd=X(a.f.g[7]),dc=a.Sa(Vd);3==dc||4==dc||34816==(dc&65280)||32256==(dc&65024)||35072==(dc&65280)?(a.K=Ui,bk(Vd,2)):2048==(dc&65024)&&(Ek(a,Vd),a.K=
Ui);a.K?(a.Ab(a.b,Vd,!0),tk(a)||(a.J&&ue(a.J),a.K=0)):Yk(a,Ti?"tr":"t")}}break;case "r":if("reset"==b){a.J&&a.J.reset();break}wk(a,g);break;case "s":a:switch(g[1]){case "base":if(g[2]){var Wc=+g[2];if(8==Wc||10==Wc||16==Wc)a.W=Wc;else{a.v("invalid base: "+Wc);break}}a.v("default base: "+a.W);break;case "cs":var Xc;void 0!==g[3]&&(Xc=+g[3]);switch(g[2]){case "int":a.f.Lb=Xc;break;case "start":a.f.nc=Xc;break;case "stop":a.f.Pb=Xc;break;default:a.v("unknown cs option");break a}void 0!==Xc&&me(a.f);
a.v("checksums "+(a.f.A.Mb?"enabled":"disabled"));break;case "sp":void 0!==g[2]&&(re(a.f,+g[2])||a.v("warning: using 1x multiplier, previous target not reached"));a.v("target speed: "+(a.f.wb.toFixed(2)+"Mhz")+" ("+a.f.lb+"x)");break;default:if(g[1]){a.v("unknown option: "+g[1]);break}case "?":a.v("debugger options:"),a.v("\tbase #\t\tset default base to #"),a.v("\tcs int #\tset checksum cycle interval to #"),a.v("\tcs start #\tset checksum cycle start count to #"),a.v("\tcs stop #\tset checksum cycle stop count to #"),

File diff suppressed because one or more lines are too long

View file

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