Successfully running PCx86 and PC8080 machines on the same page now
This commit is contained in:
parent
145ec9d125
commit
f0509bc5d1
30 changed files with 2773 additions and 3118 deletions
|
|
@ -6,7 +6,7 @@ one of several JavaScript Machines in the [PCjs Project](https://github.com/jeff
|
|||
includes:
|
||||
|
||||
* [PCx86](/docs/pcx86/), an x86-based IBM PC and PC-compatible emulator
|
||||
* [PC8080](/modules/pc8080/), a 8080-based machine emulator (e.g., [Space Invaders](/devices/pc8080/machine/invaders/), [VT100 Terminal](/devices/pc8080/machine/vt100/))
|
||||
* [PC8080](/modules/pc8080/), an 8080-based machine emulator (e.g., [Space Invaders](/devices/pc8080/machine/invaders/), [VT100 Terminal](/devices/pc8080/machine/vt100/))
|
||||
* [C1Pjs](/docs/c1pjs/), a 6502-based emulation of the Ohio Scientific [Challenger 1P](/devices/c1p/)
|
||||
|
||||
All PCjs computer simulations are written entirely in [JavaScript](/modules/). No Flash, Java or other plugins are
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: page
|
||||
title: IBM PC AT (Model 5170, 2Mb20Mb Hard Disk) with EGA Display and Debugger
|
||||
title: IBM PC AT (Model 5170, 2Mb, 20Mb Hard Disk) with EGA Display and Debugger
|
||||
permalink: /devices/pcx86/machine/5170/ega/2048kb/rev3/debugger/
|
||||
redirect_from:
|
||||
- /devices/pc/machine/5170/ega/2048kb/rev3/debugger/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
layout: page
|
||||
title: IBM PC AT (Model 5170, 2Mb, 20Mb Hard Disk) with EGA Display and VT100 Debugger
|
||||
permalink: /devices/pcx86/machine/5170/ega/2048kb/rev3/debugger/vt100/
|
||||
machines:
|
||||
- id: ibm5170
|
||||
type: pcx86
|
||||
debugger: true
|
||||
- id: vt100
|
||||
type: pc8080
|
||||
debugger: true
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
---
|
||||
|
||||
{% include machine.html id="ibm5170" %}
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pcx86/1.24.0/machine.xsl"?>
|
||||
<machine id="ibm5170" class="pcx86" border="1" pos="center" background="#FAEBD7">
|
||||
<name>IBM PC AT (8Mhz), 128Kb EGA, 2Mb RAM, 20Mb Hard Disk</name>
|
||||
<computer id="at-ega-2048k" name="IBM PC AT" buswidth="24"/>
|
||||
<cpu id="cpu286" model="80286" cycles="8000000" autostart="true"/>
|
||||
<ram id="ramLow" addr="0x00000" test="false" size="0xa0000" comment="ROM BIOS memory test has been disabled"/>
|
||||
<ram id="ramExt" addr="0x100000" size="0x160000" comment=""/>
|
||||
<rom id="romBIOS" addr="0xf0000" size="0x10000" alias="0xff0000" file="/devices/pcx86/rom/5170/1985-11-15/ATBIOS-REV3.json"/>
|
||||
<video ref="/devices/pcx86/video/ibm/ega/1984-09-13/128kb-lockfs.xml"/>
|
||||
<fdc ref="/disks/pcx86/compiled/library.xml" automount='{A:{name:"PC-DOS 3.30 (Disk 1)",path:"/disks/pcx86/dos/ibm/3.30/PCDOS330-DISK1.json"}, B:{name:"PC-DOS 3.30 (Disk 2)",path:"/disks/pcx86/dos/ibm/3.30/PCDOS330-DISK2.json"}}'/>
|
||||
<keyboard ref="/devices/pcx86/keyboard/us84-buttons-arrows.xml"/>
|
||||
<debugger id="debugger" messages="fault" commands=""/>
|
||||
<panel ref="/devices/pcx86/panel/wide.xml"/>
|
||||
<hdc ref="/disks/pcx86/fixed/20mb/pcdos330-empty.xml"/>
|
||||
<chipset id="chipset" model="5170" floppies="[1440,1200]"/>
|
||||
<serial id="com1" adapter="1"/>
|
||||
<serial id="com2" adapter="2" binding="print" tabsize="8" charbol="9"/>
|
||||
<mouse serial="com1"/>
|
||||
</machine>
|
||||
|
|
@ -12,11 +12,11 @@ function Ea(a){var b;if(window)try{b=window.localStorage.getItem(a)}catch(c){}re
|
|||
function Ia(a,b,c,d){var e=null;b="data:application/"+b+(c?";base64":"")+",";b=Ga("Firefox")?b+(c?a:encodeURIComponent(a)):b+(c?a:encodeURI(a));d&&(e=document.createElement("a"),"string"!=typeof e.download&&(e=null));e?(e.href=b,e.download=d,document.body.appendChild(e),e.click(),document.body.removeChild(e),a="Check your Downloads folder for "+d+"."):(window.open(b),a="Check your browser for a new window/tab containing the requested data"+(d?" ("+d+")":"")+".");return a}
|
||||
function Ja(a,b,c){function d(){--a;0<=a&&(b()||(a=0));0<a?setTimeout(d,0):c()}d()}function Ka(a,b){function c(){b(100===d)&&(e=setTimeout(c,d),d=100)}var d=0,e=null,f=!1;a.onmousedown=function(){f||e||(d=500,c())};a.ontouchstart=function(){e||(d=500,c())};a.onmouseup=a.onmouseout=function(){e&&(clearTimeout(e),e=null)};a.ontouchend=a.ontouchcancel=function(){e&&(clearTimeout(e),e=null);f=!0}}var La={init:[],show:[],exit:[]},Ma=!1,Na=!0;
|
||||
function Pa(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function Qa(a){La.init.push(a)}function Ra(a){if(Na)try{for(var b=0;b<a.length;b++)a[b]()}catch(c){w(""+("An unexpected exception occurred:\n\n"+c.message+"\n\nPlease send this information to support@pcjs.org. Thanks."))}}function Sa(a){!Na&&a?(Na=!0,Ma&&Ta("init")):Na=a}function Ta(a){La[a]&&Ra(La[a])}Pa("onload",function(){Ma=!0;Ra(La.init)});Pa("onpageshow",function(){Ra(La.show)});
|
||||
Pa(Ga("Opera")||Ga("iOS")?"onunload":"onbeforeunload",function(){Ra(La.exit)});function Ua(a,b,c,d){this.type=a;b||(b={id:"",name:""});this.id=b.id;this.name=b.name;this.uk=b.comment;this.hk=b;void 0===this.id&&(this.id="");b=this.id.indexOf(".");0<b?(this.ve=this.id.substr(0,b),this.Rd=this.id.substr(b+1)):this.Rd=this.id;this[a]=c;this.la={bf:!1,bd:!1,bh:!1,cc:!1,ud:!1};this.tg=null;this.la.ud=!1;this.qa={};this.ha=null;this.wc=d||0;Va.push(this)}var Wa=void 0,Ya={};
|
||||
Pa(Ga("Opera")||Ga("iOS")?"onunload":"onbeforeunload",function(){Ra(La.exit)});function Ua(a,b,c,d){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.uk=b.comment;this.hk=b;b=this.id.indexOf(".");0>b?this.Rd=this.id:(this.ve=this.id.substr(0,b),this.Rd=this.id.substr(b+1));this[a]=c;this.la={bf:!1,bd:!1,bh:!1,cc:!1,ud:!1};this.tg=null;this.la.ud=!1;this.qa={};this.ha=null;this.wc=d||0;Va.push(this)}var Wa=void 0,Ya={};
|
||||
if(window){Wa||(Wa=window.location.search.substr(1));for(var Za,$a=/\+/g,ab=/([^&=]+)=?([^&]*)/g;Za=ab.exec(Wa);)Ya[decodeURIComponent(Za[1].replace($a," "))]=decodeURIComponent(Za[2].replace($a," "))}function cb(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b}
|
||||
function db(a,b){b||(b=Ua);a.prototype=cb(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}var Va=[],eb={};function fb(a,b,c){eb[a]&&b&&(eb[a][b]=c)}function gb(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<Va.length;b++){var d=Va[b];a&&d.id.indexOf(a)||c.push(d)}return c}function hb(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;c<Va.length;c++)if(Va[c].id===a)return Va[c]}return null}
|
||||
function ib(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<Va.length;d++)if(c)c==Va[d]&&(c=null);else if(!(a!=Va[d].type||b&&Va[d].id.indexOf(b)))return Va[d]}return null}function jb(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){w(c.message+" ("+a+")")}return b}function kb(a,b,c){var d;b&&(void 0===d&&(d="Panel"),(d=ib(d,a.id))&&(b=d.qa[b])&&a.Pb(null,c,b))}
|
||||
function mb(a,b){for(var c=nb(b.parentNode,"pcx86-control"),d=0;d<c.length;d++)for(var e=c[d].childNodes,f=0;f<e.length;f++){var g=e[f];if(1===g.nodeType){var h=g.getAttribute("class");if(h)for(var k=h.split(" "),l=0;l<k.length;l++)switch(h=k[l],h){case "pcx86-binding":(h=jb(g))&&h.binding&&a.Pb(h.type,h.binding,g,h.value),l=k.length}}}}
|
||||
function db(a,b){b||(b=Ua);a.prototype=cb(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={Machines:{},Components:[]});var eb=window.PCjs.Machines,Va=window.PCjs.Components}else eb={},Va=[];function fb(a,b,c){eb[a]&&b&&(eb[a][b]=c)}function gb(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<Va.length;b++){var d=Va[b];a&&d.id.indexOf(a)||c.push(d)}return c}
|
||||
function hb(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;c<Va.length;c++)if(Va[c].id===a)return Va[c]}return null}function ib(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<Va.length;d++)if(c)c==Va[d]&&(c=null);else if(!(a!=Va[d].type||b&&Va[d].id.indexOf(b)))return Va[d]}return null}function jb(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){w(c.message+" ("+a+")")}return b}
|
||||
function kb(a,b,c){var d;b&&(void 0===d&&(d="Panel"),(d=ib(d,a.id))&&(b=d.qa[b])&&a.Pb(null,c,b))}function mb(a,b){for(var c=nb(b.parentNode,"pcx86-control"),d=0;d<c.length;d++)for(var e=c[d].childNodes,f=0;f<e.length;f++){var g=e[f];if(1===g.nodeType){var h=g.getAttribute("class");if(h)for(var k=h.split(" "),l=0;l<k.length;l++)switch(h=k[l],h){case "pcx86-binding":(h=jb(g))&&h.binding&&a.Pb(h.type,h.binding,g,h.value),l=k.length}}}}
|
||||
function nb(a,b,c){c&&(b+="-"+c+"-object");if(a.getElementsByClassName)return a.getElementsByClassName(b);var d;c=[];a=a.getElementsByTagName("*");var e=new RegExp("(^| )"+b+"( |$)");b=0;for(d=a.length;b<d;b++)e.test(a[b].className)&&c.push(a[b]);return c}
|
||||
Ua.prototype={constructor:Ua,parent:null,toString:function(){return this.name?this.name:this.id||this.type},Pb:function(a,b,c){switch(b){case "clear":return this.qa[b]||(this.qa[b]=c,c.onclick=function(a){return function(){a.qa.print&&(a.qa.print.value="")}}(this)),!0;case "print":return this.qa[b]||(this.Ef=this.qa[b]=c,c.value="",this.O=function(a){return function(b,c){8192<a.value.length&&(a.value=a.value.substr(a.value.length-4096));a.value+=(void 0!==c?c+": ":"")+(b||"")+"\n";a.scrollTop=a.scrollHeight}}(c),
|
||||
this.Na=function(a){this.O(a,this.Rd)}),!0;default:return!1}},log:function(){},O:function(){},status:function(a){this.O(this.Rd+": "+a)},Na:function(a,b,c){c=c||this.type;b||w((c?c+": ":"")+a)},ic:function(){return this.la.cc=!0},hc:function(a,b){b&&(this.la.cc=!1);return!0}};function x(a,b,c,d,e,f,g){a.ha&&(!0===g?g=0:null==g&&(g=a.wc),ob(a.ha,a,b,c,d,e,f,g))}function y(a,b,c,d){a.ha&&(!0===c||A(a,c|0))&&a.ha.message(b,d)}
|
||||
|
|
@ -35,7 +35,7 @@ rj:25,oj:20,qj:28,Oj:13,Qj:21,Nj:16,Pj:24,tj:13,vj:21,sj:16,uj:24,Tf:2,Sf:7,Qh:5
|
|||
80:"set current PSP @BX",81:"get current PSP (bx)",82:"get system variables (ES:BX)",83:"translate BPB @DS:@SI to DPB (ES:BP)",84:"get verify flag (AL)",85:"create child PSP at segment @DX",86:"rename file $@DS:@DX to $@ES:@DI",87:"get(0)/set(1) file @BX date @DX and time @CX (@AL)",88:"get(0)/set(1) memory allocation strategy (@AL)",89:"get extended error information",90:"create temporary file $@DS:@DX with attributes @CX",91:"create file $@DS:@DX with attributes @CX",92:"lock(0)/unlock(1) file @BX region @CX:@DX length @SI:@DI (@AL)",
|
||||
93:"critical error information (@AL)",96:"get fully-qualified filename from $@DS:@SI",99:"get lead byte table (@AL)",108:"extended open file $@DS:@SI"},65:{79:"check debugger loaded"}};function zb(a){Ua.call(this,"Panel",a,zb);this.L=this.W=this.fa=-1}db(zb);function Ab(a,b,c,d){this.A=[a,b,c,d];this.B=null;void 0===a&&(this.A[0]=256*Math.random()|0,this.A[1]=256*Math.random()|0,this.A[2]=256*Math.random()|0,this.A[3]=255,this.B=null)}
|
||||
Ab.prototype.toString=function(){this.B||(this.B="#"+r(this.A[0],2)+r(this.A[1],2)+r(this.A[2],2));return this.B};function Bb(a,b,c,d){this.x=a;this.y=b;this.ad=c;this.A=d}Bb.prototype.contains=function(a,b){return a>=this.x&&a<this.x+this.ad&&b>=this.y&&b<this.y+this.A};function Cb(a,b,c,d){void 0===d&&(d=b>=c>>2);d?(b=new Bb(a.x,a.y,a.ad,a.A*b/c|0),a.y+=b.A,a.A-=b.A):(b=new Bb(a.x,a.y,a.ad*b/c|0,a.A),a.x+=b.ad,a.ad-=b.ad);return b}m=zb.prototype;
|
||||
m.Pb=function(a,b,c,d){return this.V&&this.V.Pb(a,b,c,d)||this.F&&this.F.Pb(a,b,c,d)||this.B&&this.B.Pb(a,b,c,d)||this.ha&&this.ha.Pb(a,b,c,d)?!0:this.parent.Pb.call(this,a,b,c,d)};m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.F=c;this.ha=d;this.B=Eb(a,"Keyboard")};m.ic=function(a,b){b||Fb();return!0};m.hc=function(){return!0};m.je=function(a,b){a.button||(this.fa=b?0:-1,Gb(this,a,b))};m.If=function(a){Gb(this,a)};
|
||||
m.Pb=function(a,b,c,d){return this.V&&this.V.Pb(a,b,c,d)||this.F&&this.F.Pb(a,b,c,d)||this.B&&this.B.Pb(a,b,c,d)||this.ha&&this.ha.Pb(a,b,c,d)?!0:this.parent.Pb.call(this,a,b,c,d)};m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.F=c;this.ha=d;this.B=Db(a,"Keyboard")};m.ic=function(a,b){b||Fb();return!0};m.hc=function(){return!0};m.je=function(a,b){a.button||(this.fa=b?0:-1,Gb(this,a,b))};m.If=function(a){Gb(this,a)};
|
||||
function Gb(a,b,c){var d=1280/null.offsetWidth,e=720/null.offsetHeight,f=null.getBoundingClientRect(),d=(b.clientX-f.left)*d|0;b=(b.clientY-f.top)*e|0;null==c&&(a.fa||(a.fa=Math.abs(a.L-d)>Math.abs(a.W-b)?1:2),1==a.fa?b=a.W:2==a.fa&&(d=a.L));a.L=d;a.W=b;if(0<=d&&1280>d&&0<=b&&720>b){a:{c=d;if(960>c&&a.A&&a.A.Qe)for(f=0;f<a.A.Qe.length;f++)if(e=a.A.Qe[f],e.contains(c,b)){c-=e.x;b-=e.y;var d=a.A.Bf[f],g=ta(Hb.ak,a.A.Sg[d.Rk]),f=g*a.ea.Sb,d=(g+d.Vd)*a.ea.Sb-1;0<b&&(f+=e.ad*(b-1)*a.ya);f+=c*a.ya;f|=0;
|
||||
f>d&&(f=d);c=f;break a}c=-1}if(-1!==c&&(c&=-16,c!=a.Ca)){b=c;if(a.context&&a.ia&&a.ka){e=a.ia.width;a.ka.fillStyle="black";a.ka.fillRect(0,360,e,360);Ib(a,378,a.ia,a.ka);a.pa=a.Ea.width/24|0;if(null==b)Jb(a,"Mouse over memory to dump");else for(Jb(a,"0x"+r(b),null,0,1),f=1;16>=f;f++){d="";for(g=1;8>=g;g++){var h;h=a.ea;var k=b++;h=h.sa[(k&h.Hb)>>>h.La].se(k&h.A,k);Jb(a,r(h,2),null,1);d+=32<=h&&128>h?String.fromCharCode(h):"."}Jb(a,d,null,0,1)}a.context.drawImage(a.ia,0,360,e,360,a.rb,a.Db,a.Pa,a.cb)}a.Ca=
|
||||
c}}}m.qd=function(){};function Kb(a,b,c,d){a.A.Bf[a.A.Bi++]={Rk:b,Vd:c,type:d};return sa(Hb,b,c,0,d)}function Ib(a,b,c,d){var e,f=null.style.color,g=a.Oa=10;a.C=g;a.U=b;a.X=a.wa=18;e||(e=a.ua||a.wa+"px Monaco, Lucida Console, Courier New");a.ga=a.ua=e;c&&(a.Ea=c);d&&(a.N=d,a.Fa=f||"white")}
|
||||
|
|
@ -68,7 +68,7 @@ function Gc(a,b){b?0===--a.Ve&&(a.sc=a.N?a.L:a.xf,a.zf=a.N?a.X:a.pi,a.yf=a.N?a.U
|
|||
function Zb(a,b,c){b||(b=5==a.type?Hc:6==a.type?Ic:Jc);zc(a,b,c);Bc(a,b,c)}var Jc=[],ec=[B.prototype.Fa,B.prototype.sb,B.prototype.$a,B.prototype.Rd,B.prototype.Dd,B.prototype.Xc],Ac=[B.prototype.Ea,B.prototype.rb,B.prototype.Pa,B.prototype.tc,B.prototype.td,B.prototype.Wc],Ic=[B.prototype.Ja,B.prototype.Jb,B.prototype.fb,B.prototype.Cc,B.prototype.Hd,B.prototype.ve],Hc=[B.prototype.Ka,B.prototype.Ub,B.prototype.gb,B.prototype.Uc,B.prototype.Id,B.prototype.kd];
|
||||
if(vb)var dc=[B.prototype.Ca,B.prototype.Tb,B.prototype.Oa,B.prototype.bc,B.prototype.rd,B.prototype.Vc],cc=[B.prototype.aa,B.prototype.pa,B.prototype.ga,B.prototype.ra,B.prototype.ya,B.prototype.wa],Kc=[B.prototype.Ia,B.prototype.Db,B.prototype.cb,B.prototype.uc,B.prototype.Gd,B.prototype.jd];
|
||||
function Lc(a,b){Ua.call(this,"CPU",a,Lc,1);var c=a.cycles||b,d=a.multiplier||1;this.Y={};this.Y.Jd=c;this.Y.Zd=d;this.Y.vg=Math.round(this.Y.Jd/1E4)/100;this.Y.Fe=this.Y.vg*this.Y.Zd;this.la.Fb=!1;this.la.fh=!1;this.la.Li=a.autoStart;this.la.Pi=!1;this.la.Ze=!1;this.Y.Jf=this.Y.lf=0;this.Y.Kf=a.csStart;this.Y.kf=a.csInterval;this.Y.mf=a.csStop;this.ri=this.Le.bind(this);rb(this)}db(Lc);var Mc=["power","reset"];m=Lc.prototype;
|
||||
m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.ha=d;for(b=0;b<Mc.length;b++)(c=this.qa[Mc[b]])&&this.V.Pb(null,Mc[b],c);this.Tb=Eb(a,"FPU");this.N=Eb(a,"ChipSet");a=Nc(a,"autoStart");null!=a&&(this.la.Li="true"==a?!0:"false"==a?!1:!!a);rb(this)};m.reset=function(){};m.save=function(){return null};m.restore=function(){return!1};
|
||||
m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.ha=d;for(b=0;b<Mc.length;b++)(c=this.qa[Mc[b]])&&this.V.Pb(null,Mc[b],c);this.Tb=Db(a,"FPU");this.N=Db(a,"ChipSet");a=Nc(a,"autoStart");null!=a&&(this.la.Li="true"==a?!0:"false"==a?!1:!!a);rb(this)};m.reset=function(){};m.save=function(){return null};m.restore=function(){return!1};
|
||||
m.ic=function(a,b){if(!b){if(a&&this.restore){Oc(this);if(!this.restore(a))return!1;Pc(this)}else this.reset();this.ha?this.ha.ih():this.O("No debugger detected")}Rc(this);return!0};m.hc=function(a){return a?this.save():!0};function Uc(a){(a.la.Li||!a.ha&&void 0===a.qa.run)&&a.Le(!0)}m.Ri=function(){return 0};function Pc(a){void 0===a.Y.Kf&&(a.Y.Kf=0);void 0===a.Y.kf&&(a.Y.kf=-1);void 0===a.Y.mf&&(a.Y.mf=-1);a.la.Ze=0<=a.Y.Kf&&0<a.Y.kf;a.la.Ze&&(a.Y.Jf=0,a.Y.lf=a.Y.Kf-a.uc)}
|
||||
function Vc(a,b){if(a.la.Ze){var c=!1;a.Y.Jf=a.Y.Jf+a.Ri()|0;a.Y.lf-=b;0>=a.Y.lf&&(a.Y.lf+=a.Y.kf,c=!0);0<=a.Y.mf&&a.Y.mf<=Wc(a)&&(a.Y.kf=a.Y.mf=-1,Pc(a),a.Wb(),c=!0);c&&a.O(Wc(a)+" cycles: checksum="+r(a.Y.Jf))}}
|
||||
m.Pb=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.qa[b]=c;a=!0;break;case "run":this.qa[b]=c;c.onclick=function(){var a;if(a=d.V)if(a=d.V,a.la.cc)a=!0;else{var b=null,c,h=gb(a.id);for(c=0;c<h.length&&(b=h[c],b===a||b.la.bf);c++);if(c==h.length)for(c=0;c<h.length&&(b=h[c],b===a||b.la.cc);c++);c==h.length&&(b=a);w("The "+b.type+" component ("+b.id+") is not "+(b.la.bf?"powered yet":"ready yet"+(b.tg?" (waiting for notification)":""))+".");a=!1}a&&(d.la.Fb?d.Wb(!0):d.Le(!0))};
|
||||
|
|
@ -95,7 +95,7 @@ d.oa(h+g)));c&&d.jb(h+0,f);d.Za|=8;return!0}m.save=function(){return[this.Z,this
|
|||
function ed(a,b,c,d){void 0===c&&(c=!!(a.F.Za&1));a.cd=!1;if(c)if(a.load=a.ug,a.Xi=a.gm,a.mc=a.Di,a.nc=a.Fi,void 0===d&&(d=!!(a.F.ca&131072)),d)a.load=a.V,a.mc=a.ea,a.nc=a.qa,a.Lb=a.Gc=3,a.ba=a.Oc=2,a.R=a.Ba=65535,a.Ta=65535,a.Zb=a.Ta+1,a.Oc=a.ba,a.Xb=-1,a.df=!1;else{if(!(a.Z&-4))a.mc=a.pg,a.nc=a.qg;else if(a.type&4096){6144==(a.type&6656)&&(a.mc=a.pg);if(a.type&2048||!(a.type&512))a.nc=a.qg;1024==(a.type&3072)&&(a.mc==a.Di&&(a.mc=a.Jk),a.nc==a.Fi&&(a.nc=a.Kk),a.cd=!0);b&&6>a.id&&a.Z&-4&&-1!==a.Xb&&
|
||||
(c=a.Xb+5,d=a.F.Qa(c),d&1||a.F.qc(c,d|1))}b&&(a.Lb=a.Z&3,a.Gc=(a.wb&24576)>>13,80386>a.F.ja||!(a.ext&64)?(a.ba=2,a.R=65535):(a.ba=4,a.R=-1),a.Oc=a.ba,a.Ba=a.R)}else a.load=a.mh,a.Xi=a.hm,a.mc=a.Ei,a.nc=a.Gi,a.Lb=a.Gc=0,a.Xb=-1,a.df=!1}
|
||||
function Ad(a){this.ja=+a.model||8088;var b=a.stepping;this.Uc=this.ja+(b?ca(b,16):0);b=0;switch(this.ja){default:b=4772727;break;case 80286:b=6E6;break;case 80386:b=16E6}Lc.call(this,a,b);this.Zf=61442;this.Cc=1792;this.Xf=28672;this.Dd=4;this.ra=255;this.B=80286<=this.ja?xb:wb;this.X=Bd;this.cg=Cd;this.hg=Dd;this.ig=Ed;if(80186<=this.ja&&(this.X=Bd.slice(),this.cg=Cd.slice(),this.hg=Dd.slice(),this.ra=31,this.X[15]=Fd,this.X[96]=Gd,this.X[97]=Hd,this.X[98]=Id,this.X[99]=Fd,this.X[100]=Fd,this.X[101]=
|
||||
Fd,this.X[102]=Fd,this.X[103]=Fd,this.X[104]=Jd,this.X[105]=Kd,this.X[106]=Ld,this.X[107]=Md,this.X[108]=Nd,this.X[109]=Od,this.X[110]=Pd,this.X[111]=Qd,this.X[192]=Rd,this.X[193]=Sd,this.X[200]=Td,this.X[201]=Xd,this.X[241]=Yd,this.cg[7]=Zd,this.hg[7]=Zd,80286<=this.ja)){this.Zf=2;this.Cc|=28672;this.Dd=0;this.X[15]=$d;this.tc=fe.slice();for(a=0;a<this.tc.length;a++)this.tc[a]||(this.tc[a]=ge);this.X[84]=he;this.X[99]=ie;if(80386<=this.ja){var c;this.Xf=0;this.Cc|=196608;this.X[100]=je;this.X[101]=
|
||||
Fd,this.X[102]=Fd,this.X[103]=Fd,this.X[104]=Jd,this.X[105]=Kd,this.X[106]=Ld,this.X[107]=Md,this.X[108]=Nd,this.X[109]=Od,this.X[110]=Pd,this.X[111]=Qd,this.X[192]=Rd,this.X[193]=Sd,this.X[200]=Td,this.X[201]=Ud,this.X[241]=Yd,this.cg[7]=Zd,this.hg[7]=Zd,80286<=this.ja)){this.Zf=2;this.Cc|=28672;this.Dd=0;this.X[15]=$d;this.tc=ae.slice();for(a=0;a<this.tc.length;a++)this.tc[a]||(this.tc[a]=ge);this.X[84]=he;this.X[99]=ie;if(80386<=this.ja){var c;this.Xf=0;this.Cc|=196608;this.X[100]=je;this.X[101]=
|
||||
ke;this.X[102]=le;this.X[103]=me;for(c in M)this.tc[+c]=M[c];80546<=this.Uc&&80562>=this.Uc&&(this.tc[166]=ne,this.tc[167]=oe)}}this.Id=[];this.le=[];this.ne=0;Oc(this);this.la.Xd=this.la.Ni=!1;this.Qg=0;this.ld=this.sa=[];this.La=this.Sb=this.Fa=this.Gd=this.jd=this.Hb=this.Db=0;pe(this)}db(Ad,Lc);function qe(a,b,c,d){Gc((d?a.ld:a.sa)[b>>>a.La],c);d&&Ub(a)}
|
||||
function re(a){var b;if(a.sa===a.ld){a.sa=Array(a.Gd);a.me=new B(null,0,0,5,null,a);Mb(a.me,a.ha);for(b=0;b<a.Gd;b++)a.sa[b]=a.me;a.kd=new B;a.bg=Array(512);a.oe=0}else for(var c=0;c<a.Hd.length;c++){b=a.Hd[c];var d=a.sa[b];512>a.oe&&(a.bg[a.oe++]=d);a.sa[b]=a.me}a.Hd=[]}function Ub(a){a.Za&-2147483648&&re(a)}
|
||||
function Fc(a,b,c,d){var e=(b&-4194304)>>>20,f=a.ld[(a.Pd+e&a.Hb)>>>a.La],g=f.Nd(e);if(!(g&1))return d||se.call(a,b,!1,c),a.kd;if(!(g&4)&&3==a.pa)return d||se.call(a,b,!0,c),a.kd;var h=(b&4190208)>>>10,g=a.ld[((g&-4096)+h&a.Hb)>>>a.La],k=g.Nd(h);if(!(k&1))return d||se.call(a,b,!1,c),a.kd;if(!(k&4)&&3==a.pa)return d||se.call(a,b,!0,c),a.kd;c=a.ld[((k&-4096)+(b&4095)&a.Hb)>>>a.La];if(d)return c;d=b>>>a.La;k=a.sa[d];b=b&-4096;var l;0<a.oe?(l=a.bg[--a.oe],l.ih(b)):l=new B(b,0,0,6);b=l;b.Cd=c;b.yb=f;b.A=
|
||||
|
|
@ -133,7 +133,7 @@ m.qd=function(a){this.Qg&&(a||!this.la.Fb||this.la.Pi)&&(Sf(this,"EAX",this.G),S
|
|||
m.wf=function(a){this.la.Xd=!0;var b=this.la.Ni=this.ha&&Tf(this.ha),c=a?this.la.fh?0:1:-1;this.la.fh=!1;this.fb=this.A=a;this.N&&!a&&ad(this.N);a||A(this,1024)||(this.S|=4);do{var d=this.S&3312;if(d)this.Ha|=d;else if(this.re=this.Ga,this.ka=this.vb,this.Ka=this.ta,this.D=this.C=-1,this.Ha&3072&&Se(this),this.Ha=this.S&256,this.ua){a:{if(!(this.S&4))for(var d=80286>this.ja?0:1,e=0;2>e;e++){switch(d){case 0:if(this.ua&1&&this.ca&512){var f=Uf(this.N);if(-1<=f&&(this.ua&=-2,0<=f)){this.ua&=-5;Vf.call(this,
|
||||
f);d=!0;break a}}break;case 1:if(this.ua&2){this.ua&=-3;80386<=this.ja&&(this.Ja[6]|=16384);Vf.call(this,1);d=!0;break a}}d=1-d}d=!1}if(d&&!a){this.O("interrupt dispatched");this.S=0;break}if(this.ua&4){this.S=this.A=0;break}}if(b){if(Wf(this.ha,this.Ga,c)){this.Wb();break}c=1}this.S=0;this.X[this.xa()].call(this)}while(0<this.A);return this.la.Xd?this.fb-this.A:void 0===this.la.Xd?0:-1};Qa(function(){for(var a=nb(document,"pcx86","cpu"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new Ad(d);mb(d,c)}});
|
||||
function Xf(a){Ua.call(this,"FPU",a,Xf);this.ja=a.model||8087;(a=a.stepping)&&ca(a,16);this.V=new Float64Array(8);this.aa=new Int32Array(this.V.buffer);this.pa=new Float32Array(1);this.ua=new Int32Array(this.pa.buffer);this.X=new Float64Array(1);this.L=new Int32Array(this.X.buffer);this.ea=Array(3);this.fa=this.ga=-1;this.W=this.U=this.ia=this.A=0;this.ka=new Float64Array(1);this.ra=new Int32Array(this.ka.buffer);this.ra[0]=0;this.ra[1]=268402688;Yf(this)}db(Xf);m=Xf.prototype;
|
||||
m.Ic=function(a,b,c){this.F=c;this.N=Eb(a,"ChipSet");rb(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)Yf(this);else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.save=function(){var a=new hf(this),b=[],c=0;b[c++]=this.jc;b[c++]=Zf(this);b[c++]=$f(this);for(var d=0;d<this.V.length;d++)b[c++]=this.V[d];N(a,0,b);return a.data()};
|
||||
m.Ic=function(a,b,c){this.F=c;this.N=Db(a,"ChipSet");rb(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)Yf(this);else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.save=function(){var a=new hf(this),b=[],c=0;b[c++]=this.jc;b[c++]=Zf(this);b[c++]=$f(this);for(var d=0;d<this.V.length;d++)b[c++]=this.V[d];N(a,0,b);return a.data()};
|
||||
m.restore=function(a){a=a[0];var b=0;this.jc=a[b++]&-57409;var c=a[b++];this.ma=c&-14337;this.B=(c&14336)>>11;ag(this);bg(this,a[b++]);for(c=0;c<this.V.length;c++)this.V[c]=a[b++];return!0};function Yf(a){a.C=0;a.jc=959;a.ma=0;a.B=0;a.N&&(a=a.N,a.ja>=cg&&dg(a,13))}function ag(a){a.ma&=-129;a.ma&~a.jc&63&&(a.ma|=128);if(a.ma&128&&!(a.jc&128))return a=a.N,a.ja>=cg?eg(a,13):a.ya&0||Vf.call(a.F,2),!0;a=a.N;a.ja>=cg&&dg(a,13);return!1}function fg(a,b){80387<=a.ja||(b&=-65);a.ma|=b;return ag(a)}
|
||||
function Zf(a){return a.ma|a.B<<11}function gg(a,b){return isFinite(b)?!0:!fg(a,Infinity===b?8:16)}function hg(a,b,c){var d=null;null!=b&&null!=c&&(d=b+c,gg(a,d)||(d=null));return d}function ig(a,b,c){var d=null;null!=b&&null!=c&&(d=b-c,gg(a,d)||(d=null));return d}function jg(a,b,c){var d=null;null!=b&&null!=c&&(d=b*c,gg(a,d)||(d=null));return d}function kg(a,b,c){var d=null;null==b||null==c||!c&&fg(a,2)||(d=b/c,gg(a,d)||(d=null));return d}
|
||||
function lg(a,b,c){if(null!=b&&null!=c){var d=0;isNaN(b)||isNaN(c)?d=17664:(b-=c,0>b?d=256:0===b&&(d=16384));a.ma=a.ma&-18177|d;return!0}return!1}function mg(a,b,c){if(null==b)return null;var d=a.jc&3072;0==d?(d=Math.round(b),.5===d-b&&d%2&&d--):d=1024==d||3072==d&&0<b?Math.floor(b):Math.ceil(b);if(c){if(d>=c){if(fg(a,1))return null;d=-c}else if(d<-c){if(fg(a,1))return null;d=-c}a.L[0]=d|0;2147483648<c&&(a.L[1]=d/4294967296|0,!a.L[1]&&0>d&&(a.L[1]=-1))}return d}
|
||||
|
|
@ -288,7 +288,7 @@ function Ij(){var a=this.T();pf(this)||sf(this)?(O(this,K(this)+a),this.A-=this.
|
|||
function Nj(){var a=this.T();qf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)}function Oj(){var a=this.T();!tf(this)!=!uf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb}function Pj(){var a=this.T();!tf(this)==!uf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb}function Qj(){var a=this.T();sf(this)||!tf(this)!=!uf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb}
|
||||
function Rj(){var a=this.T();sf(this)||!tf(this)!=!uf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)}function Sj(){this.Jb.call(this,Tj,this.xa);this.A-=-1===this.C?1:this.B.Eg}function Uj(){this.S|=1;this.$a.call(this,bi)}function Vj(){this.S|=1;this.fa.call(this,bi)}function Wj(){this.Oa.call(this,bi)}function Xj(){this.W.call(this,bi)}function Rd(){this.Jb.call(this,Yj,tj)}function Sd(){this.ya.call(this,2==this.ba?Zj:ak,tj)}
|
||||
function bk(){var a=Rf(this),b=D(this);O(this,b);a&&G(this,I(this)+a);this.A-=this.B.Yj}function ck(){var a=D(this);O(this,a);this.A-=this.B.Vj}function Td(){this.U=this.ga;var a=Rf(this),b=this.xa()&31;this.A-=11;J(this,this.P);var c=I(this)&this.R;if(0<b){for(this.A-=(b<<2)+(1<b?1:0);--b;)this.P=this.P&~this.R|this.P-this.ba&this.R,J(this,nd(this,this.ta,this.P&this.R));J(this,c)}this.P=this.P&~this.R|c;G(this,I(this)&~this.ta.Ba|I(this)-a&this.ta.Ba);this.U=-1}
|
||||
function Xd(){this.U=this.ga;G(this,I(this)&~this.ta.Ba|this.P&this.ta.Ba);this.P=this.P&~this.R|D(this)&this.R;this.A-=5;this.U=-1}function dk(){yj.call(this,Rf(this));this.A-=this.B.Xj}function ek(){yj.call(this,0);this.A-=this.B.Wj}function fk(a){this.jg=a;this.W.call(this,Lh)}function gk(){this.S|=36;this.A-=this.B.od}function Yd(){ge.call(this)}function Fd(){C.call(this,6)}
|
||||
function Ud(){this.U=this.ga;G(this,I(this)&~this.ta.Ba|this.P&this.ta.Ba);this.P=this.P&~this.R|D(this)&this.R;this.A-=5;this.U=-1}function dk(){yj.call(this,Rf(this));this.A-=this.B.Xj}function ek(){yj.call(this,0);this.A-=this.B.Wj}function fk(a){this.jg=a;this.W.call(this,Lh)}function gk(){this.S|=36;this.A-=this.B.od}function Yd(){ge.call(this)}function Fd(){C.call(this,6)}
|
||||
function ge(){O(this,this.re-this.va.Aa);ub(this,"Undefined opcode "+t(this.Qa(this.Ga))+" at "+("0x"+r(this.Ga)));this.Wb()}
|
||||
var Bd=[function(){this.$a.call(this,th)},function(){this.fa.call(this,uh)},function(){this.Oa.call(this,th)},function(){this.W.call(this,uh)},function(){this.G=this.G&-256|th.call(this,this.G&255,this.xa());this.A--},function(){this.G=this.G&~this.R|uh.call(this,this.G&this.R,this.Ma());this.A--},function(){od(this,this.Xa.Z,this.ba,2);this.A-=this.B.Ie},function(){this.U=this.ga;vd(this,D(this));this.A-=this.B.zc;this.U=-1},function(){this.$a.call(this,gi)},function(){this.fa.call(this,hi)},function(){this.Oa.call(this,
|
||||
gi)},function(){this.W.call(this,hi)},function(){this.G=this.G&-256|gi.call(this,this.G&255,this.xa());this.A--},function(){this.G=this.G&~this.R|hi.call(this,this.G&this.R,this.Ma());this.A--},function(){od(this,this.va.Z,this.ba,2);this.A-=this.B.Ie},function(){kf(this,D(this));this.A-=this.B.zc},function(){this.$a.call(this,rh)},function(){this.fa.call(this,sh)},function(){this.Oa.call(this,rh)},function(){this.W.call(this,sh)},function(){this.G=this.G&-256|rh.call(this,this.G&255,this.xa());this.A--},
|
||||
|
|
@ -338,9 +338,9 @@ a,this.G),c=this.wa!=this.ia>>31);c?(wf(this),yf(this)):(xf(this),zf(this));this
|
|||
a;var c=a<<16>>16,d=(b=this.M<<16|this.G&65535)/c|0;if(d!=d<<16>>16||8086==this.ja&&-32768==d)return Aj.call(this),a;this.ia=d&65535;this.wa=b%c&65535}else{var c=this.G,d=this.M,e=a,f=0,g=0;0>e&&(e=-e|0,f=1-f);0>d&&(c=-c|0,d=~d+(c?0:1)|0,g=1,f=1-f);!nj.call(this,c,d,e)||this.ia>2147483647+f||this.wa>2147483647+g?c=!1:(f&&(this.ia=-this.ia),g&&(this.wa=-this.wa),c=!0);if(!c)return Aj.call(this),a;this.ia|=0;this.wa|=0}this.cb=!0;this.A-=-1===this.D?this.B.rj:this.B.qj;this.S|=2;return a}],Cd=[function(a){var b=
|
||||
a+1|0;of(this,a,1,b,190);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&255},function(a){var b=a-1|0;of(this,a,1,b,190,!0);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&255},Nh,Nh,Nh,Nh,Nh,Nh],Dd=[function(a){var b=a+1|0;of(this,a,1,b,this.Ia|62);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&this.R},function(a){var b=a-1|0;of(this,a,1,b,this.Ia|62,!0);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&this.R},function(a){J(this,K(this));O(this,a);this.A-=-1===this.D?this.B.jj:this.B.ij;this.S|=
|
||||
2;return a},function(a){if(-1===this.D)return Nh.call(this,a);this.U=this.ga;wj.call(this,a,this.na(this.D+this.ba));this.A-=this.B.gj;this.S|=2;this.U=-1;return a},function(a){O(this,a);this.A-=-1===this.D?this.B.Ej:this.B.Dj;this.S|=2;return a},function(a){if(-1===this.D)return Nh.call(this,a);yd(this,a,this.na(this.D+this.ba));this.A-=this.B.Bj;this.S|=2;return a},function(a){var b=a;this.S&512&&(a=a-2&65535,80286>this.ja&&(b=a));J(this,b);this.A-=-1===this.D?this.B.Sc:this.B.Uj;this.S|=2;return a},
|
||||
Nh];function ne(){this.W.call(this,gj);this.A-=-1===this.D?6:13}function oe(){this.fa.call(this,fj);this.A-=-1===this.D?12:19}var fe=Array(256);fe[0]=function(){16>(this.Qa(this.Ga)&56)&&(this.S|=1);this.ya.call(this,this.ig,uj)};fe[1]=function(){this.Qa(this.Ga)&16||(this.S|=1);this.ya.call(this,nk,uj)};fe[2]=function(){!(this.Za&1)||this.ca&131072?C.call(this,6):this.W.call(this,Uh)};fe[3]=function(){!(this.Za&1)||this.ca&131072?C.call(this,6):this.W.call(this,$h)};
|
||||
fe[5]=function(){this.pa?C.call(this,13,0,0,!0):(Gf(this,this.na(2054)),this.J=this.na(2086),this.K=this.na(2088),this.P=this.na(2090),this.H=this.na(2094),this.M=this.na(2096),this.I=this.na(2098),this.G=this.na(2100),id(this.Xa,2102,this.na(2084)),id(this.va,2108,this.na(2082)),id(this.ta,2114,this.na(2080)),id(this.vb,2120,this.na(2078)),xd(this,this.na(2072)),O(this,this.na(2074)),G(this,this.na(2092)),this.Ec=this.na(2126)|this.Qa(2128)<<16,this.Ad=this.Ec+this.na(2130),this.Mc=this.na(2138)|
|
||||
this.Qa(2140)<<16,this.Ud=this.Mc+this.na(2142),id(this.Bc,2132,this.na(2076)),id(this.Sa,2144,this.na(2070)),this.A-=195)};fe[6]=function(){this.pa?C.call(this,13,0):(this.Za&=-9,this.A-=2)};fe[11]=Fd;fe[166]=Fd;fe[255]=Fd;var M=[];M[5]=Fd;
|
||||
Nh];function ne(){this.W.call(this,gj);this.A-=-1===this.D?6:13}function oe(){this.fa.call(this,fj);this.A-=-1===this.D?12:19}var ae=Array(256);ae[0]=function(){16>(this.Qa(this.Ga)&56)&&(this.S|=1);this.ya.call(this,this.ig,uj)};ae[1]=function(){this.Qa(this.Ga)&16||(this.S|=1);this.ya.call(this,nk,uj)};ae[2]=function(){!(this.Za&1)||this.ca&131072?C.call(this,6):this.W.call(this,Uh)};ae[3]=function(){!(this.Za&1)||this.ca&131072?C.call(this,6):this.W.call(this,$h)};
|
||||
ae[5]=function(){this.pa?C.call(this,13,0,0,!0):(Gf(this,this.na(2054)),this.J=this.na(2086),this.K=this.na(2088),this.P=this.na(2090),this.H=this.na(2094),this.M=this.na(2096),this.I=this.na(2098),this.G=this.na(2100),id(this.Xa,2102,this.na(2084)),id(this.va,2108,this.na(2082)),id(this.ta,2114,this.na(2080)),id(this.vb,2120,this.na(2078)),xd(this,this.na(2072)),O(this,this.na(2074)),G(this,this.na(2092)),this.Ec=this.na(2126)|this.Qa(2128)<<16,this.Ad=this.Ec+this.na(2130),this.Mc=this.na(2138)|
|
||||
this.Qa(2140)<<16,this.Ud=this.Mc+this.na(2142),id(this.Bc,2132,this.na(2076)),id(this.Sa,2144,this.na(2070)),this.A-=195)};ae[6]=function(){this.pa?C.call(this,13,0):(this.Za&=-9,this.A-=2)};ae[11]=Fd;ae[166]=Fd;ae[255]=Fd;var M=[];M[5]=Fd;
|
||||
M[7]=function(){if(this.pa)C.call(this,13,0,0,!0);else{var a=this.Xa.mc(this.J&this.Ba,204);if(-1!==a){pj.call(this,this.oa(a));var b=this.oa(a+168),c=(b&24576)>>13;xd(this,this.oa(a+4),c);this.Ec=this.oa(a+112);this.Ad=this.Ec+this.oa(a+116);this.Mc=this.oa(a+100);this.Ud=this.Mc+this.oa(a+104);hd(this.Bc,this.oa(a+56),this.oa(a+120),this.oa(a+124),this.oa(a+128));hd(this.Sa,this.oa(a+52),this.oa(a+84),this.oa(a+88),this.oa(a+92));this.J=this.oa(a+12);this.K=this.oa(a+16);this.P=this.oa(a+20);this.H=
|
||||
this.oa(a+28);this.M=this.oa(a+32);this.I=this.oa(a+36);this.G=this.oa(a+40);hd(this.Ob,this.oa(a+60),this.oa(a+132),this.oa(a+136),this.oa(a+140));hd(this.Nb,this.oa(a+64),this.oa(a+144),this.oa(a+148),this.oa(a+152));hd(this.vb,this.oa(a+68),this.oa(a+156),this.oa(a+160),this.oa(a+164));hd(this.ta,this.oa(a+72),b,this.oa(a+172),this.oa(a+176));hd(this.va,this.oa(a+76),this.oa(a+180),this.oa(a+184),this.oa(a+188));hd(this.Xa,this.oa(a+80),this.oa(a+192),this.oa(a+196),this.oa(a+200));O(this,this.oa(a+
|
||||
8));G(this,this.oa(a+24))}this.A-=122<<(a&3?1:0)}};M[16]=Uj;M[17]=Vj;M[18]=Wj;M[19]=Xj;M[32]=function(){if(this.pa)C.call(this,13,0);else{var a,b=this.xa();switch((b&56)>>3){case 0:a=this.Za;break;case 2:a=this.te;break;case 3:a=this.Pd;break;default:ge.call(this);return}ve(this,b&7,a);this.A-=6}};M[33]=function(){if(this.pa)C.call(this,13,0);else{var a=this.xa(),b=(a&56)>>3;4==b||5==b?ge.call(this):(ve(this,a&7,this.Ja[b]),this.A-=22)}};
|
||||
|
|
@ -367,7 +367,7 @@ window.webkitAudioContext),this.sb&&(this.Fa=new this.sb));this.reset(!0);rb(thi
|
|||
Ak[5150][0][wk]={Lc:48,hd:{0:0,1:16,2:32,3:48,none:0,tv:16,color:32,cga:32,mda:48,mono:48,ega:0,vga:0},Qd:"Monitor Type"};Ak[5150][0][5]={Lc:12,hd:{16:0,32:4,48:8,64:12},Qd:"Base Memory (16Kb Increments)"};Ak[5150][1][6]={Lc:31,hd:{0:0,32:1,64:2,96:3,128:4,160:5,192:6,224:7,256:8,288:9,320:10,352:11,384:12,416:13,448:14,480:15,512:16,544:17,576:18},Qd:"Expansion Memory (32Kb Increments)"};Ak[5160]=[{},{}];Ak[5160][0][vk]=Ak[5150][0][vk];Ak[5160][0][3]=Ak[5150][0][3];Ak[5160][0][wk]=Ak[5150][0][wk];
|
||||
Ak[5160][0][5]={Lc:12,hd:{64:0,128:4,192:8,256:12},Qd:"Base Memory (64Kb Increments)"};Ak[5160][1][6]=Ak[5150][1][6];Ak[5160.101]=[{},{}];Ak[5160.101][0][5]={Lc:143,hd:{128:1,256:130,512:8,640:141},Qd:"Base Memory (128Kb Increments)"};Ak[5160.101][0][3]={Lc:16,hd:{0:0,1:16},Qd:"Coprocessor"};Ak[5160.101][1][2]={Lc:1,hd:{0:0,1:1},Qd:"Floppy Type"};Ak[5160.101][1][vk]=Ak[5150][0][vk];Ak[5160.101][1][wk]=Ak[5150][0][wk];m=pk.prototype;
|
||||
m.Pb=function(a,b,c){switch(b){case tk:return this.qa[b]=c,Bk(this,0,b),!0;case xk:if(5150==(this.ja|0)||5160.101==this.ja)return this.qa[b]=c,Bk(this,1,b),!0;break;case "swdesc":return this.qa[b]=c,!0}return!1};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.V=a;this.Tb=Eb(a,"FPU");uk(this,3,this.Tb?1:0,!0);this.B=Eb(a,"Keyboard");this.gb=c.Y.Jd/1193181;ic(b,this,Ck);mc(b,this,Dk);this.ja<cg?5160.101!=this.ja?(ic(b,this,Ek),mc(b,this,Fk)):(ic(b,this,Gk),mc(b,this,Hk)):(ic(b,this,Ik),mc(b,this,Jk),5180==(this.ja|0)&&(ic(b,this,Kk),mc(b,this,Lk)));if(d){var e=this;Mk(d,1024,function(){for(var a=0;a<e.vc.length;a++){for(var b=e.vc[a],c="PIC"+a+":",d=0;d<b.Yc.length;d++)c+=" IC"+(d+1)+"="+t(b.Yc[d]);
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.V=a;this.Tb=Db(a,"FPU");uk(this,3,this.Tb?1:0,!0);this.B=Db(a,"Keyboard");this.gb=c.Y.Jd/1193181;ic(b,this,Ck);mc(b,this,Dk);this.ja<cg?5160.101!=this.ja?(ic(b,this,Ek),mc(b,this,Fk)):(ic(b,this,Gk),mc(b,this,Hk)):(ic(b,this,Ik),mc(b,this,Jk),5180==(this.ja|0)&&(ic(b,this,Kk),mc(b,this,Lk)));if(d){var e=this;Mk(d,1024,function(){for(var a=0;a<e.vc.length;a++){for(var b=e.vc[a],c="PIC"+a+":",d=0;d<b.Yc.length;d++)c+=" IC"+(d+1)+"="+t(b.Yc[d]);
|
||||
c+=" IMR="+t(b.Bd)+" IRR="+t(b.lc)+" ISR="+t(b.Pc)+" DELAY="+b.of;e.ha.O(c)}});Mk(d,2048,function(a){a=(a=a[0])?+a:null;for(var b=0;b<e.W.length;b++)if(null==a||b==a){Nk(e,b);var c=e.W[b],d="TIMER"+b+":",l=0;if(null!=c.nd)for(var n=0;n<=c.nd;n++)l|=c.Ab[n]<<8*n;d+=" mode="+(c.mode>>1)+" bytes="+c.nd+" count="+u(l);e.ha.O(d)}});Mk(d,4096,function(){for(var a="",b=0;64>b;b++){var c=13>=b?Ok(e,b):e.A[b];a&&(a+="\n");a+="CMOS["+t(b)+"]: "+t(c)}e.ha.O(a)})}Te(c,26,this.bm.bind(this))};
|
||||
m.ic=function(a,b){if(!b)if(!a)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};
|
||||
m.reset=function(a){var b;Pk(this);this.L=Array(this.cb);for(b=0;b<this.cb;b++)Qk(this,b);this.vc=Array(this.Ea);Rk(this,0,32);1<this.Ea&&Rk(this,1,160);this.Pa=this.Oa=null;this.W=Array(5180==(this.ja|0)?6:3);for(b=0;b<this.W.length;b++)Sk(this,b);this.Ca=this.rb=this.X=this.$a=null;this.ya=0;5160.101==this.ja&&(this.wa=0);if(this.ja>=cg){this.N=16;this.fa=0;this.aa=16;this.Ja=0;this.ga=160;512<=Tk(this)&&(this.ga|=16);3==+Uk(this,wk,void 0)&&(this.ga|=64);5180==(this.ja|0)&&(this.ga|=12);this.Ka=
|
||||
|
|
@ -431,7 +431,7 @@ Zl.prototype.ic=function(){this.Sd&&(this.ha&&bm(this.ha,this.id,0,this.V>>>4,0,
|
|||
function $l(a,b,c,d){if(d)a.Na("Unable to load system ROM (error "+d+": "+b+")");else{fb(a.ve,b,c);if("["==c.charAt(0)||"{"==c.charAt(0))try{var e=eval("("+c+")"),f=e.bytes,g=e.data;if(f)a.A=f;else if(g)for(a.A=Array(4*g.length),d=c=0;c<g.length;c++)a.A[d++]=g[c]&255,a.A[d++]=g[c]>>8&255,a.A[d++]=g[c]>>16&255,a.A[d++]=g[c]>>24&255;else a.A=e;a.Sd=e.symbols;if(!a.A.length){w("Empty ROM: "+b);return}if(1==a.A.length){w(a.A[0]);return}}catch(h){a.Na("ROM data error: "+h.message);return}else for(b=c.replace(/\n/gm,
|
||||
" ").replace(/ +$/,"").split(" "),a.A=Array(b.length),e=0;e<b.length;e++)a.A[e]=ca(b[e],16);am(a)}}
|
||||
function am(a){if(!sb(a))if(!a.L)rb(a);else if(a.A&&a.ea){a.C||(a.C=a.A.length);if(a.A.length!=a.C)ub(a,"ROM size (0x"+r(a.A.length)+") does not match specified size ("+("0x"+r(a.C))+")");else{var b;b=a.V;if(Sb(a.ea,b,a.C,ac)){for(var c=0;c<a.A.length;c++){var d=a.ea,e=b+c;d.sa[(e&d.Hb)>>>d.La].xf(e&d.A,a.A[c]&255,e)}b=!0}else b=!1;if(b){b=[];"number"==typeof a.N?b.push(a.N):null!=a.N&&a.N.length&&(b=a.N);for(c=0;c<b.length;c++){var d=a,e=b[c],f=Yb(d.ea,d.V,d.C);Xb(d.ea,e,d.C,f)}a.B&&((b=hb(a.B,a.id))?
|
||||
(c=a.A,d=a.W,5==b.Ua?cm(b,c,d||[12640,8752],8):b.Ua==dm&&cm(b,c,d||[14221,16269],8),rb(b)):a.Na("Unable to find component: "+a.B));delete a.A}}rb(a)}}Qa(function(){for(var a=nb(document,"pcx86","rom"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new Zl(d);mb(d,c)}});function em(a){Ua.call(this,"RAM",a,em);this.B=a.addr;this.A=a.size;this.L=a.test;this.V=!!this.A;this.C=!1}db(em);m=em.prototype;m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.N=Eb(a,"ChipSet");rb(this)};
|
||||
(c=a.A,d=a.W,5==b.Ua?cm(b,c,d||[12640,8752],8):b.Ua==dm&&cm(b,c,d||[14221,16269],8),rb(b)):a.Na("Unable to find component: "+a.B));delete a.A}}rb(a)}}Qa(function(){for(var a=nb(document,"pcx86","rom"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new Zl(d);mb(d,c)}});function em(a){Ua.call(this,"RAM",a,em);this.B=a.addr;this.A=a.size;this.L=a.test;this.V=!!this.A;this.C=!1}db(em);m=em.prototype;m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.N=Db(a,"ChipSet");rb(this)};
|
||||
m.ic=function(a,b){return!b&&(this.reset(),a&&this.controller&&!this.restore(a))?!1:!0};m.hc=function(a){return a&&this.controller?this.save():!0};
|
||||
m.reset=function(){if(!this.B&&!this.V&&this.N){var a=1024*Tk(this.N);this.A&&a!=this.A&&($b(this.ea,this.B,this.A),this.C=!1);this.A=a}!this.C&&this.A&&Sb(this.ea,this.B,this.A,1)&&(this.C=!0,"ramCPQ"==this.Rd&&(this.controller=new fm(this),Sb(this.ea,gm,4,4,this.controller)));if(this.C){if(this.L||gc(this.ea,1138,4660),"ramCPQ"!=this.Rd&&this.N&&(a=this.N,a.A)){var b=1048576>this.B?21:23,c=a.A[b]|a.A[b+1]<<8,c=c+(this.A>>10);a.A[b]=c&255;a.A[b+1]=c>>8;Xk(a)}}else w("No RAM allocated")};
|
||||
m.save=function(){var a=new hf(this);this.controller&&N(a,0,this.controller.save());return a.data()};m.restore=function(a){return this.controller?this.controller.restore(a[0]):!0};function fm(a){this.N=a;this.C=hm;this.ha=im;this.B=jm;this.A=null}var gm=-2134900736,hm=65535,im=2575,jm=2,km=[null,0],lm=[function(a){return this.controller.Qa(a)},null,null,function(a,b){this.controller.qc(a,b)},null,null];m=fm.prototype;m.save=function(){return[this.C,this.B]};
|
||||
|
|
@ -448,7 +448,7 @@ Y[107]=37;Y[75]=10789;Y[108]=38;Y[76]=10790;Y[X[";"]]=39;Y[X[":"]]=10791;Y[X["'"
|
|||
Y[1115]=62;Y[1116]=63;Y[1117]=64;Y[1118]=65;Y[1119]=66;Y[1120]=67;Y[1121]=68;Y[1144]=69;Y[1145]=70;Y[1036]=71;Y[1038]=72;Y[1033]=73;Y[1109]=74;Y[1037]=75;Y[1101]=76;Y[1039]=77;Y[1107]=78;Y[1035]=79;Y[1040]=80;Y[1034]=81;Y[1045]=82;Y[1046]=83;Y[4027]=84;Y[1122]=87;Y[1123]=88;Y[1091]=91;Y[1093]=93;Y[1224]=91;Y[4003]=7470;Y[4008]=7494;Y[4046]=3677523;Y[4045]=3677522;Y[4013]=3677468;m=mm.prototype;
|
||||
m.Pb=function(a,b,c,d){var e=this,f=a+"-"+b;if(void 0===this.qa[f])switch(b){case "kbd":return c.onkeydown=function(a){return vm(e,a,!0)},c.onkeypress=function(a){a=a||window.event;a=a.which||a.keyCode;e.L="";var b=!Y[a]||!!(e.xc&128);b||wm(e,a,!0);return b},c.onkeyup=function(a){return vm(e,a,!1)},!0;case "caps-lock":return this.qa[f]=c,c.onclick=function(){e.V&&e.V.yd();wm(e,1020,!0)},!0;case "num-lock":return this.qa[f]=c,c.onclick=function(){e.V&&e.V.yd();wm(e,1144,!0)},!0;case "scroll-lock":return this.qa[f]=
|
||||
c,c.onclick=function(){e.V&&e.V.yd();wm(e,1145,!0)},!0;default:var g=b.toUpperCase().replace(/-/g,"_");if(void 0!==sm[g]&&"button"==a)return this.qa[f]=c,c.onclick=function(a,b,c){return function(){a.V&&a.V.yd();xm(a,c,!0);wm(a,c,!0)}}(this,g,sm[g]),!0;if(void 0!==tm[b])return this.ga++,this.qa[f]=c,a=function(a,b,c){return function(){wm(a,c)}}(this,b,tm[b]),b=function(a,b,c){return function(){ym(a,c)}}(this,b,tm[b]),"ontouchstart"in window?(c.ontouchstart=a,c.ontouchend=b):(c.onmousedown=a,c.onmouseup=
|
||||
c.onmouseout=b),!0;if(d)return this.qa[f]=c,c.onclick=function(){e.V&&e.V.yd();d&&!e.L&&(e.L=d,zm(e,300))},!0}return!1};function Am(a,b,c){if(a.ga){for(var d in qm)if(b==qm[d]){b=+d;(d=pm[d])&&(b=d);break}for(var e in tm)if((d=tm[e]==b)||(d=b,97<=d&&122>=d&&(d-=32),d=tm[e]==d),d){(a=a.qa["key-"+e])&&void 0!==c&&(a.style.color=c?"#ffffff":"#000000",a.style.backgroundColor=c?"#000000":"#ffffff");break}}}m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.F=c;this.ha=d;this.N=Eb(a,"ChipSet")};
|
||||
c.onmouseout=b),!0;if(d)return this.qa[f]=c,c.onclick=function(){e.V&&e.V.yd();d&&!e.L&&(e.L=d,zm(e,300))},!0}return!1};function Am(a,b,c){if(a.ga){for(var d in qm)if(b==qm[d]){b=+d;(d=pm[d])&&(b=d);break}for(var e in tm)if((d=tm[e]==b)||(d=b,97<=d&&122>=d&&(d-=32),d=tm[e]==d),d){(a=a.qa["key-"+e])&&void 0!==c&&(a.style.color=c?"#ffffff":"#000000",a.style.backgroundColor=c?"#000000":"#ffffff");break}}}m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.F=c;this.ha=d;this.N=Db(a,"ChipSet")};
|
||||
function nm(a,b){var c=0;a.ja=null;"string"==typeof b&&(a.ja=b.toUpperCase(),c=om.indexOf(a.ja),0>c&&(c=0));if(b=om[c])a.ra=parseInt(b.substr(2),10)}function Tl(a){y(a,"keyboard reset",65792);a.A=[];Ul(a,170)}function Pl(a,b,c){a.aa!==c&&(a.aa=a.fa=c)&&(a.U=!0);a.X!==b&&(a.X=b)&&!a.fa&&Xl(a,!0);a.X&&a.fa&&(Tl(a),a.fa=!1)}function Ul(a,b){a.N&&(a.A.unshift(b),a.U=!0,Wl(a.N,b))}
|
||||
function Ql(a){var b=0;a.A.length&&a.U&&(b=a.A[0],a.N&&Wl(a.N,b));A(a)&&y(a,b?"scan code "+t(b)+" available":"no scan codes available")}function Nl(a){var b=0;a.A.length&&(b=a.A[0]);A(a)&&y(a,"scan code "+t(b)+" delivered");return b}function Xl(a,b){0<a.A.length&&(a.A.shift(),(a.U=b)&&(a.A.length&&a.N?Wl(a.N,a.A[0]):b=!1),A(a)&&y(a,"scan codes shifted, notify "+(b?"true":"false")))}m.ic=function(a,b){return!b&&(this.reset(),a&&this.restore&&!this.restore(a))?!1:!0};
|
||||
m.hc=function(a){return a?this.save():!0};m.reset=function(){if(!this.ja&&this.N)switch(this.N.ja){case 5150:case 5160:nm(this,om[0]);break;default:nm(this,om[1])}Bm(this);this.xc=this.C=0;this.A=[];this.U=!0;this.L=""};m.save=function(){var a=new hf(this),b=0,c=[];c[b++]=this.aa;c[b]=this.X;N(a,0,c);return a.data()};m.restore=function(a){return Bm(this,a[0])};function Bm(a,b){var c=0;void 0===b&&(b=[]);a.aa=a.U=b[c++];a.X=b[c];a.W=0;return!0}
|
||||
|
|
@ -492,8 +492,8 @@ function gn(a,b){var c=a.mb[b];if(null!=c&&5<=a.Ua){var d=0,e=0,f=0;switch(b){ca
|
|||
m=Z.prototype;
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;c=(c=Fm[this.ja])&&c[0];3!==c&&(ic(b,this,hn),mc(b,this,jn));1!==c&&(ic(b,this,kn),mc(b,this,ln));5<=this.Ua&&(ic(b,this,mn),mc(b,this,nn));this.Ua==dm&&(ic(b,this,on),mc(b,this,pn));if(d){var e=this;Mk(d,262144,function(a){if(e.C)if(a[0]){var b=e.C;if(b.sd){var c,d,f,q=!1,p=8,z=8,F=-1,v=b.video.L>>3;for(c=0;c<a.length;c++){var E=a[c];if(c){var H=E.charAt(0);d=ca(E.substr(1));switch(H){case "l":p=d;break;case "n":1<=d&&8>=d&&(z=d,q=!0);break;case "p":0<=
|
||||
d&&3>=d&&(F=d);break;case "w":d<v&&(v=d);break;default:b.ha.O("unrecognized argument: "+E)}}else f=ca(E)}void 0===f?f=b.B||0:f>=b.ob&&(f-=b.ob);a="";for(c=0;c<p;c++){E=r(b.ob+f)+":";for(d=0;d<z&&f<b.sd.length;d++)H=b.sd[f++],E+=" "+(0>F?r(H):da(H>>(F<<3),8));q&&(f+=v-z);a&&(a+="\n");a+=E}a&&b.ha.O(a);b.B=f}else b.ha.O("no buffer")}else e.ha.O("BIOSMODE: "+t(e.Ia)),b=e.C,fn(b,"CRTC",b.Ac,b.mb,b.lg),5<=b.Ua&&(fn(b," GRC",b.ce,b.be,b.Vg),fn(b," SEQ",b.de,b.Ke,b.Wg),fn(b," ATC",b.Od,b.Tc,b.Ug),fn(b," ATCINDX",
|
||||
b.Od),b.ha.O(" ATCDATA: "+b.Ye),fn(b," FEAT",b.eg),fn(b," MISC",b.vf),fn(b," STATUS0",b.Ng)),fn(b," STATUS1",b.ma),1!=b.Ua&&3!=b.Ua||fn(b," MODEREG",b.gd),3==b.Ua&&fn(b," COLOR",b.tf),5<=b.Ua&&(b.ha.O(" LATCHES: "+r(b.Gb)),b.ha.O(" ACCESS: "+r(b.xg,4)),b.ha.O("Use 'dump video [addr]' to dump video memory"));else e.ha.O("no active video card")})}if((this.B=Eb(a,"Keyboard"))&&this.ka){for(var f in this.qa)0<f.indexOf("lock")&&this.B.Pb("led",f,this.qa[f]);this.B.Pb(this.wk?"textarea":"canvas",
|
||||
"kbd",this.V)}this.Vc=9;(this.N=Eb(a,"ChipSet"))&&this.cg&&5==this.Ua&&(this.Vc=sk(this.cg,this.Vc));"mouse"==this.hg?(this.W=Eb(a,"Mouse"))&&qn(this,2):"keygrid"==this.hg&&this.B&&qn(this,1)};
|
||||
b.Od),b.ha.O(" ATCDATA: "+b.Ye),fn(b," FEAT",b.eg),fn(b," MISC",b.vf),fn(b," STATUS0",b.Ng)),fn(b," STATUS1",b.ma),1!=b.Ua&&3!=b.Ua||fn(b," MODEREG",b.gd),3==b.Ua&&fn(b," COLOR",b.tf),5<=b.Ua&&(b.ha.O(" LATCHES: "+r(b.Gb)),b.ha.O(" ACCESS: "+r(b.xg,4)),b.ha.O("Use 'dump video [addr]' to dump video memory"));else e.ha.O("no active video card")})}if((this.B=Db(a,"Keyboard"))&&this.ka){for(var f in this.qa)0<f.indexOf("lock")&&this.B.Pb("led",f,this.qa[f]);this.B.Pb(this.wk?"textarea":"canvas",
|
||||
"kbd",this.V)}this.Vc=9;(this.N=Db(a,"ChipSet"))&&this.cg&&5==this.Ua&&(this.Vc=sk(this.cg,this.Vc));"mouse"==this.hg?(this.W=Db(a,"Mouse"))&&qn(this,2):"keygrid"==this.hg&&this.B&&qn(this,1)};
|
||||
m.Pb=function(a,b,c){var d=this;if(!this.qa[b])switch(this.qa[b]=c,b){case "fullScreen":return this.ia&&this.ia.Xe?c.onclick=function(){d.Xe()}:c.parentNode.removeChild(c),!0;case "lockPointer":return this.vk=c.textContent,this.V&&this.V.De?c.onclick=function(){d.De(!0)}:c.parentNode.removeChild(c),!0;case "refresh":return c.onclick=function(){rn(d,!0)},!0}return!1};
|
||||
m.Xe=function(){var a=!1;if(this.ia){if(this.ia.Xe){a="100%";if(screen&&screen.width&&screen.height){var b=screen.width/screen.height,c=this.ra/this.Ea;b>c&&(a=Math.round(c/b*100)+"%")}this.rf?(this.ka.style.width=a,this.ka.style.width=a,this.ka.style.display="block",this.ka.style.margin="auto"):(this.ia.style.width=a,this.ia.style.height="auto");this.ia.style.backgroundColor="black";this.ia.Xe();a=!0}this.V&&this.V.focus()}return a};
|
||||
function Im(a,b){!b&&a.ia&&(a.rf?a.ka.style.width=a.ka.style.height="":a.ia.style.width=a.ia.style.height="");y(a,"notifyFullScreen("+b+")",!0);a.B&&(a.B.dh=b)}m.De=function(a){var b=!1;this.V&&(a?this.V.De&&(this.V.De(),this.W&&this.W.Wf(!0),b=!0):this.V.tk&&(this.V.tk(),this.W&&this.W.Wf(!1),b=!0),this.V&&this.V.focus());return b};m.Wf=function(a){this.W&&(this.W.Wf(a),this.B&&(this.B.dh=a));var b=this.qa.lockPointer;b&&(b.textContent=a?"Press Esc to Unlock Pointer":this.vk)};
|
||||
|
|
@ -508,7 +508,7 @@ function zn(a,b){if(1==b)return a.Ca[0]=Om[0],a.Ca[1]=Om[7],a.Ca;if(2==b){var c=
|
|||
(c.Tc[20]&12)<<4,c.Tc[16]&128&&(g&=-49,g|=(c.Tc[20]&3)<<4),g=d[g],h=g<<2&252,k=g>>4&252,g=g>>10&252):(h=(g&4?170:0)|(g&32?85:0),k=(g&2?170:0)|(g&16?85:0),g=(g&1?170:0)|(g&8?85:0)),a.Ca[f]=[h,k,g,255]}a.rb=!0}return a.Ca}function cm(a,b,c,d){a.Uc=b;a.Jb=c;a.Tb=d}
|
||||
function vn(a,b){var c=!1;if(window&&a.Uc&&(!b||a.U)){var d=0,e=a.Tb?a.Tb:8,f=zn(a);null!=a.Jb[0]&&An(a,3,a.Jb[0],d,e,8,a.Uc,f)&&(c=!0);d=a.Tb?0:2048;e=a.Tb?a.Tb:9;null!=a.Jb[1]&&(An(a,1,a.Jb[1],d,e,14,a.Uc,Mm,Nm)&&(c=!0),a.Tb&&An(a,a.Ua,a.Jb[1],0,a.Tb,14,a.Uc,f)&&(c=!0))}return c}function An(a,b,c,d,e,f,g,h,k){var l=!1;null!=c&&(Bn(a,b,c,d,e,f,g,h,k)&&(l=!0),a.un&&Bn(a,b<<1,c,d,e,f,g,h,k)&&(l=!0));return l}
|
||||
function Bn(a,b,c,d,e,f,g,h,k){var l=!1,n=b&1?0:1,q=a.Oa[b],p=16>h.length?h.length:16;q||(q={Qc:e<<n,Rc:f<<n,Pe:Array(p),ti:h.slice(0,p),Af:k,Tg:Array(p)});for(k=0;k<p;k++){var z=h[k],F=q.Pe[k]?q.ti[k]:[];if(z[0]!==F[0]||z[1]!==F[1]||z[2]!==F[2]){var l=q,F=k,v=n,E=c,H=d,L=e,V=f,P=g,bb=[0,0,0,0],ia=document.createElement("canvas");ia.width=l.Qc<<4;ia.height=l.Rc<<4;for(var ja=ia.getContext("2d"),Ha=void 0,Xa=void 0,Ba=void 0,Vb=8>V||!H?V:8,wa=ja.createImageData(l.Qc,l.Rc),Ha=0;256>Ha;Ha++){for(Ba=
|
||||
0;Ba<V;Ba++)for(var Ud=l.Af&&F&1&&Ba>=V-2,Qc=P[Ba<Vb?E+Ha*Vb+Ba:H+Ha*Vb+Ba-Vb],Vd=0;Vd<=v;Vd++)for(Xa=0;Xa<L;Xa++){var Je=Xa<<v,Wd=(Ba<<v)+Vd,Ke=Ud||Qc&128>>(8<=Xa&&192<=Ha&&223>=Ha?7:Xa)?z:bb;Cn(wa,Je,Wd,Ke);v&&Cn(wa,Je+1,Wd,Ke)}ja.putImageData(wa,(Ha&15)*l.Qc,(Ha>>4)*l.Rc)}l.Pe[F]="#"+r(z[0],2)+r(z[1],2)+r(z[2],2);l.ti[F]=z;l.Tg[F]=ia;l=!0}}a.Oa[b]=q;return l}function $n(a){0<a.Pa||0<=a.ua?0>a.cb&&(a.cb=0):a.cb=-1}
|
||||
0;Ba<V;Ba++)for(var Vd=l.Af&&F&1&&Ba>=V-2,Qc=P[Ba<Vb?E+Ha*Vb+Ba:H+Ha*Vb+Ba-Vb],Wd=0;Wd<=v;Wd++)for(Xa=0;Xa<L;Xa++){var Je=Xa<<v,Xd=(Ba<<v)+Wd,Ke=Vd||Qc&128>>(8<=Xa&&192<=Ha&&223>=Ha?7:Xa)?z:bb;Cn(wa,Je,Xd,Ke);v&&Cn(wa,Je+1,Xd,Ke)}ja.putImageData(wa,(Ha&15)*l.Qc,(Ha>>4)*l.Rc)}l.Pe[F]="#"+r(z[0],2)+r(z[1],2)+r(z[2],2);l.ti[F]=z;l.Tg[F]=ia;l=!0}}a.Oa[b]=q;return l}function $n(a){0<a.Pa||0<=a.ua?0>a.cb&&(a.cb=0):a.cb=-1}
|
||||
function yn(a){if(a.U){for(var b=10;15>=b;b++)if(null==a.C.mb[b])return;var c=a.C.mb[10],b=c&31,d=a.C.mb[11]&31,e=a.C.mb[9]&31,f=!1;a.C===a.A&&(f=!0,7!=e||4!=b||d||(d=7));if(c&32||b>d&&!f||b>e)ao(a);else{c=a.C.mb[15]+((a.C.mb[14]&63)<<8);a.ua!=c&&(ao(a),a.ua=c);d=d-b+1;if(a.jg!=b||a.Ce!=d)a.jg=b,a.Ce=d;a.$a=e+1;$n(a)}}}
|
||||
function ao(a){if(0<=a.ua){if(void 0!==a.ga){var b=a.ga[a.ua];if(b&131072){var b=b&-131073,c=a.ua%a.L,d=a.ua/a.L|0;a.U&&a.Oa[a.U]&&(a.gb&&bo(a,c,d,b,a.gb),bo(a,c,d,b));a.ga[a.ua]=b}}a.ua=-1}}
|
||||
function co(a){var b,c=a.C;a.hf=!1;var d=c.be[5];if(null!=d){b=1024;var e=0,f=c.be[3]&31;switch(d&3){case 0:if(f){e=32;switch(f&24){case 8:e=96;break;case 16:e=160;break;case 24:e=224}c.dd=f&7}break;case 1:e=1;break;case 2:switch(f&24){default:e=2;break;case 8:e=98;break;case 16:e=162;break;case 24:e=226}break;case 3:a.Ua==dm&&(e=3,c.dd=f&7)}d&8&&(b=1280);c=c.Ke[4];null!=c&&(c&4||(b|=4096,e|=16),d&64&&(c&8&&(b|=16384,e|=4),a.hf=!0));b|=e}return b}
|
||||
|
|
@ -543,13 +543,13 @@ var hn={948:Z.prototype.Hl,949:Z.prototype.Gl,952:Z.prototype.Il,954:Z.prototype
|
|||
Qa(function(){for(var a=nb(document,"pcx86","video"),b=0;b<a.length;b++){var c=a[b],d=jb(c),e=document.createElement("canvas");if(void 0===e||!e.getContext){c.innerHTML="<br/>Missing <canvas> support. Please try a newer web browser.";break}e.setAttribute("class","pcjs-canvas");e.setAttribute("width",d.screenWidth);e.setAttribute("height",d.screenHeight);e.style.backgroundColor=d.screenColor;e.style.height="auto";0<=ya().indexOf("MSIE")&&(c.onresize=function(a,b,c,d){return function(){b.style.height=
|
||||
(a.clientWidth*d/c|0)+"px"}}(c,e,d.screenWidth,d.screenHeight),c.onresize());var f=+(d.aspect||Ya.aspect);f&&.3<=f&&3.33>=f&&(Pa("onresize",function(a,b,c){return function(){b.style.height=(a.clientWidth/c|0)+"px"}}(c,e,f)),window.onresize());c.appendChild(e);f=document.createElement("textarea");Ga("iOS")&&(f.setAttribute("autocapitalize","off"),f.setAttribute("autocorrect","off"));c.appendChild(f);var g=e.getContext("2d"),d=new Z(d,e,g,f,c);mb(d,c)}});
|
||||
function no(a){this.W=a.adapter;switch(this.W){case 1:this.V=956;this.C=7;break;case 2:this.V=888;this.C=7;break;case 3:this.V=632;this.C=5;break;default:w("Unrecognized parallel adapter #"+this.W);return}this.A=this.B=null;Ua.call(this,"ParallelPort",a,no,4194304);a=a.binding;"console"==a?this.B="":kb(this,a,oo)}db(no);var oo="buffer";m=no.prototype;m.Pb=function(a,b,c){switch(b){case oo:return this.qa[b]=this.A=c,!0}return!1};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.N=Eb(a,"ChipSet");ic(b,this,po,this.V);mc(b,this,qo,this.V);rb(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){ro(this)};m.save=function(){var a=new hf(this),b=0,c=[];c[b++]=this.L;c[b++]=this.Yb;c[b]=this.Cf;N(a,0,c);return a.data()};m.restore=function(a){return ro(this,a[0])};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.N=Db(a,"ChipSet");ic(b,this,po,this.V);mc(b,this,qo,this.V);rb(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){ro(this)};m.save=function(){var a=new hf(this),b=0,c=[];c[b++]=this.L;c[b++]=this.Yb;c[b]=this.Cf;N(a,0,c);return a.data()};m.restore=function(a){return ro(this,a[0])};
|
||||
function ro(a,b){var c=0;void 0===b&&(b=[0,0,0]);a.L=b[c++];a.Yb=b[c++];a.Cf=b[c];return!0}m.ul=function(a,b){var c=this.L;x(this,a,null,b,"DATA",c);return c};m.Sl=function(a,b){var c=this.Yb;x(this,a,null,b,"STAT",c);return c};m.ql=function(a,b){var c=this.Cf;x(this,a,null,b,"CTRL",c);return c};
|
||||
m.Om=function(a,b,c){x(this,a,b,c,"DATA");this.L=b;this.Yb|=64;if(this.A)8==b?this.A.value=this.A.value.slice(0,-1):(this.A.value+=String.fromCharCode(b),this.A.scrollTop=this.A.scrollHeight),a=!0;else if(null!=this.B){if(10==b||1024<=this.B.length)this.O(this.B),this.B="";10!=b&&(this.B+=String.fromCharCode(b));a=!0}else a=!1;a&&(this.Yb&=-65);so(this)};m.Jm=function(a,b,c){x(this,a,b,c,"CTRL");this.Cf=b;so(this)};function so(a){a.N&&a.C&&(a.Cf&16&&!(a.Yb&64)?eg(a.N,a.C):dg(a.N,a.C))}
|
||||
var po={0:no.prototype.ul,1:no.prototype.Sl,2:no.prototype.ql},qo={0:no.prototype.Om,2:no.prototype.Jm};Qa(function(){for(var a=nb(document,"pcx86","parallel"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new no(d);mb(d,c)}});
|
||||
function to(a){this.ra=a.adapter;switch(this.ra){case 1:this.ka=1016;this.fa=4;break;case 2:this.ka=760;this.fa=3;break;default:w("Unrecognized serial adapter #"+this.ra);return}this.V=this.U=null;this.Ca=a.tabSize;this.ya=a.charBOL;this.X=0;Ua.call(this,"SerialPort",a,to,8388608);a=a.binding;"console"==a?this.U="":kb(this,a,uo)}db(to);var uo="buffer";m=to.prototype;m.xi=function(a,b){return a==this.Rd?(this.W=b,this):null};
|
||||
m.Pb=function(a,b,c){var d=this;switch(b){case uo:return this.qa[b]=this.V=c,c.onkeydown=function(a){a=a||window.event;var b=a.keyCode;if(8===b||a.ctrlKey&&65<=b&&90>=b)a.preventDefault&&a.preventDefault(),64<b&&(b-=64),vo(d,[b]);return!0},c.onkeypress=function(a){a=a||window.event;vo(d,[a.which||a.keyCode]);a.preventDefault&&a.preventDefault();return!0},c.removeAttribute("readonly"),!0}return!1};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.N=Eb(a,"ChipSet");ic(b,this,wo,this.ka);mc(b,this,xo,this.ka);rb(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){yo(this)};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.N=Db(a,"ChipSet");ic(b,this,wo,this.ka);mc(b,this,xo,this.ka);rb(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){yo(this)};
|
||||
m.save=function(){var a=new hf(this),b=0,c=[];c[b++]=this.pa;c[b++]=this.wa;c[b++]=this.aa;c[b++]=this.ia;c[b++]=this.L;c[b++]=this.B;c[b++]=this.C;c[b++]=this.A;c[b++]=this.ua;c[b]=this.ga;N(a,0,c);return a.data()};m.restore=function(a){return yo(this,a[0])};function yo(a,b){var c=0;void 0===b&&(b=[0,0,384,0,1,0,0,96,48,[]]);a.pa=b[c++];a.wa=b[c++];a.aa=b[c++];a.ia=b[c++];a.L=b[c++];a.B=b[c++];a.C=b[c++];a.A=b[c++];a.ua=b[c++];a.ga=b[c];return!0}function vo(a,b){a.ga=a.ga.concat(b);zo(a)}
|
||||
function zo(a){0<a.ga.length&&!(a.A&1)&&(a.pa=a.ga.shift(),a.A|=1);var b=-1;a.A&1&&a.ia&1&&(b=4);0<=b?(a.L&=-8,a.L|=b,a.N&&a.fa&&eg(a.N,a.fa,100)):(a.L|=1,a.N&&a.fa&&dg(a.N,a.fa))}m.Pl=function(a,b){var c=this.B&128?this.aa&255:this.pa;x(this,a,null,b,this.B&128?"DLL":"RBR",c);this.A&=-2;zo(this);return c};m.Bl=function(a,b){var c=this.B&128?this.aa>>8:this.ia;x(this,a,null,b,this.B&128?"DLM":"IER",c);return c};m.Cl=function(a,b){var c=this.L;x(this,a,null,b,"IIR",c);return c};
|
||||
m.Dl=function(a,b){var c=this.B;x(this,a,null,b,"LCR",c);return c};m.Fl=function(a,b){var c=this.C;x(this,a,null,b,"MCR",c);return c};m.El=function(a,b){var c=this.A;x(this,a,null,b,"LSR",c);return c};m.Kl=function(a,b){var c=this.ua;x(this,a,null,b,"MSR",c);return c};
|
||||
|
|
@ -557,7 +557,7 @@ m.mn=function(a,b,c){x(this,a,b,c,this.B&128?"DLL":"THR");if(this.B&128)this.aa=
|
|||
"";10!=b&&(this.U+=String.fromCharCode(b));b=!0}else b=!1;b&&(this.A|=96)}};m.Ym=function(a,b,c){x(this,a,b,c,this.B&128?"DLM":"IER");this.B&128?this.aa=this.aa&255|b<<8:this.ia=b};m.Zm=function(a,b,c){x(this,a,b,c,"LCR");this.B=b};
|
||||
m.$m=function(a,b,c){var d=this.C;x(this,a,b,c,"MCR");this.C=b;this.W&&(d^b)&3&&(a=this.W,b=this.C,(c=3==(b&3))?a.Hc||(d=!1,a.C&2||(a.reset(),y(a,"serial mouse reset"),d=!0),a.C&1||(y(a,"serial mouse ID requested"),d=!0),d&&(vo(a.N,[77,77]),y(a,"serial mouse ID sent")),Ao(a),a.Hc=c):a.Hc&&(y(a,"serial mouse inactive"),Bo(a),a.Hc=c),a.C=b)};
|
||||
var wo={0:to.prototype.Pl,1:to.prototype.Bl,2:to.prototype.Cl,3:to.prototype.Dl,4:to.prototype.Fl,5:to.prototype.El,6:to.prototype.Kl},xo={0:to.prototype.mn,1:to.prototype.Ym,3:to.prototype.Zm,4:to.prototype.$m};Qa(function(){for(var a=nb(document,"pcx86","serial"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new to(d);mb(d,c)}});function Co(a){Ua.call(this,"Mouse",a,Co,16777216);if(this.ka=a.serial)this.pa="SerialPort";this.ia=this.ga=this.Hc=!1;this.B=[];this.A=[];rb(this)}db(Co);var tn=0;m=Co.prototype;
|
||||
m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.F=c;this.ha=d;for(b=null;b=Eb(a,"Video",b);)this.B.push(b)};m.ic=function(a,b){if(!b){if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;if(this.pa&&!this.N){for(var c=null;(c=Eb(this.V,this.pa,c))&&(!c.xi||!(this.N=c.xi(this.ka,this))););if(this.N)for(this.A=[],c=0;c<this.B.length;c++){var d;d=this.B[c];d.W=this;(d=d.V)&&this.A.push(d)}else w(this.id+": "+this.pa+" "+this.ka+" unavailable")}this.Hc?Ao(this):Bo(this)}return!0};
|
||||
m.Ic=function(a,b,c,d){this.V=a;this.ea=b;this.F=c;this.ha=d;for(b=null;b=Db(a,"Video",b);)this.B.push(b)};m.ic=function(a,b){if(!b){if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;if(this.pa&&!this.N){for(var c=null;(c=Db(this.V,this.pa,c))&&(!c.xi||!(this.N=c.xi(this.ka,this))););if(this.N)for(this.A=[],c=0;c<this.B.length;c++){var d;d=this.B[c];d.W=this;(d=d.V)&&this.A.push(d)}else w(this.id+": "+this.pa+" "+this.ka+" unavailable")}this.Hc?Ao(this):Bo(this)}return!0};
|
||||
m.hc=function(a){return a?this.save():!0};m.reset=function(){Do(this)};m.save=function(){var a=new hf(this),b=0,c=[];c[b++]=this.Hc;c[b++]=this.L;c[b++]=this.W;c[b++]=this.U;c[b++]=this.X;c[b++]=this.aa;c[b++]=this.fa;c[b]=this.C;N(a,0,c);return a.data()};m.restore=function(a){return Do(this,a[0])};function Do(a,b){var c=0;void 0===b&&(b=[!1,-1,-1,0,0,!1,!1,0]);var d=b[c++];a.Hc=d;a.L=b[c++];a.W=b[c++];a.U=b[c++];a.X=b[c++];a.aa=b[c++];a.fa=b[c++];a.C=b[c];return!0}m.Wf=function(a){this.ga=a};
|
||||
function Ao(a){if(!a.ia)for(var b=0;b<a.A.length;b++)Eo(a,a.A[b])&&(a.ia=!0)}function Bo(a){if(a.ia)for(var b=0;b<a.A.length;b++){var c=a.A[b];c&&(c.style.cursor="auto")}}function Eo(a,b){return b?(b.addEventListener("mousemove",function(b){Fo(a,b)},!1),b.addEventListener("mousedown",function(b){Fo(a,b,!0)},!1),b.addEventListener("mouseup",function(b){Fo(a,b,!1)},!1),b.style.cursor="none",!0):!1}
|
||||
function Fo(a,b,c){if(void 0!==c){var d;!(d=!1!==a.ga)&&(d=a.B.length)&&(d=a.B[0],d=d.ri?d.De(!0):!1);d||(a.ga=null);a.je(b.button,c)}else{if(0>a.L||0>a.W)a.L=b.clientX,a.W=b.clientY;a.ga?(c=b.movementX||b.mozMovementX||b.webkitMovementX||0,d=b.movementY||b.mozMovementY||b.webkitMovementY||0):(c=b.clientX-a.L,d=b.clientY-a.W);a.L=b.clientX;a.W=b.clientY;a.If(c,d,a.L,a.W)}}
|
||||
|
|
@ -598,7 +598,7 @@ var sp={3:{Wd:3,ie:0,name:aa.$n},4:{Wd:2,ie:1,name:aa.Yn},5:{Wd:9,ie:7,name:aa.j
|
|||
m.Pb=function(a,b,c){var d=this;switch(b){case "listDisks":this.qa[b]=c;if(this.ga){b=[];for(a=0;a<c.options.length;a++)b.push(c.options[a]);b.sort(function(a,b){return"path"!=d.ga?a.text.localeCompare(b.text):a.value.localeCompare(b.value)});for(a=0;a<b.length;a++)c.options[a]=b[a]}c.onchange=function(){var a=d.qa.descDisk,b=c.options[c.selectedIndex];if(a&&b){var g={};if(b=b.getAttribute("data-value"))try{g=eval("("+b+")")}catch(h){w("FDC option error: "+h.message)}b=g.desc;void 0===b&&(b="");g=
|
||||
g.href;void 0!==g&&(b='<a href="'+g+'" target="_blank">'+b+"</a>");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.qa[b]=c,c.onchange=function(){var a=ca(c.value,10);null!=a&&tp(d,a)},!0;case "loadDrive":return this.qa[b]=c,c.onclick=function(){var a=d.qa.listDisks;a&&up(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.ia){c.parentNode.removeChild(c);break}this.qa[b]=c;c.onclick=function(){var a=d.qa.listDrives;a&&a.options&&d.A&&(a=ca(a.value,10),(a=
|
||||
d.A[a])?(a=a.za)?(a=Ia(pp(a),"octet-stream",!0,a.Og.replace(".json",".img")),w(a)):d.Na("No diskette loaded in drive."):d.Na("No diskette drive selected."))};return!0;case "mountDrive":if(!this.ia){c.parentNode.removeChild(c);break}this.qa[b]=c;c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length});c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;up(d,fa(b,!0),b,a)}return!1};return!0}return!1};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.V=a;this.N=Eb(a,"ChipSet");if((this.U=Nc(this.V,"autoMount")||this.U)&&"string"==typeof this.U)try{this.U=eval("("+this.U+")")}catch(e){w("FDC auto-mount error: "+e.message+" ("+this.U+")"),this.U=null}vp(this);ic(b,this,wp);mc(b,this,xp);yp(this,"None","",!0);this.ia&&yp(this,"Local Disk","?");yp(this,"Remote Disk","??");zp(this)||rb(this)};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.V=a;this.N=Db(a,"ChipSet");if((this.U=Nc(this.V,"autoMount")||this.U)&&"string"==typeof this.U)try{this.U=eval("("+this.U+")")}catch(e){w("FDC auto-mount error: "+e.message+" ("+this.U+")"),this.U=null}vp(this);ic(b,this,wp);mc(b,this,xp);yp(this,"None","",!0);this.ia&&yp(this,"Local Disk","?");yp(this,"Remote Disk","??");zp(this)||rb(this)};
|
||||
m.ic=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.V.eh){this.B=[];for(var c=0;c<this.A.length;c++)Ap(this,c,!0);zp(this,!0)}}else if(!this.restore(a))return!1;if(c=this.qa.listDrives){for(;c.firstChild;)c.removeChild(c.firstChild);c.value="";for(var d=0;d<this.ka;d++){var e=document.createElement("option");e.value=d;e.text=String.fromCharCode(65+d)+":";c.appendChild(e)}0<this.ka&&(c.value="0",tp(this,0))}}return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){vp(this)};
|
||||
m.save=function(){var a=new hf(this),b=0,c=[];c[b++]=this.hb;c[b++]=0;c[b++]=this.ma;c[b++]=this.W;c[b++]=this.L;c[b++]=this.C;c[b++]=this.aa;for(var d=b++,e=0,f=[],g=0;g<this.A.length;g++){var h=e++,k=this.A[g],l=0,n=[];n[l++]=k.Cb;n[l++]=[k.name,k.Bb,k.ub,k.lb,k.Va,k.cf,k.Ag,k.Of,k.Pf];n[l++]=k.kb;n[l++]=k.ge+100;n[l++]=k.Qb;n[l++]=k.xb;n[l++]=k.he;n[l++]=k.Ib;n[l++]=k.eb;n[l++]=k.af;n[l++]=k.lk;n[l]=k.Me;f[h]=n}c[d]=f;d=b++;for(e=0;e<this.A.length;e++)f=this.A[e],f.za&&Bp(this,f.Me,f.za);c[d]=
|
||||
this.B;c[b++]=this.X;c[b]=this.jc;N(a,0,c);return a.data()};m.restore=function(a){return vp(this,a[0])};
|
||||
|
|
@ -625,7 +625,7 @@ Qa(function(){for(var a=nb(document,"pcx86","fdc"),b=0;b<a.length;b++){var c=a[b
|
|||
var Lp=["XTC","ATC","COMPAQ"],Mp=[{0:[306,2],1:[375,8],2:[306,6],3:[306,4]},{1:[306,4],2:[615,4],3:[615,6],4:[940,8],5:[940,6],6:[615,4],7:[462,8],8:[733,5],9:[900,15],10:[820,3],11:[855,5],12:[855,7],13:[306,8],14:[733,7],16:[612,4],17:[977,5],18:[977,7],19:[1024,7],20:[733,5],21:[733,7],22:[733,5],23:[306,4]},{1:[306,4],2:[615,4],3:[615,6],4:[1023,8],5:[940,6],6:[697,5],7:[462,8],8:[925,5],9:[900,15],10:[980,5],11:[925,7],12:[925,9],13:[612,8],14:[980,4],16:[612,4],17:[980,5],18:[966,6],19:[1023,
|
||||
8],20:[733,5],21:[733,7],22:[524,4,40],23:[924,8],24:[966,14],25:[966,16],26:[1023,14],27:[832,6,33],28:[1222,15,34],29:[1240,7,34],30:[615,4,25],31:[615,8,25],32:[905,9,25],33:[832,8,33],34:[966,7,34],35:[966,8,34],36:[966,9,34],37:[966,5,34],38:[612,16,63],39:[1023,11,33],40:[1023,15,34],41:[1630,15,52],42:[1023,16,63],43:[805,4,26],44:[805,2,26],45:[748,8,33],46:[748,6,33],47:[966,5,25]}];m=Kp.prototype;
|
||||
m.Pb=function(a,b,c){var d=this;switch(b){case "saveHD0":case "saveHD1":return this.qa[b]=c,c.onclick=function(a){return function(){var b=d.A&&d.A[a];b&&b.za?(b=b.za,b=Ia(pp(b),"octet-stream",!0,b.Og.replace(".json",".img")),w(b)):d.Na("Hard drive "+a+" is not available.")}}(+b.slice(-1)),!0}return!1};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.V=a;if(d=Nc(a,"drives"))this.ua=d;else if(this.Fa)try{this.ua=eval("("+this.Fa+")")}catch(e){w("HDC drive configuration error: "+e.message+" ("+this.Fa+")")}this.N=Eb(a,"ChipSet");this.U=0;this.Ia=3;ic(b,this,this.ia?Np:Op);mc(b,this,this.ia?Pp:Qp);this.ia&&(this.U++,this.N&&5180==this.N.ja&&this.U++,this.Ia=2,b.aa[496]=2,b.fa[496]=2);Te(c,19,this.$l.bind(this));Te(c,64,this.am.bind(this));this.reset();Rp(this)||rb(this)};
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.ha=d;this.V=a;if(d=Nc(a,"drives"))this.ua=d;else if(this.Fa)try{this.ua=eval("("+this.Fa+")")}catch(e){w("HDC drive configuration error: "+e.message+" ("+this.Fa+")")}this.N=Db(a,"ChipSet");this.U=0;this.Ia=3;ic(b,this,this.ia?Np:Op);mc(b,this,this.ia?Pp:Qp);this.ia&&(this.U++,this.N&&5180==this.N.ja&&this.U++,this.Ia=2,b.aa[496]=2,b.fa[496]=2);Te(c,19,this.$l.bind(this));Te(c,64,this.am.bind(this));this.reset();Rp(this)||rb(this)};
|
||||
m.ic=function(a,b){if(!b)if(!a||!this.restore)Sp(this),this.V.eh&&Rp(this,!0);else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.gf=function(){return this.V?this.V.gf():""};m.ke=function(){return this.V?this.V.ke():""};m.reset=function(){Sp(this,null,!0)};
|
||||
m.save=function(){var a=new hf(this),b=0,c=[];this.ia?(c[b++]=this.X,c[b++]=this.Pa,c[b++]=this.aa,c[b++]=this.Ca,c[b++]=this.ya,c[b++]=this.wa,c[b++]=this.ra,c[b++]=this.ma,c[b++]=this.Ea,c[b++]=[this.ga,this.hb]):(c[b++]=this.pa,c[b++]=this.ma,c[b++]=this.W,c[b++]=this.L,c[b++]=this.C,c[b++]=this.Oa,c[b++]=this.Ka,c[b++]=this.Ja,c[b++]=this.ka);for(var d=0,e=[],f=0;f<this.A.length;f++){var g=d++,h=this.A[f],k=0,l=[];l[k++]=h.errorCode;l[k++]=h.nk;l[k++]=h.cf;l[k++]=h.Re;l[k++]=h.Se;l[k++]=h.kb;
|
||||
l[k++]=h.ub;l[k++]=h.ee;l[k++]=h.xb;l[k++]=h.he;l[k++]=h.Ib;l[k++]=h.eb;l[k]=h.za?h.za.save():null;e[g]=l}c[b]=e;N(a,0,c);return a.data()};m.restore=function(a){return Sp(this,a[0])};
|
||||
|
|
@ -676,7 +676,7 @@ bus:64,mem:128,port:256,dma:512,pic:1024,timer:2048,cmos:4096,rtc:8192,8042:1638
|
|||
[116,12417,4113],[109,12417,4113],[110,12417,4113],[140,12417,4113],[142,12417,4113],wq,[119,12417,4113]],[[115,12420,4113],[116,12420,4113],[109,12420,4113],[110,12420,4113],[140,12420,4113],[142,12420,4113],wq,[119,12420,4113]],[[115,12417,4449],[116,12417,4449],[109,12417,4449],[110,12417,4449],[140,12417,4449],[142,12417,4449],wq,[119,12417,4449]],[[115,12420,4449],[116,12420,4449],[109,12420,4449],[110,12420,4449],[140,12420,4449],[142,12420,4449],wq,[119,12420,4449]],[[155,4225,4097],wq,[98,
|
||||
12417],[96,12417],[95,4225],[42,12417],[32,4225],[41,12417]],[[155,4228,4100],wq,[98,12420],[96,12420],[95,4228],[42,12420],[32,4228],[41,12420]],[[44,12417],[31,12417],wq,wq,wq,wq,wq,wq],[[44,12420],[31,12420],[17,4228],[17,4231],[57,4228],[57,4231],[108,4228],wq],[],[[145,41091],[153,41091],[78,36995],[89,36995],[156,36995],[157,36995],wq,wq],[[139,41091],[144,41091],[75,36995],[77,36995],[146,41091],wq,[79,36995],wq],[wq,wq,wq,wq,[13,53380,4097],[16,57476,4097],[15,57476,4097],[14,57476,4097]]];
|
||||
m=gq.prototype;
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.V=a;this.tc=Eb(a,"FDC");this.Jb=Eb(a,"HDC");this.Tb=Eb(a,"FPU");this.W=Eb(a,"Mouse");(a=Nc(a,"messages"))&&kq(this,a);this.Ca=b.N>>2;this.Ba=b.yg;this.bc=new dd(this.F,7,"DBG");this.Ia=yq;80186<=this.F.ja&&(this.Ia=yq.slice(),this.Ia[15]=wq,80286<=this.F.ja&&(this.Ia[15]=xq,80386<=this.F.ja&&(this.Ja=8)));Mk(this,64,function(a){Cq(d,d.F.ld,a[0])});Mk(this,4,function(a){if(a=a[0]){var b=Dq(d,a);if(void 0===b)d.O("invalid selector: "+a);else if(a=Eq(d,
|
||||
m.Ic=function(a,b,c,d){this.ea=b;this.F=c;this.V=a;this.tc=Db(a,"FDC");this.Jb=Db(a,"HDC");this.Tb=Db(a,"FPU");this.W=Db(a,"Mouse");(a=Nc(a,"messages"))&&kq(this,a);this.Ca=b.N>>2;this.Ba=b.yg;this.bc=new dd(this.F,7,"DBG");this.Ia=yq;80186<=this.F.ja&&(this.Ia=yq.slice(),this.Ia[15]=wq,80286<=this.F.ja&&(this.Ia[15]=xq,80386<=this.F.ja&&(this.Ja=8)));Mk(this,64,function(a){Cq(d,d.F.ld,a[0])});Mk(this,4,function(a){if(a=a[0]){var b=Dq(d,a);if(void 0===b)d.O("invalid selector: "+a);else if(a=Eq(d,
|
||||
b,2),d.O("dumpSel("+u(a?a.Z:b)+"): %"+r(a?a.Xb:null,d.Ca)),a){var c,b=!1;if(a.type&4096)a.type&2048?(c="code"+(a.type&512?",readable":",execonly"),a.type&1024&&(c+=",conforming")):(c="data"+(a.type&512?",writable":",readonly"),a.type&1024&&(c+=",expdown")),a.type&256&&(c+=",accessed");else{var h=Fq[a.type];h&&(c=h[0],b=h[1])}!c||a.wb&32768||(c+=",not present");d.O((b?"seg="+u(a.Aa&65535)+" off="+u(a.Ta):"base="+r(a.Aa,d.Ca)+" limit="+Gq(a.Ta))+" type="+t(a.type>>8)+" ("+c+") ext="+u(a.ext&-65296)+
|
||||
" dpl="+t(a.Gc))}}else d.O("no selector")});Mk(this,134217728,function(a){var b;(a=a[0])&&(b=Dq(d,a));if(void 0===b)d.O("invalid MCB");else for(d.O("dumpMCB("+u(b)+")");b;){a=hq(d,0,b);var c=d.Qa(a,1),h=d.na(a,2),k=d.na(a,5);if(77!=c&&90!=c)break;d.O(Hq(0,b)+": '"+String.fromCharCode(c)+"' PID="+u(h)+" LEN="+u(k)+' "'+Iq(d,a,8)+'"');b+=1+k}});Mk(this,128,function(a){Cq(d,d.F.sa,a[0],d.F.sa!==d.F.ld)});Mk(this,8,function(a){a:{if(a=a[0]){var b=Dq(d,a);if(void 0===b){d.O("invalid task selector: "+a);
|
||||
break a}a=Eq(d,b,2)}else a=d.F.Sa;d.O("dumpTSS("+u(a?a.Z:b)+"): %"+r(a?a.Aa:null,d.Ca));if(a){var b="",c=a.type&-513,h=256==c?4:8,k=256==c?Jq:Kq,l,n,q,p;for(p in k)l=k[p],n=a.Aa+l,q=If(d.F,n,2),2304==c&&(q|=If(d.F,n+2,2)<<16),b&&(b+="\n"),b+=u(l)+" "+ma(p+":",11)+r(q,h);if(2304==c)for(p=0,l=q>>>16;l<a.Zb&&1023>p;)n=a.Aa+l,q=If(d.F,n,2),b+="\n"+u(l)+" ports "+u(p)+"-"+u(p+15)+": "+ea(q,2),p+=16,l+=2;d.O(b)}}});this.C=null;this.rb=0;this.cb=!1;Te(this.F,48,this.cm.bind(this));Te(this.F,65,this.dm.bind(this));
|
||||
|
|
@ -701,7 +701,7 @@ function Cq(a,b,c,d){var e=0,f=0,g=b.length;if(c){e=a.dc(Yq(a,c));if(-1===e){a.O
|
|||
wc&&5!=c&&(c=-1),h=0),e+=a.F.Sb,f++}function cr(a,b,c){a=r(a)+" "+r(b)+" ";a=a+(c&&b&64?"D":"-")+(b&32?"A":"-");a+=b&4?"U":"S";a+=b&2?"W":"R";return a+=b&1?"P":"N"}
|
||||
var Fq={256:["tss286",!1],512:["ldt",!1],768:["busy tss286",!1],1024:["call gate",!0],1280:["task gate",!0],1536:["int gate286",!0],1792:["trap gate286",!0],2304:["tss386",!1],2816:["busy tss386",!1],3072:["call gate386",!0],3584:["int gate386",!0],3840:["trap gate386",!0]},Jq={PREV_TSS:0,CPL0_SP:2,CPL0_SS:4,CPL1_SP:6,CPL1_SS:8,CPL2_SP:10,CPL2_SS:12,TASK_IP:14,TASK_PS:16,TASK_AX:18,TASK_CX:20,TASK_DX:22,TASK_BX:24,TASK_SP:26,TASK_BP:28,TASK_SI:30,TASK_DI:32,TASK_ES:34,TASK_CS:36,TASK_SS:38,TASK_DS:40,
|
||||
TASK_LDT:42},Kq={PREV_TSS:0,CPL0_ESP:4,CPL0_SS:8,CPL1_ESP:12,CPL1_SS:16,CPL2_ESP:20,CPL2_SS:24,TASK_CR3:28,TASK_EIP:32,TASK_PS:36,TASK_EAX:40,TASK_ECX:44,TASK_EDX:48,TASK_EBX:52,TASK_ESP:56,TASK_EBP:60,TASK_ESI:64,TASK_EDI:68,TASK_ES:72,TASK_CS:76,TASK_SS:80,TASK_DS:84,TASK_FS:88,TASK_GS:92,TASK_LDT:96,TASK_IOPM:100};
|
||||
function Mq(a,b,c){var d=[],e;for(e=null;e=Eb(a.V,"Disk",e);){var f=e,g=b,h=c,d=[];if(f.C)for(var k=0;k<f.C.length;k++){var l=f.C[k];if(l.gg==g&&(l=l.zd[h])){for(var n in l.we)f=l.we[n],d[f[1]]=f[0];break}}if(d.length)break}return d}function kq(a,b){a.ha=a;a.wc=a.Hk=1073741824;a.Pa=null;var c=br(a,b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(c.length)for(var d in vq)0<=ua(c,d)&&(a.wc|=vq[d],a.O(d+" messages enabled"));jq(a)}
|
||||
function Mq(a,b,c){var d=[],e;for(e=null;e=Db(a.V,"Disk",e);){var f=e,g=b,h=c,d=[];if(f.C)for(var k=0;k<f.C.length;k++){var l=f.C[k];if(l.gg==g&&(l=l.zd[h])){for(var n in l.we)f=l.we[n],d[f[1]]=f[0];break}}if(d.length)break}return d}function kq(a,b){a.ha=a;a.wc=a.Hk=1073741824;a.Pa=null;var c=br(a,b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(c.length)for(var d in vq)0<=ua(c,d)&&(a.wc|=vq[d],a.O(d+" messages enabled"));jq(a)}
|
||||
function Mk(a,b,c){for(var d in vq)if(b==vq[d]){a.$a[d]=c;break}}function dr(a,b){var c;a=a.toUpperCase();null==b?c=ua(tq,a):(c=ua(tq,a.substr(b,3)),0>c&&(c=ua(tq,a.substr(b,2))));return c}
|
||||
function er(a,b){var c=0,d=fr(a,b);if(void 0!==d)switch(b){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:c=2;break;case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 22:case 16:case 17:case 18:case 19:case 20:case 21:c=4;break;case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 56:c=8;break;case 23:c=a.Ja}return c?r(d,c):"??"}
|
||||
function fr(a,b){var c;if(0<=b){var d=a.F;switch(b){case 0:c=d.G&255;break;case 1:c=d.I&255;break;case 2:c=d.M&255;break;case 3:c=d.H&255;break;case 4:c=d.G>>8&255;break;case 5:c=d.I>>8&255;break;case 6:c=d.M>>8&255;break;case 7:c=d.H>>8&255;break;case 8:c=d.G&65535;break;case 9:c=d.I&65535;break;case 10:c=d.M&65535;break;case 11:c=d.H&65535;break;case 12:c=I(d)&65535;break;case 13:c=d.P&65535;break;case 14:c=d.K&65535;break;case 15:c=d.J&65535;break;case 22:c=K(d)&65535;break;case 23:c=wd(d);break;
|
||||
|
|
@ -760,50 +760,51 @@ Yq(a,g[1],!0);if(q)if(a.ua=q,void 0===g[2])a.O("begin assemble at "+Rq(q)),a.Ea=
|
|||
a.O("\tbc [a]\tclear breakpoint at addr [a]"),a.O("\tbl\tlist all breakpoints"),a.O("\tbn [n]\tbreak after [n] instruction(s)");else{var H=F.charAt(1);if("l"==H){var L=0,L=L+or(a,a.A),L=L+or(a,a.ra);(L+=or(a,a.ga))||a.O("no breakpoints")}else if("n"==H)a.Oa=Dq(a,v),a.O("break after "+a.Oa+" instruction(s)");else if(void 0===v)a.O("missing breakpoint address");else{var V={};if("*"!=v&&(V=Yq(a,v,!0,!0),!V))break a;v=null==V.Ra?v:u(V.Ra);"c"==H?null==V.Ra?(iq(a),a.O("all breakpoints cleared")):Qq(a,
|
||||
a.A,V)||Qq(a,a.ra,V)||Qq(a,a.ga,V)||a.O("breakpoint missing: "+Rq(V)):"i"==H?a.O("breakpoint "+(hc(a.ea,V.Ra)?"enabled":"cleared")+": port "+v+" (input)"):"o"==H?a.O("breakpoint "+(lc(a.ea,V.Ra)?"enabled":"cleared")+": port "+v+" (output)"):null!=V.Ra&&(ar(a,V,E),"p"==H?a.Td(a.A,V):"r"==H?a.Td(a.ra,V):"w"==H?a.Td(a.ga,V):a.O("unknown breakpoint command: "+H))}}}break;case "c":Er(a);break;case "d":a:{var P=g,bb,ia=P[0],ja=P[1],Ha=P[2],Xa=P[3];if("?"==ja){var Ba="";for(bb in vq)a.$a[bb]&&(Ba&&(Ba+=
|
||||
","),Ba+=bb);Ba+=",state,symbols";a.O("dump memory commands:");a.O("\tdb [a] [#] dump # bytes at address a");a.O("\tdw [a] [#] dump # words at address a");a.O("\tdd [a] [#] dump # dwords at address a");a.O("\tdh [#] [#] dump # instructions from history");a.O("\tdi [#] dump descriptor info for IDT #");a.O("\tds [#] dump descriptor info for selector #");Ba.length&&a.O("dump extension commands:\n\t"+Ba)}else if("state"==ja){var Vb=Mr(a.V,!0);"console"==Ha?console.log(Vb):(Er(a),
|
||||
a.O(Vb))}else if("symbols"==ja)for(var wa=0;wa<a.B.length;wa++){var Ud=a.B[wa],Qc;for(Qc in Ud.Sd)if("."!=Qc.charAt(0)){var Vd=Ud.Sd[Qc],Je=Vd.o;if(void 0!==Je){var Wd=Vd.s;void 0===Wd&&(Wd=Ud.Z);var Ke=Ud.Sd[Qc].l;Ke&&(Qc=Ke);a.O(Hq(Je,Wd)+" "+Qc)}}}else{if("ds"==ia||"dg"==ia||"dl"==ia)ia="d",P=[ia,"desc",ja];"d"==ia&&"page"==ja&&(ia="dp",P.shift());if("dp"==ia){P.shift();var ki=P[0];if(ki){var Ue=a.dc(Yq(a,ki));if(-1===Ue)a.O("invalid address: "+ki);else{var ae,Da=null;if(80386<=a.F.ja){var be=
|
||||
a.ea,Da={};Da.ck=(Ue&-4194304)>>>20;Da.vi=a.F.Pd+Da.ck;Da.yb=be.sa[(Da.vi&be.Hb)>>>be.La];Da.Vi=Da.yb.Nd(Da.ck);Da.dk=(Ue&4190208)>>>10;Da.wi=(Da.Vi&-4096)+Da.dk;Da.zb=be.sa[(Da.wi&be.Hb)>>>be.La];Da.Wi=Da.zb.Nd(Da.dk);Da.Gk=(Da.Wi&-4096)+(Ue&4095)}if(ae=Da){a.O("linear PDE addr PDE PTE addr PTE physical");a.O("--------- ---------- -------- ---------- -------- ----------");var pd="%"+r(Ue),pd=pd+(" %%"+cr(ae.vi,ae.Vi)),pd=pd+(" %%"+cr(ae.wi,ae.Wi,!0)),
|
||||
pd=pd+(" %%"+r(ae.Gk));a.O(pd)}else a.O("unsupported operation")}}else a.O("missing address")}else{if("d"==ia){if("disk"==ja){P[0]="l";P[1]="json";Ir(a,P);break a}for(bb in vq)if(P[1]==bb){var Dn=a.$a[bb];Dn?(P.shift(),P.shift(),Dn(P)):a.O("no dump registered for "+ja);break a}ja||(ia=a.Cc||"db")}else a.Cc=ia;if("dh"==ia){var En=ja,Fn=Ha,Gn="",Hn=0,tb=a.Fa,sc=a.ia;if(sc.length){var Db=+En||a.Ub,ce=+Fn||10;isNaN(Db)?Db=ce:Gn="more ";Db>sc.length&&(a.O("note: only "+sc.length+" available"),Db=sc.length);
|
||||
tb-=Db;0>tb&&(null==sc[sc.length-1].Z?(Db=tb+Db,tb=0):tb+=sc.length);var li=[];"call"==Fn&&(ce=1E5,li=["CALL"]);for(void 0!==En&&a.O(Db+" instructions earlier:");0<ce&&tb!=a.Fa;){var qd=sc[tb++];if(null==qd.Z)break;var Ve=hq(a,qd.Ra,qd.Z,qd.Da,qd.type,qd.Rb,qd.oc),fs=Db--,In=qr(a,Ve,"history",fs);(!li.length||0<=In.indexOf(li[0]))&&a.O(In);Ve.Te&&(tb+=Ve.Te,ce-=Ve.Te,Db-=Ve.Te);tb>=sc.length&&(tb=0);a.Ub=Db;Hn++;ce--}}Hn||(a.O("no "+Gn+"history available"),a.Ub=void 0)}else if("di"==ia){P.shift();
|
||||
var mi=P[0];if(mi){var We=Dq(a,mi);if(void 0===We||0>We||255<We)a.O("invalid vector: "+mi);else{var Jn="&",Kn=!!(a.F.Za&1),Ln=!1,pg=a.F.Mc+(We<<(Kn?3:2)),ni=a.F.na(pg+0),gs=a.F.na(pg+2);Kn&&(Jn="#",a.F.na(pg+4)&2048&&(Ln=!0,ni|=a.F.na(pg+6)<<16));a.O("dumpIDT("+u(We)+"): "+Jn+r(gs,4)+":"+r(ni,Ln?8:4))}}else a.O("no IDT vector")}else if("dt"==ia)P.shift(),a.O("no information");else{var de=Yq(a,ja);if(de&&(null!=de.Z||null!=de.Da)){var qg=0;Ha&&("l"==Ha.charAt(0)&&(Ha=Ha.substr(1)||Xa),qg=Dq(a,Ha)>>>
|
||||
0,65536<qg&&(qg=65536));for(var rd="",rg="dd"==ia?4:"dw"==ia?2:1,sg=rg*qg||128,hs=sg+15>>4||1;hs--&&0<sg;){var tg=0,oi=0,Xe,Ye="",pi="",ja=Rq(de);for(Xe=16;0<Xe&&0<sg;Xe--){var ug=a.Qa(de,1),tg=tg|ug<<(oi++<<3);oi==rg&&(Ye+=r(tg,2*rg),Ye+=1==rg?9==Xe?"-":" ":" ",tg=oi=0);pi+=32<=ug&&128>ug?String.fromCharCode(ug):".";sg--}rd&&(rd+="\n");rd+=ja+" "+Ye+(0==Xe?" "+pi:"")}rd&&a.O(rd);a.Db=de}}}}}break;case "e":if("else"==g[0])break;var vg=1,Mn=255,Nn=a.Qa,On=a.qc;"ew"==g[0]&&(vg=2,Mn=65535,Nn=a.na,
|
||||
a.O(Vb))}else if("symbols"==ja)for(var wa=0;wa<a.B.length;wa++){var Vd=a.B[wa],Qc;for(Qc in Vd.Sd)if("."!=Qc.charAt(0)){var Wd=Vd.Sd[Qc],Je=Wd.o;if(void 0!==Je){var Xd=Wd.s;void 0===Xd&&(Xd=Vd.Z);var Ke=Vd.Sd[Qc].l;Ke&&(Qc=Ke);a.O(Hq(Je,Xd)+" "+Qc)}}}else{if("ds"==ia||"dg"==ia||"dl"==ia)ia="d",P=[ia,"desc",ja];"d"==ia&&"page"==ja&&(ia="dp",P.shift());if("dp"==ia){P.shift();var ki=P[0];if(ki){var Ue=a.dc(Yq(a,ki));if(-1===Ue)a.O("invalid address: "+ki);else{var be,Da=null;if(80386<=a.F.ja){var ce=
|
||||
a.ea,Da={};Da.ck=(Ue&-4194304)>>>20;Da.vi=a.F.Pd+Da.ck;Da.yb=ce.sa[(Da.vi&ce.Hb)>>>ce.La];Da.Vi=Da.yb.Nd(Da.ck);Da.dk=(Ue&4190208)>>>10;Da.wi=(Da.Vi&-4096)+Da.dk;Da.zb=ce.sa[(Da.wi&ce.Hb)>>>ce.La];Da.Wi=Da.zb.Nd(Da.dk);Da.Gk=(Da.Wi&-4096)+(Ue&4095)}if(be=Da){a.O("linear PDE addr PDE PTE addr PTE physical");a.O("--------- ---------- -------- ---------- -------- ----------");var pd="%"+r(Ue),pd=pd+(" %%"+cr(be.vi,be.Vi)),pd=pd+(" %%"+cr(be.wi,be.Wi,!0)),
|
||||
pd=pd+(" %%"+r(be.Gk));a.O(pd)}else a.O("unsupported operation")}}else a.O("missing address")}else{if("d"==ia){if("disk"==ja){P[0]="l";P[1]="json";Ir(a,P);break a}for(bb in vq)if(P[1]==bb){var Dn=a.$a[bb];Dn?(P.shift(),P.shift(),Dn(P)):a.O("no dump registered for "+ja);break a}ja||(ia=a.Cc||"db")}else a.Cc=ia;if("dh"==ia){var En=ja,Fn=Ha,Gn="",Hn=0,tb=a.Fa,sc=a.ia;if(sc.length){var Eb=+En||a.Ub,de=+Fn||10;isNaN(Eb)?Eb=de:Gn="more ";Eb>sc.length&&(a.O("note: only "+sc.length+" available"),Eb=sc.length);
|
||||
tb-=Eb;0>tb&&(null==sc[sc.length-1].Z?(Eb=tb+Eb,tb=0):tb+=sc.length);var li=[];"call"==Fn&&(de=1E5,li=["CALL"]);for(void 0!==En&&a.O(Eb+" instructions earlier:");0<de&&tb!=a.Fa;){var qd=sc[tb++];if(null==qd.Z)break;var Ve=hq(a,qd.Ra,qd.Z,qd.Da,qd.type,qd.Rb,qd.oc),fs=Eb--,In=qr(a,Ve,"history",fs);(!li.length||0<=In.indexOf(li[0]))&&a.O(In);Ve.Te&&(tb+=Ve.Te,de-=Ve.Te,Eb-=Ve.Te);tb>=sc.length&&(tb=0);a.Ub=Eb;Hn++;de--}}Hn||(a.O("no "+Gn+"history available"),a.Ub=void 0)}else if("di"==ia){P.shift();
|
||||
var mi=P[0];if(mi){var We=Dq(a,mi);if(void 0===We||0>We||255<We)a.O("invalid vector: "+mi);else{var Jn="&",Kn=!!(a.F.Za&1),Ln=!1,pg=a.F.Mc+(We<<(Kn?3:2)),ni=a.F.na(pg+0),gs=a.F.na(pg+2);Kn&&(Jn="#",a.F.na(pg+4)&2048&&(Ln=!0,ni|=a.F.na(pg+6)<<16));a.O("dumpIDT("+u(We)+"): "+Jn+r(gs,4)+":"+r(ni,Ln?8:4))}}else a.O("no IDT vector")}else if("dt"==ia)P.shift(),a.O("no information");else{var ee=Yq(a,ja);if(ee&&(null!=ee.Z||null!=ee.Da)){var qg=0;Ha&&("l"==Ha.charAt(0)&&(Ha=Ha.substr(1)||Xa),qg=Dq(a,Ha)>>>
|
||||
0,65536<qg&&(qg=65536));for(var rd="",rg="dd"==ia?4:"dw"==ia?2:1,sg=rg*qg||128,hs=sg+15>>4||1;hs--&&0<sg;){var tg=0,oi=0,Xe,Ye="",pi="",ja=Rq(ee);for(Xe=16;0<Xe&&0<sg;Xe--){var ug=a.Qa(ee,1),tg=tg|ug<<(oi++<<3);oi==rg&&(Ye+=r(tg,2*rg),Ye+=1==rg?9==Xe?"-":" ":" ",tg=oi=0);pi+=32<=ug&&128>ug?String.fromCharCode(ug):".";sg--}rd&&(rd+="\n");rd+=ja+" "+Ye+(0==Xe?" "+pi:"")}rd&&a.O(rd);a.Db=ee}}}}}break;case "e":if("else"==g[0])break;var vg=1,Mn=255,Nn=a.Qa,On=a.qc;"ew"==g[0]&&(vg=2,Mn=65535,Nn=a.na,
|
||||
On=a.jb);var Pn=vg<<1,Qn=g[1];if(null==Qn)a.O("edit memory commands:"),a.O("\teb [a] [...] edit bytes at address a"),a.O("\tew [a] [...] edit words at address a");else{var wg=Yq(a,Qn);if(wg)for(var xg=2;xg<g.length;xg++){var Ze=$q(a,g[xg]);if(void 0===Ze){a.O("unrecognized value: "+g[xg]);break}Ze&~Mn&&a.O("warning: "+r(Ze)+" exceeds "+vg+"-byte value");var is=Nn.call(a,wg);a.O("changing "+Rq(wg)+" from 0x"+r(is,Pn)+" to 0x"+r(Ze,Pn));On.call(a,wg,Ze,vg)}}break;case "f":Fr(a,g[1]);break;case "g":a:{var Rn=
|
||||
g[1],js=b;"gt"==g[0]&&(a.cb=!0);if(void 0!==Rn){var qi=Yq(a,Rn,!0);if(!qi)break a;ar(a,qi,js);a.Td(a.A,qi,!0)}a.Le(!0)||c||a.O("cpu busy or unavailable, run command ignored")}break;case "h":a:{var ri;if(a.la.Fb)ri="halting",a.Wb();else{if(qb(a,!0))break a;ri="already halted"}c||a.O(ri)}break;case "i":if("if"==g[0]){var si;var $e=b.substr(2),$e=na($e);$q(a,$e)?(c||a.O("true: "+$e),si=!0):(c||a.O("false: "+$e),si=!1);si||(d=!1);break}if("int"==g[0]){var yg;a:switch(Dq(a,g[1])){case 19:kk(a,19,a.F.Ga,
|
||||
!0);a.ya=a.pa;yg=!0;break a;case 33:kk(a,33,a.F.Ga,!0);a.ya=a.pa;yg=!0;break a;default:yg=!1}yg||(d=!1);break}var ti=g[1];if(ti&&"?"!=ti){var ui=Dq(a,ti);if(void 0!==ui){var ks=jc(a.ea,ui,1);a.O(u(ui)+": "+t(ks))}}else a.O("input commands:"),a.O("\ti [p]\tread port [p]"),a.O("warning: port accesses can affect hardware state");break;case "k":var ls=g[0];if("?"==g[1])a.O("stack trace commands:"),a.O("\tk\tshow frame addresses"),a.O("\tks\tshow symbol information");else{var vi=0,Sn=a.F.va.Z,af=hq(a),
|
||||
Sc=hq(a,I(a.F),a.F.ta.Z);for(a.O("stack trace for "+Rq(Sc));10>vi;){for(var tc=null,ms=256;Sc.Ra>>>0<a.F.Mg>>>0;){af.Ra=a.tb(Sc,!0);if(null==Sc.Da||!ms--)break;af.Z=Sn;if(tc=Kr(a,af))break;af.Z=a.tb(Sc);if(tc=Kr(a,af,!0)){Sn=a.tb(Sc,!0);0<tc.indexOf("INT")&&a.tb(Sc,!0);break}}if(!tc||null==tc)break;var Tn=null;if("ks"==ls){var Un=tc.match(/[0-9A-F]+$/);Un&&(Tn=Hr(a,Un[0]))}tc=ma(tc,50)+" ;"+(Tn||"stack="+Rq(Sc));a.O(tc);vi++}vi||a.O("no return addresses found")}break;case "l":if("ln"==g[0]){Hr(a,
|
||||
g[1],!0);break}Ir(a,g);break;case "m":if("mouse"==g[0]){var wi=g[1],zg=g[2];if(a.W){var Vn=1;"-"==zg.charAt(0)&&(Vn=-1,zg=zg.substr(1));var sd=Dq(a,zg,wi);if(void 0!==sd)switch(sd=sd*Vn|0,wi){case "x":a.W.If(sd,0);break;case "y":a.W.If(0,sd);break;case "click":a.W.je(sd,!0);a.W.je(sd,!1);break;default:a.O("unknown action: "+wi)}}else a.O("no mouse");break}a:{var uc,vc=null,Oa=g[1];"?"==Oa&&(Oa=void 0);if(void 0!==Oa){var td=0;if("all"==Oa)td=1610481663,Oa=null;else if("on"==Oa)vc=!0,Oa=null;else if("off"==
|
||||
Oa)vc=!1,Oa=null;else{"keys"==Oa&&(Oa="key");"kbd"==Oa&&(Oa="keyboard");for(uc in vq)if(Oa==uc){td=vq[uc];vc=!!(a.wc&td);break}if(!td){a.O("unknown message category: "+Oa);break a}}td&&("on"==g[2]?(a.wc|=td,vc=!0):"off"==g[2]&&(a.wc&=~td,vc=!1))}var ns=0,Tc="";for(uc in vq)if(!Oa||Oa==uc){var os=!!(a.wc&vq[uc]);if(null===vc||vc==os)Tc&&(Tc+=","),++ns%10||(Tc+="\n\t"),"key"==uc&&(uc="keys"),Tc+=uc}void 0===Oa&&a.O("message commands:\n\tm [category] [on|off]\tturn categories on/off");a.O((null!==vc?
|
||||
vc?"messages on: ":"messages off: ":"message categories:\n\t")+(Tc||"none"));jq(a)}break;case "o":var xi=g[1],ps=g[2];if(xi&&"?"!=xi){var yi=Dq(a,xi,"port #"),zi=Dq(a,ps);void 0!==yi&&void 0!==zi&&(nc(a.ea,yi,1,zi),a.O(u(yi)+": "+t(zi)))}else a.O("output commands:"),a.O("\to [p] [b]\twrite byte [b] to port [p]"),a.O("warning: port accesses can affect hardware state");break;case "p":if("print"==g[0]){Jr(a,b.substr(5));break}var Wn="pr"==g[0]?1:0,ee=1+Wn;if(a.N)a.O("step in progress");else{var Ag,
|
||||
Xn=!1,lb=hq(a,K(a.F),a.F.va.Z);do switch(Ag=!1,a.Qa(lb)){case 38:case 46:case 54:case 62:case 100:case 101:case 102:case 103:case 240:Tq(a,lb,1);Ag=!0;break;case 204:case 206:a.N=ee;Tq(a,lb,1);break;case 205:case 224:case 225:case 226:a.N=ee;Tq(a,lb,lb.Rb?4:2);break;case 232:a.N=ee;Tq(a,lb,lb.Rb?5:3);break;case 154:a.N=ee;Tq(a,lb,lb.Rb?7:5);break;case 255:var Yn=a.tb(lb)&14591;if(4351==Yn||6399==Yn)a.N=ee,qr(a,lb);break;case 243:case 242:Tq(a,lb,1);Xn=Ag=!0;break;case 108:case 109:case 110:case 111:case 164:case 165:case 166:case 167:case 170:case 171:case 172:case 173:case 174:case 175:Xn&&
|
||||
(a.N=ee,Tq(a,lb,1))}while(Ag);a.N?(a.Td(a.A,lb,!0),a.Le()||(a.V&&a.V.yd(),a.N=0)):Lr(a,Wn?"tr":"t")}break;case "r":if("reset"==b){a.V&&a.V.reset();break}ir(a,g);break;case "t":Lr(a,g[0],g[1]);break;case "u":jr(a,g[1],g[2],8);break;case "v":if("var"==g[0]){Gr(a,b.substr(3))||(d=!1);break}a.O("PCx86 version 1.24.0 ("+a.F.ja+",RELEASE,NOPREFETCH"+(vb?",TYPEDARRAYS":",LONGARRAYS")+",NOBACKTRACK)");a.O(ya());break;case "x":a:if(g[1]&&"?"!=g[1])switch(g[1]){case "cs":var bf;void 0!==g[3]&&(bf=+g[3]);switch(g[2]){case "int":a.F.Y.kf=
|
||||
vc?"messages on: ":"messages off: ":"message categories:\n\t")+(Tc||"none"));jq(a)}break;case "o":var xi=g[1],ps=g[2];if(xi&&"?"!=xi){var yi=Dq(a,xi,"port #"),zi=Dq(a,ps);void 0!==yi&&void 0!==zi&&(nc(a.ea,yi,1,zi),a.O(u(yi)+": "+t(zi)))}else a.O("output commands:"),a.O("\to [p] [b]\twrite byte [b] to port [p]"),a.O("warning: port accesses can affect hardware state");break;case "p":if("print"==g[0]){Jr(a,b.substr(5));break}var Wn="pr"==g[0]?1:0,fe=1+Wn;if(a.N)a.O("step in progress");else{var Ag,
|
||||
Xn=!1,lb=hq(a,K(a.F),a.F.va.Z);do switch(Ag=!1,a.Qa(lb)){case 38:case 46:case 54:case 62:case 100:case 101:case 102:case 103:case 240:Tq(a,lb,1);Ag=!0;break;case 204:case 206:a.N=fe;Tq(a,lb,1);break;case 205:case 224:case 225:case 226:a.N=fe;Tq(a,lb,lb.Rb?4:2);break;case 232:a.N=fe;Tq(a,lb,lb.Rb?5:3);break;case 154:a.N=fe;Tq(a,lb,lb.Rb?7:5);break;case 255:var Yn=a.tb(lb)&14591;if(4351==Yn||6399==Yn)a.N=fe,qr(a,lb);break;case 243:case 242:Tq(a,lb,1);Xn=Ag=!0;break;case 108:case 109:case 110:case 111:case 164:case 165:case 166:case 167:case 170:case 171:case 172:case 173:case 174:case 175:Xn&&
|
||||
(a.N=fe,Tq(a,lb,1))}while(Ag);a.N?(a.Td(a.A,lb,!0),a.Le()||(a.V&&a.V.yd(),a.N=0)):Lr(a,Wn?"tr":"t")}break;case "r":if("reset"==b){a.V&&a.V.reset();break}ir(a,g);break;case "t":Lr(a,g[0],g[1]);break;case "u":jr(a,g[1],g[2],8);break;case "v":if("var"==g[0]){Gr(a,b.substr(3))||(d=!1);break}a.O("PCx86 version 1.24.0 ("+a.F.ja+",RELEASE,NOPREFETCH"+(vb?",TYPEDARRAYS":",LONGARRAYS")+",NOBACKTRACK)");a.O(ya());break;case "x":a:if(g[1]&&"?"!=g[1])switch(g[1]){case "cs":var bf;void 0!==g[3]&&(bf=+g[3]);switch(g[2]){case "int":a.F.Y.kf=
|
||||
bf;break;case "start":a.F.Y.Kf=bf;break;case "stop":a.F.Y.mf=bf;break;default:a.O("unknown cs option");break a}void 0!==bf&&Pc(a.F);a.O("checksums "+(a.F.la.Ze?"enabled":"disabled"));break;case "sp":void 0!==g[2]&&(Xc(a.F,+g[2])||a.O("warning: using 1x multiplier, previous target not reached"));a.O("target speed: "+(a.F.Y.Fe.toFixed(2)+"Mhz")+" ("+a.F.Y.Zd+"x)");break;default:a.O("unknown option: "+g[1])}else a.O("execution options:"),a.O("\tcs int #\tset checksum cycle interval to #"),a.O("\tcs start #\tset checksum cycle start count to #"),
|
||||
a.O("\tcs stop #\tset checksum cycle stop count to #"),a.O("\tsp #\t\tset speed multiplier to #");break;case "?":if(g[1]){Jr(a,b.substr(1));break}var cf="commands:",Ai;for(Ai in oq)cf+="\n"+ma(Ai,7)+oq[Ai];Tf(a)||(cf+="\nnote: frequency/history disabled if no exec breakpoints");a.O(cf);break;default:a.O("unknown command: "+b),d=!1}}}catch(Zn){a.O("debugger error: "+(Zn.stack||Zn.message)),d=!1}return d}function lq(a,b,c){b=br(a,b,c);for(var d in b)if(!pr(a,b[d]))return!1;return!0}
|
||||
Qa(function(){for(var a=nb(document,"pcx86","debugger"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new gq(d);mb(d,c)}});function hf(a,b,c){this.id=a.id;this.key=Nr(a,b,c);this.ha=a.ha;Or(this,a.hk)}function Nr(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
hf.prototype={constructor:hf,value:function(){return this[this.id]},data:function(){return this[this.id]},load:function(a){return a?(this[this.id]=a,this.A=!0):this.A?!0:Ca()&&(a=Ea(this.key))?(this[this.id]=a,this.A=!0):!1},toString:function(){var a=this[this.id];return"string"==typeof a?a:JSON.stringify(a)},clear:function(a){Or(this);var b=[];try{for(var c=0,d=window.localStorage.length;c<d;c++)b.push(window.localStorage.key(c))}catch(e){}for(c=0;c<b.length;c++)if((d=b[c])&&(a||d.substr(0,this.key.length)==
|
||||
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function Or(a,b){a[a.id]={};b&&N(a,"parms",b);a.A=!1}function Pr(a){var b=!0;if(Ca()){var c=JSON.stringify(a[a.id]);Fa(a.key,c)||(w("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function Qr(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){w(c.message||c),b=!1}return b}function Rr(a,b){return a[a.id][b]||null}function N(a,b,c){try{a[a.id][b]=c}catch(d){}}
|
||||
function Sr(a,b,c){Ua.call(this,"Computer",a,Sr,67108864);this.la.cc=!1;Tr(this,b);this.ga=Nc(this,"autoPower",a);this.N=0;this.ra=a.busWidth||a.buswidth;this.A=Ur;this.aa=null;this.W=this.pa=!1;this.ua=Nc(this,"url")||"";this.ya=(Math.random()+.1).toString(36).substr(2,12);this.B=Vr(this);if(this.F=ib("CPU",this.id)){this.ha=ib("Debugger",this.id);this.L=[];for(b=null;b=Eb(this,"Video",b);)this.L.push(b);this.ea=new Lb({id:this.ve+".bus",busWidth:this.ra},this.F,this.ha);var d,e=gb(this.id);if((this.C=
|
||||
ib("Panel",this.id))&&this.C.Ef)for(b=0;b<e.length;b++)d=e[b],d.Na=this.C.Na,d.O=this.C.O,d.Ef=this.C.Ef;this.O("PCx86 v1.24.0\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>");for(b=0;b<e.length;b++)d=e[b],d.Ic&&d.Ic(this,this.ea,this.F,this.ha);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.X=d:this.A=parseInt(d,10));var f;if(a=Nc(this,"state")||(f=!0,a.state))b=this.ia=a,f||(this.W=!0,this.A=Ur),this.A&&(this.fa=new hf(this,
|
||||
"1.24.0"),this.fa.load()?b=null:delete this.fa);!b&&this.A&&(b=Wr(this))&&(this.W=!0);if(b){var g=this;va(b,null,!0,function(a,b,c){c?(g.X=null,g.W=!1,g.Na("Unable to load machine state from server (error "+c+(b?": "+na(b):"")+")")):(g.aa=b,g.pa=!0);rb(g)})}else rb(this);this.qa.power||(this.ga=!0);!c&&this.ga&&Xr(this,this.ag)}else w("Unable to find CPU component")}db(Sr);var Ur=0;m=Sr.prototype;m.gf=function(){return this.ya};
|
||||
function Tr(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){w(d.message+" ("+c+")")}}a.U=b}function Nc(a,b,c){var d=b.toLowerCase(),d=Ya[b]||Ya[d];void 0===d&&a.U&&(d=a.U[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}m.ke=function(){return this.B||""};function Xr(a,b,c){for(var d=gb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!sb(f)){sb(f,function(){Xr(a,b,c)});return}}b.call(a,c)}
|
||||
function Yr(a,b){var c=new hf(a,"1.24.0","validate");if(c.load()&&Qr(c)){var d=Rr(c,"timestamp"),e=b?Rr(b,"timestamp"):"unknown";d!=e&&(a.Na("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
|
||||
m.ag=function(a){void 0===a&&(a=this.A||(this.aa?1:Ur));if(!this.N){this.N++;var b=!1,c=!1;this.ka=!1;var d=this.fa||new hf(this,"1.24.0");if(-1==a)b=!0;else if(a>Ur){if(d.load(this.aa)){this.V=new hf(this,"1.24.0","failsafe");this.V.load()&&(Zr(this,d),a=2,Or(this.V));N(this.V,"timestamp",qa());Pr(this.V);var e=this.A&&!this.W;if(1==a||za("Click OK to restore the previous PCx86 machine state, or CANCEL to reset the machine.")){if(c=Qr(d)){var f=Rr(d,"code"),g=Rr(d,"data");f&&("ok"==f?d.load(g):("error"==
|
||||
f&&"no machine state"!=g?(this.Na("Error: "+g),"unable to verify user"==g&&(Fa("user",""),this.B=null)):this.O(f+": "+g),Or(d),d.load()?(c=Qr(d),e=!0):c=!1))}e&&Yr(this,c?d:null)}else 2==a&&d.clear()}else Yr(this);delete this.aa;delete this.fa}e=gb(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.F&&(c=$r(this,g,d,b,c));b=[d,a,c];-1!=a?Xr(this,this.Ji,b):this.Ji(b)}};
|
||||
function $r(a,b,c,d,e){if(!b.la.cc){b.la.cc=!0;if(b.ic){var f=null;e&&((f=Rr(c,b.id))||(f=Rr(c,b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.ic(f,d)&&f&&(w("Unable to restore state for "+b.type),a.ia&&!a.pa?(c.clear(),a.A=Ur,window&&window.location.reload()):a.ka=!0,b.ic(null),e=!1)}if(!d&&b.uk)for(a=b.uk.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
m.Ji=function(a){var b=a[0],c=0>a[1];a=a[2];this.wa=!0;this.la.cc=!0;var d=this.qa.power;d&&(d.textContent="Shutdown");this.F&&($r(this,this.F,b,c,a),Uc(this.F));this.ka&&(Zr(this,b),b.clear());!c&&this.V&&(this.V.clear(),delete this.V);this.N=0};
|
||||
function Zr(a,b){if(za("There may be a problem with your PCx86 machine.\n\nTo help us diagnose it, click OK to send this PCx86 machine state to http://www.pcjs.org.")){var c=a.ke(),d=b.toString(),e={app:"PCx86",ver:"1.24.0"};e.url=a.ua;e.user=c;e.type="bug";e.data=d;va("http://www.pcjs.org/api/v1/report",e,!0)}}
|
||||
Qa(function(){for(var a=nb(document,"pcx86","debugger"),b=0;b<a.length;b++){var c=a[b],d=jb(c),d=new gq(d);mb(d,c)}});
|
||||
function Nr(a,b,c){Ua.call(this,"Computer",a,Nr,67108864);this.la.cc=!1;Or(this,b);this.ga=Nc(this,"autoPower",a);this.N=0;this.ra=a.busWidth||a.buswidth;this.A=Pr;this.aa=null;this.W=this.pa=!1;this.ua=Nc(this,"url")||"";this.ya=(Math.random()+.1).toString(36).substr(2,12);this.B=Qr(this);if(this.F=ib("CPU",this.id)){this.ha=ib("Debugger",this.id);this.L=[];for(b=null;b=Db(this,"Video",b);)this.L.push(b);this.ea=new Lb({id:this.ve+".bus",busWidth:this.ra},this.F,this.ha);var d,e=gb(this.id);if((this.C=
|
||||
ib("Panel",this.id))&&this.C.Ef)for(b=0;b<e.length;b++)d=e[b],d.Na=this.C.Na,d.O=this.C.O,d.Ef=this.C.Ef;this.O("PCx86 v1.24.0\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>");for(b=0;b<e.length;b++)d=e[b],d.Ic&&d.Ic(this,this.ea,this.F,this.ha);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.X=d:this.A=parseInt(d,10));var f;if(a=Nc(this,"state")||(f=!0,a.state))b=this.ia=a,f||(this.W=!0,this.A=Pr),this.A&&(this.fa=new hf(this,
|
||||
"1.24.0"),this.fa.load()?b=null:delete this.fa);!b&&this.A&&(b=Rr(this))&&(this.W=!0);if(b){var g=this;va(b,null,!0,function(a,b,c){c?(g.X=null,g.W=!1,g.Na("Unable to load machine state from server (error "+c+(b?": "+na(b):"")+")")):(g.aa=b,g.pa=!0);rb(g)})}else rb(this);this.qa.power||(this.ga=!0);!c&&this.ga&&Sr(this,this.ag)}else w("Unable to find CPU component")}db(Nr);var Pr=0;m=Nr.prototype;m.gf=function(){return this.ya};
|
||||
function Or(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){w(d.message+" ("+c+")")}}a.U=b}function Nc(a,b,c){var d=b.toLowerCase(),d=Ya[b]||Ya[d];void 0===d&&a.U&&(d=a.U[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}m.ke=function(){return this.B||""};function Sr(a,b,c){for(var d=gb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!sb(f)){sb(f,function(){Sr(a,b,c)});return}}b.call(a,c)}
|
||||
function Tr(a,b){var c=new hf(a,"1.24.0","validate");if(c.load()&&Ur(c)){var d=Vr(c,"timestamp"),e=b?Vr(b,"timestamp"):"unknown";d!=e&&(a.Na("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
|
||||
m.ag=function(a){void 0===a&&(a=this.A||(this.aa?1:Pr));if(!this.N){this.N++;var b=!1,c=!1;this.ka=!1;var d=this.fa||new hf(this,"1.24.0");if(-1==a)b=!0;else if(a>Pr){if(d.load(this.aa)){this.V=new hf(this,"1.24.0","failsafe");this.V.load()&&(Wr(this,d),a=2,Xr(this.V));N(this.V,"timestamp",qa());Yr(this.V);var e=this.A&&!this.W;if(1==a||za("Click OK to restore the previous PCx86 machine state, or CANCEL to reset the machine.")){if(c=Ur(d)){var f=Vr(d,"code"),g=Vr(d,"data");f&&("ok"==f?d.load(g):("error"==
|
||||
f&&"no machine state"!=g?(this.Na("Error: "+g),"unable to verify user"==g&&(Fa("user",""),this.B=null)):this.O(f+": "+g),Xr(d),d.load()?(c=Ur(d),e=!0):c=!1))}e&&Tr(this,c?d:null)}else 2==a&&d.clear()}else Tr(this);delete this.aa;delete this.fa}e=gb(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.F&&(c=Zr(this,g,d,b,c));b=[d,a,c];-1!=a?Sr(this,this.Ji,b):this.Ji(b)}};
|
||||
function Zr(a,b,c,d,e){if(!b.la.cc){b.la.cc=!0;if(b.ic){var f=null;e&&((f=Vr(c,b.id))||(f=Vr(c,b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.ic(f,d)&&f&&(w("Unable to restore state for "+b.type),a.ia&&!a.pa?(c.clear(),a.A=Pr,window&&window.location.reload()):a.ka=!0,b.ic(null),e=!1)}if(!d&&b.uk)for(a=b.uk.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
m.Ji=function(a){var b=a[0],c=0>a[1];a=a[2];this.wa=!0;this.la.cc=!0;var d=this.qa.power;d&&(d.textContent="Shutdown");this.F&&(Zr(this,this.F,b,c,a),Uc(this.F));this.ka&&(Wr(this,b),b.clear());!c&&this.V&&(this.V.clear(),delete this.V);this.N=0};
|
||||
function Wr(a,b){if(za("There may be a problem with your PCx86 machine.\n\nTo help us diagnose it, click OK to send this PCx86 machine state to http://www.pcjs.org.")){var c=a.ke(),d=b.toString(),e={app:"PCx86",ver:"1.24.0"};e.url=a.ua;e.user=c;e.type="bug";e.data=d;va("http://www.pcjs.org/api/v1/report",e,!0)}}
|
||||
function Mr(a,b,c){var d,e="none";if(a.N)return null;a.N--;var f=new hf(a,"1.24.0"),g=new hf(a,"1.24.0","validate"),h=qa();N(g,"timestamp",h);N(f,"timestamp",h);N(f,"version","1.24.0");N(f,"url",window?window.location.href:null);N(f,"browser",ya());a.F&&a.F.hc&&(c&&a.F.Wb(),d=a.F.hc(b,c),"object"===typeof d&&N(f,a.F.id,d),c&&(a.F.la.cc=!1,!1===d&&(e=null)));for(var h=gb(a.id),k=0;k<h.length;k++){var l=h[k];l.la.cc&&(l.hc&&(d=l.hc(b,c),"object"===typeof d&&N(f,l.id,d)),c&&(l.la.cc=!1,!1===d&&(e=null)))}e&&
|
||||
(c?(h=d=!1,b?(a.B&&as(a,a.B,f.toString()),Pr(g)&&Pr(f)||(e=null,d=h=!0)):a.A&&(d=!0,h=3==a.A),d&&f.clear(h)):e=f.toString());c&&(a.la.cc=!1,b=a.qa.power)&&(b.textContent="Power");a.N=0;return e}m.reset=function(){this.ea&&this.ea.reset&&(y(this,"Resetting "+this.ea.type),this.ea.reset());for(var a=gb(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.ea&&c.reset&&(y(this,"Resetting "+c.type),c.reset())}};
|
||||
(c?(h=d=!1,b?(a.B&&$r(a,a.B,f.toString()),Yr(g)&&Yr(f)||(e=null,d=h=!0)):a.A&&(d=!0,h=3==a.A),d&&f.clear(h)):e=f.toString());c&&(a.la.cc=!1,b=a.qa.power)&&(b.textContent="Power");a.N=0;return e}m.reset=function(){this.ea&&this.ea.reset&&(y(this,"Resetting "+this.ea.type),this.ea.reset());for(var a=gb(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.ea&&c.reset&&(y(this,"Resetting "+c.type),c.reset())}};
|
||||
m.start=function(a,b){for(var c=gb(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}};m.stop=function(a,b){for(var c=gb(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.stop&&e.stop(a,b)}};
|
||||
m.Pb=function(a,b,c){var d=this;switch(b){case "power":return this.qa[b]=c,c.onclick=function(){d.N||(d.la.cc?Mr(d,!1,!0):Xr(d,d.ag))},!0;case "reset":return this.qa[b]=c,c.onclick=function(){if(d.la.cc&&!d.N)if(d.A&&!d.X){var a=za("Click OK to save changes to this PCx86 machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");Mr(d,a,!0);!a&&d.ia?window&&window.location.reload():(a||(d.eh=!0),d.ag(Ur),d.eh=!1)}else d.reset(),d.F&&Uc(d.F)},!0;case "save":if(ha(xa(),"pcjs.org")){c.parentNode.removeChild(c);
|
||||
break}this.qa[b]=c;c.onclick=function(){var a=Vr(d,!0);if(a){var b=!!(d.A&&!d.X||d.ia),c=Mr(d,b);b?as(d,a,c):d.Na("Resume disabled, machine state not saved")}};return!0}return!1};
|
||||
function Vr(a,b){var c=a.B;c||(c=Ea("user"),void 0!==c?!c&&b&&(c=null,window&&(c=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c&&((c=bs(a,c))||a.Na("The user ID is invalid."))):b&&a.Na("Browser local storage is not available"));return c}
|
||||
function bs(a,b){a.B=null;var c=va(xa()+"/api/v1/user?req=verify&user="+b),d=c[1];if(!c[0]&&d)try{c=eval("("+d+")"),c.code&&"ok"==c.code&&(Fa("user",c.data),a.B=c.data)}catch(e){w(e.message+" ("+d+")")}return a.B}function Wr(a){var b=null;a.B&&(b=xa()+"/api/v1/user?req=load&user="+a.B+"&state="+Nr(a,"1.24.0"));return b}
|
||||
function as(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=Nr(a,"1.24.0");d.data=c;b=va(xa()+"/api/v1/user",d);d=b[0];if(b[1]){if(d){var e=d.indexOf("\n");0<e&&(d=d.substr(0,e));d.indexOf("Error: ")||(d=d.substr(7))}d='{"code":'+b[1]+',"data":"'+d+'"}'}b=JSON.parse(d);b&&"ok"==b.code?a.Na("Machine state saved to server"):c&&(c=b&&b.data||"unable to save machine state",c="error"==b.code?"Error: "+c:"Error "+b.code+": "+c,a.Na(c),Fa("user",""),a.B=null)}}
|
||||
function Eb(a,b,c){a=gb(a.id);for(var d=0;d<a.length;d++){var e=a[d];if(c)c==e&&(c=null);else if(e.type==b)return e}return null}m.yd=function(a){if(this.L.length){var b=0,c=0;a&&window&&(b=window.scrollX,c=window.scrollY);var d=this.L[0];d.V&&d.V.focus();a&&window&&window.scrollTo(b,c)}};m.qd=function(a){this.F&&this.F.qd(a);this.C&&this.C.qd(a)};
|
||||
m.Pb=function(a,b,c){var d=this;switch(b){case "power":return this.qa[b]=c,c.onclick=function(){d.N||(d.la.cc?Mr(d,!1,!0):Sr(d,d.ag))},!0;case "reset":return this.qa[b]=c,c.onclick=function(){if(d.la.cc&&!d.N)if(d.A&&!d.X){var a=za("Click OK to save changes to this PCx86 machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");Mr(d,a,!0);!a&&d.ia?window&&window.location.reload():(a||(d.eh=!0),d.ag(Pr),d.eh=!1)}else d.reset(),d.F&&Uc(d.F)},!0;case "save":if(ha(xa(),"pcjs.org")){c.parentNode.removeChild(c);
|
||||
break}this.qa[b]=c;c.onclick=function(){var a=Qr(d,!0);if(a){var b=!!(d.A&&!d.X||d.ia),c=Mr(d,b);b?$r(d,a,c):d.Na("Resume disabled, machine state not saved")}};return!0}return!1};
|
||||
function Qr(a,b){var c=a.B;c||(c=Ea("user"),void 0!==c?!c&&b&&(c=null,window&&(c=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c&&((c=as(a,c))||a.Na("The user ID is invalid."))):b&&a.Na("Browser local storage is not available"));return c}
|
||||
function as(a,b){a.B=null;var c=va(xa()+"/api/v1/user?req=verify&user="+b),d=c[1];if(!c[0]&&d)try{c=eval("("+d+")"),c.code&&"ok"==c.code&&(Fa("user",c.data),a.B=c.data)}catch(e){w(e.message+" ("+d+")")}return a.B}function Rr(a){var b=null;a.B&&(b=xa()+"/api/v1/user?req=load&user="+a.B+"&state="+bs(a,"1.24.0"));return b}
|
||||
function $r(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=bs(a,"1.24.0");d.data=c;b=va(xa()+"/api/v1/user",d);d=b[0];if(b[1]){if(d){var e=d.indexOf("\n");0<e&&(d=d.substr(0,e));d.indexOf("Error: ")||(d=d.substr(7))}d='{"code":'+b[1]+',"data":"'+d+'"}'}b=JSON.parse(d);b&&"ok"==b.code?a.Na("Machine state saved to server"):c&&(c=b&&b.data||"unable to save machine state",c="error"==b.code?"Error: "+c:"Error "+b.code+": "+c,a.Na(c),Fa("user",""),a.B=null)}}
|
||||
function Db(a,b,c){a=gb(a.id);for(var d=0;d<a.length;d++){var e=a[d];if(c)c==e&&(c=null);else if(e.type==b)return e}return null}m.yd=function(a){if(this.L.length){var b=0,c=0;a&&window&&(b=window.scrollX,c=window.scrollY);var d=this.L[0];d.V&&d.V.focus();a&&window&&window.scrollTo(b,c)}};m.qd=function(a){this.F&&this.F.qd(a);this.C&&this.C.qd(a)};
|
||||
function cd(a,b){for(var c=0;c<a.L.length;c++)rn(a.L[c],b);if(a.C&&(c=a.C,c.Ja)){Ib(c,18,c.aa,c.Ia);if(c.gb){var d=c.ea,e=c.A,f,g;null==f&&(f=0);null==g&&(g=d.X-f|0);null==e&&(e={ah:0,Vd:0,Sg:[]});var h=f>>>d.La;f=f+g-1>>>d.La;e.ah=0;for(e.Vd=0;h<=f;)g=d.sa[h],e.ah+=g.size,g.size&&(e.Sg.push(sa(Hb,h,0,0,g.type)),e.Vd++),h++;c.A=e;c.ya=c.A.Vd*c.ea.Sb/691200;d=0;c.A.Bi=0;c.A.Bf||(c.A.Bf=[]);var e=-1,h=0,k=-1;for(f=0;f<c.A.Vd;f++){var l=c.A.Sg[f];g=ta(Hb.type,l);l=ta(Hb.ak,l);if(g!=e||l!=k+1)(k=f-h)&&
|
||||
(d+=Kb(c,h,k,e)),e=g,h=f;k=l}d+=Kb(c,h,f-h,e);e=c.A.Lk!=d;c.A.Lk=d;if(e){e=new Bb(0,0,c.aa.width,c.aa.height);c.A.Qe=[];h=c.A.Vd;for(d=0;d<c.A.Bi;d++)f=c.A.Bf[d].Vd,c.A.Qe.push(Cb(e,f,h,!d)),h-=f;for(d=0;d<c.A.Qe.length;d++)e=c.A.Bf[d],h=f=c.A.Qe[d],g=c.Ia,(k=xc[e.type])||(k=new Ab),g.strokeStyle="black",g.strokeRect(h.x,h.y,h.ad,h.A),g.fillStyle="string"==typeof k?k:k.toString(),g.fillRect(h.x,h.y,h.ad,h.A),h=c,g=f,h.ga=h.ua,h.X=h.wa,f=g.x+(g.ad>>1),k=g.y+(g.A>>1),l=g.A,g.ad<g.A&&(l=g.ad,h.ra=!0,
|
||||
h.N.save(),h.N.translate(f,k),h.N.rotate(-Math.PI/2),f=k=0),l<h.X&&(h.X=l,h.ga=h.X+"px Monaco, Lucida Console, Courier New"),g=k,h.C=f,h.U=g,h=c,e=Wb[e.type]+" ("+(e.Vd*c.ea.Sb/1024|0)+"Kb)",h.N.font=h.ga,h.C-=h.N.measureText(e).width>>1,h.U+=(h.X>>1)-2,Jb(h,e),h.ra&&(h.N.restore(),h.ra=!1)}}else Jb(c,"This space intentionally left blank");c.context.drawImage(c.aa,0,0,c.aa.width,c.aa.height,c.sb,c.Jb,c.$a,c.fb);c.Ja=!1}}
|
||||
Qa(function(){for(var a=nb(document,"pcx86-machine"),b=0;b<a.length;b++)for(var c=a[b],d=jb(c),c=nb(c,"pcx86","computer"),e=0;e<c.length;e++){var f=c[e],g=jb(f),g=new Sr(g,d,!0);mb(g,f);g.ga&&Xr(g,g.ag)}});La.show.push(function(){for(var a=nb(document,"pcx86","computer"),b=0;b<a.length;b++){var c=jb(a[b]);(c=ib("Computer",c.id))&&c.wa&&!c.la.cc&&c.ag(-1)}});
|
||||
La.exit.push(function(){for(var a=nb(document,"pcx86","computer"),b=0;b<a.length;b++){var c=jb(a[b]);(c=ib("Computer",c.id))&&c.la.cc&&Mr(c,!(!c.A||c.X),!0)}});var cs=0;function ds(a,b,c,d,e,f){e("Loading "+a+"...");va(a,null,!0,function(g,h,k){k?(h||(h="unable to load "+a+" ("+k+")"),f(h,null)):es(h,a,b,c,d,e,f)})}
|
||||
Qa(function(){for(var a=nb(document,"pcx86-machine"),b=0;b<a.length;b++)for(var c=a[b],d=jb(c),c=nb(c,"pcx86","computer"),e=0;e<c.length;e++){var f=c[e],g=jb(f),g=new Nr(g,d,!0);mb(g,f);g.ga&&Sr(g,g.ag)}});La.show.push(function(){for(var a=nb(document,"pcx86","computer"),b=0;b<a.length;b++){var c=jb(a[b]);(c=ib("Computer",c.id))&&c.wa&&!c.la.cc&&c.ag(-1)}});
|
||||
La.exit.push(function(){for(var a=nb(document,"pcx86","computer"),b=0;b<a.length;b++){var c=jb(a[b]);(c=ib("Computer",c.id))&&c.la.cc&&Mr(c,!(!c.A||c.X),!0)}});function hf(a,b,c){this.id=a.id;this.key=bs(a,b,c);this.ha=a.ha;Xr(this,a.hk)}function bs(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
hf.prototype={constructor:hf,value:function(){return this[this.id]},data:function(){return this[this.id]},load:function(a){return a?(this[this.id]=a,this.A=!0):this.A?!0:Ca()&&(a=Ea(this.key))?(this[this.id]=a,this.A=!0):!1},toString:function(){var a=this[this.id];return"string"==typeof a?a:JSON.stringify(a)},clear:function(a){Xr(this);var b=[];try{for(var c=0,d=window.localStorage.length;c<d;c++)b.push(window.localStorage.key(c))}catch(e){}for(c=0;c<b.length;c++)if((d=b[c])&&(a||d.substr(0,this.key.length)==
|
||||
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function Xr(a,b){a[a.id]={};b&&N(a,"parms",b);a.A=!1}function Yr(a){var b=!0;if(Ca()){var c=JSON.stringify(a[a.id]);Fa(a.key,c)||(w("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function Ur(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){w(c.message||c),b=!1}return b}function Vr(a,b){return a[a.id][b]||null}function N(a,b,c){try{a[a.id][b]=c}catch(d){}}var cs=0;
|
||||
function ds(a,b,c,d,e,f){e("Loading "+a+"...");va(a,null,!0,function(g,h,k){k?(h||(h="unable to load "+a+" ("+k+")"),f(h,null)):es(h,a,b,c,d,e,f)})}
|
||||
function es(a,b,c,d,e,f,g){function h(a,f){if(f)g(f,null);else{if(c){fb(c,b,a);var h=b;h&&0>h.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(h=window.location.pathname+h);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1<d.length&&(d+=",")):d='{state:"'+d+'",':d="{";d+='url:"'+h+'"}';"object"==typeof resources&&(h=null);a=a.replace(/(<machine[^>]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(h?' url="'+h+'"':""))}e||(a=a.replace(/(<xsl:variable name="APPCLASS">).*?(<\/xsl:variable>)/,"$1pcx86$2"));
|
||||
h=null;if("<"==a.charAt(0))try{e||(a=a.replace(/<!DOCTYPE(.|[\r\n])*]>\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(h=new window.ActiveXObject("Microsoft.XMLDOM"),h.async=!1,h.loadXML(a)):h=(new window.DOMParser).parseFromString(a,"text/xml")}catch(q){h=null,a=q.message}else a="unrecognized XML: "+(255<a.length?a.substr(0,255)+"...":a);g(a,h)}}a?e?qs(a,f,h):h(a,null):g("no data"+(b?" for file: "+b:""),null)}
|
||||
function qs(a,b,c){var d;if(d=/<([a-z]+)\s+ref="(.*?)"(.*?)\/>/g.exec(a)){var e=d[2];b("Loading "+e+"...");va(e,null,!0,function(f,g,h){if(h||!g)c(a,"unable to resolve XML reference: "+d[0]+" ("+h+")");else{if(f=d[3])if(h=g.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var k=h[0],l,n=/( [a-z]+=)(['"])(.*?)\2/g;l=n.exec(f);)k=0>k.indexOf(l[1])?k.replace(">",l[0]+">"):k.replace(new RegExp(l[1]+"(['\"])(.*?)\\1"),l[0]);h[0]!=k&&(g=g.replace(h[0],k))}else{c(a,"missing <"+d[1]+"> in "+e);return}g=g.replace(/<\?xml[^>]*>[\r\n]*/,
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ function p(a){window&&window.alert(a)}function ra(a){var b=!1;window&&(b=window.
|
|||
function xa(a,b){try{return window.localStorage.setItem(a,b),!0}catch(c){}return!1}function ya(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}
|
||||
function za(a,b,c,d){var e=null;b="data:application/"+b+(c?";base64":"")+",";b=ya("Firefox")?b+(c?a:encodeURIComponent(a)):b+(c?a:encodeURI(a));d&&(e=document.createElement("a"),"string"!=typeof e.download&&(e=null));e?(e.href=b,e.download=d,document.body.appendChild(e),e.click(),document.body.removeChild(e),a="Check your Downloads folder for "+d+"."):(window.open(b),a="Check your browser for a new window/tab containing the requested data"+(d?" ("+d+")":"")+".");return a}
|
||||
var Aa={init:[],show:[],exit:[]},Ba=!1,Ca=!0;function Da(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function Ea(a){Aa.init.push(a)}function Fa(a){if(Ca)try{for(var b=0;b<a.length;b++)a[b]()}catch(c){p(""+("An unexpected exception occurred:\n\n"+c.message+"\n\nPlease send this information to support@pcjs.org. Thanks."))}}function Ga(a){!Ca&&a?(Ca=!0,Ba&&Ha("init")):Ca=a}function Ha(a){Aa[a]&&Fa(Aa[a])}Da("onload",function(){Ba=!0;Fa(Aa.init)});
|
||||
Da("onpageshow",function(){Fa(Aa.show)});Da(ya("Opera")||ya("iOS")?"onunload":"onbeforeunload",function(){Fa(Aa.exit)});function Ia(a,b,c){this.type=a;b||(b={id:"",name:""});this.id=b.id;this.name=b.name;this.Ah=b.comment;this.gj=b;void 0===this.id&&(this.id="");b=this.id.indexOf(".");0<b?(this.mf=this.id.substr(0,b),this.ye=this.id.substr(b+1)):this.ye=this.id;this[a]=c;this.da={ne:!1,Qc:!1,ig:!1,Sb:!1,Yc:!1};this.Cf=null;this.da.Yc=!1;this.ka={};this.Ia=null;Ja.push(this)}var Ka=void 0,La={};
|
||||
Da("onpageshow",function(){Fa(Aa.show)});Da(ya("Opera")||ya("iOS")?"onunload":"onbeforeunload",function(){Fa(Aa.exit)});function Ia(a,b,c){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.Ah=b.comment;this.gj=b;b=this.id.indexOf(".");0>b?this.ye=this.id:(this.mf=this.id.substr(0,b),this.ye=this.id.substr(b+1));this[a]=c;this.da={ne:!1,Qc:!1,ig:!1,Sb:!1,Yc:!1};this.Cf=null;this.da.Yc=!1;this.ka={};this.Ia=null;Ja.push(this)}var Ka=void 0,La={};
|
||||
if(window){Ka||(Ka=window.location.search.substr(1));for(var Ma,Na=/\+/g,Oa=/([^&=]+)=?([^&]*)/g;Ma=Oa.exec(Ka);)La[decodeURIComponent(Ma[1].replace(Na," "))]=decodeURIComponent(Ma[2].replace(Na," "))}function Pa(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b}
|
||||
function Qa(a,b){b||(b=Ia);a.prototype=Pa(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}var Ja=[],Ra={};function Sa(a,b,c){Ra[a]&&b&&(Ra[a][b]=c)}function Ta(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<Ja.length;b++){var d=Ja[b];a&&d.id.indexOf(a)||c.push(d)}return c}function Ua(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;c<Ja.length;c++)if(Ja[c].id===a)return Ja[c]}return null}
|
||||
function Va(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<Ja.length;d++)if(c)c==Ja[d]&&(c=null);else if(!(a!=Ja[d].type||b&&Ja[d].id.indexOf(b)))return Ja[d]}return null}function Wa(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){p(c.message+" ("+a+")")}return b}function Xa(a,b,c){var d;b&&(void 0===d&&(d="Panel"),(d=Va(d,a.id))&&(b=d.ka[b])&&a.zb(null,c,b))}
|
||||
function Ya(a,b){for(var c=Za(b.parentNode,"pcx86-control"),d=0;d<c.length;d++)for(var e=c[d].childNodes,f=0;f<e.length;f++){var g=e[f];if(1===g.nodeType){var h=g.getAttribute("class");if(h)for(var k=h.split(" "),m=0;m<k.length;m++)switch(h=k[m],h){case "pcx86-binding":(h=Wa(g))&&h.binding&&a.zb(h.type,h.binding,g,h.value),m=k.length}}}}
|
||||
function Qa(a,b){b||(b=Ia);a.prototype=Pa(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={Machines:{},Components:[]});var Ra=window.PCjs.Machines,Ja=window.PCjs.Components}else Ra={},Ja=[];function Sa(a,b,c){Ra[a]&&b&&(Ra[a][b]=c)}function Ta(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<Ja.length;b++){var d=Ja[b];a&&d.id.indexOf(a)||c.push(d)}return c}
|
||||
function Ua(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;c<Ja.length;c++)if(Ja[c].id===a)return Ja[c]}return null}function Va(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<Ja.length;d++)if(c)c==Ja[d]&&(c=null);else if(!(a!=Ja[d].type||b&&Ja[d].id.indexOf(b)))return Ja[d]}return null}function Wa(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){p(c.message+" ("+a+")")}return b}
|
||||
function Xa(a,b,c){var d;b&&(void 0===d&&(d="Panel"),(d=Va(d,a.id))&&(b=d.ka[b])&&a.zb(null,c,b))}function Ya(a,b){for(var c=Za(b.parentNode,"pcx86-control"),d=0;d<c.length;d++)for(var e=c[d].childNodes,f=0;f<e.length;f++){var g=e[f];if(1===g.nodeType){var h=g.getAttribute("class");if(h)for(var k=h.split(" "),m=0;m<k.length;m++)switch(h=k[m],h){case "pcx86-binding":(h=Wa(g))&&h.binding&&a.zb(h.type,h.binding,g,h.value),m=k.length}}}}
|
||||
function Za(a,b,c){c&&(b+="-"+c+"-object");if(a.getElementsByClassName)return a.getElementsByClassName(b);var d;c=[];a=a.getElementsByTagName("*");var e=new RegExp("(^| )"+b+"( |$)");b=0;for(d=a.length;b<d;b++)e.test(a[b].className)&&c.push(a[b]);return c}
|
||||
Ia.prototype={constructor:Ia,parent:null,toString:function(){return this.name?this.name:this.id||this.type},zb:function(a,b,c){switch(b){case "clear":return this.ka[b]||(this.ka[b]=c,c.onclick=function(a){return function(){a.ka.print&&(a.ka.print.value="")}}(this)),!0;case "print":return this.ka[b]||(this.hg=this.ka[b]=c,c.value="",this.rc=function(a){return function(b,c){8192<a.value.length&&(a.value=a.value.substr(a.value.length-4096));a.value+=(void 0!==c?c+": ":"")+(b||"")+"\n";a.scrollTop=a.scrollHeight}}(c),
|
||||
this.Ba=function(a){this.rc(a,this.ye)}),!0;default:return!1}},log:function(){},rc:function(){},status:function(a){this.rc(this.ye+": "+a)},Ba:function(a,b,c){c=c||this.type;b||p((c?c+": ":"")+a)},Vb:function(){return this.da.Sb=!0},Ub:function(a,b){b&&(this.da.Sb=!1);return!0}};function $a(a,b){if(a.da.ig)return a.da.Qc&&(a.da.Qc=!1),a.da.ig=!1;if(a.da.Yc)return a.rc(a.toString()+" error"),!1;a.da.Qc=b;return a.da.Qc}
|
||||
|
|
@ -74,8 +74,8 @@ z&&(n=a.sb,W=b==e.Ab+c,E<=J&&(!W||0<=e.fc||n<=J))){b=k&65535;h&2048&&(f=x|m<<16)
|
|||
Ic(e,e.Xa.ja,4,2),e.Xa.load(0),Ic(e,e.Ta.ja,4,2),e.Ta.load(0),Ic(e,e.xa.ja,4,2),Jc(e,0),Ic(e,e.pa.ja,4,2),Kc(e,0));Ic(e,r,e.U,2);for(y(e,g);f;)y(e,a.H[--f]);a.pe=!0}return a.ya}if(0!=z)return t.call(e,13,c&65532|(W?2:0)),-1;if(!(g&32768))return t.call(e,11,c&65532|(W?2:0)),-1;break;case 2:if(n){if(4096>h||2048==(h&2560))return t.call(e,13,c&65532),-1;if(!(g&32768))return t.call(e,11,c&65532),-1}break;case 3:if(!n||4096>h||512!=(h&2560))return t.call(e,13,c&65532),-1;if(!(g&32768))return t.call(e,
|
||||
12,c&65532),-1;break;case 4:r=h&-513;if(!n||256!=r&&2304!=r)return t.call(e,13,c&65532),-1;2304==r&&(a.Eh=k+e.ga(k+100+2)|0,a.zj=k+a.Za|0);break;case 6:if(!(h&4096)&&768<h&&2304!=h&&2816!=h)return-1}d?(a.B.ja=c,a.B.ya=k,a.B.Za=f,a.B.lb=g,a.B.type=h,a.B.ext=m,a.B.hc=b):(a.ja=c,a.ya=k,a.Za=f,a.C=(f>>>0)+1,a.lb=g,a.type=h,a.ext=m,a.hc=b,zc(a,!0,!0,!1));return k}
|
||||
function Ec(a,b,c){var d=a.A,e=a.sb,f=d.ia.ja,g=d.ia.ya;if(!c){if(!(d.ia.type&512))return t.call(d,13,b&65532),!1;d.bb(d.ia.hc+4,d.ia.lb&=-513)}if(-1===d.ia.load(b))return!1;var h=d.ia.ya;if(!1!==c){if(d.ia.type&512)return t.call(d,13,b&65532),!1;d.bb(d.ia.hc+4,d.ia.lb|=512)}d.ia.type=d.ia.type&-513|d.ia.lb&512;256==d.ia.type||768==d.ia.type?(d.bb(g+14,A(d)),d.bb(g+16,Lc(d)),d.bb(g+18,d.J),d.bb(g+20,d.G),d.bb(g+22,d.M),d.bb(g+24,d.D),d.bb(g+26,w(d)),d.bb(g+28,d.K),d.bb(g+30,d.I),d.bb(g+32,d.H),d.bb(g+
|
||||
34,d.pa.ja),d.bb(g+36,d.Ca.ja),d.bb(g+38,d.P.ja),d.bb(g+40,d.xa.ja),d.Zb.load(d.ga(h+42)),Mc(d,d.ga(h+16)|(c?16384:0)),d.J=d.ga(h+18),d.G=d.ga(h+20),d.M=d.ga(h+22),d.D=d.ga(h+24),d.K=d.ga(h+28),d.I=d.ga(h+30),d.H=d.ga(h+32),d.pa.load(d.ga(h+34)),d.xa.load(d.ga(h+40)),Oc(d,d.ga(h+14),d.ga(h+36)),b=38,g=26,a.sb<e&&(g=(a.sb<<2)+2,b=g+2),Dc(d,d.ga(h+b),!0),v(d,d.ga(h+g))):(d.Va(g+28,d.dd),d.Va(g+32,A(d)),d.Va(g+36,Lc(d)),d.Va(g+40,d.J),d.Va(g+44,d.G),d.Va(g+48,d.M),d.Va(g+52,d.D),d.Va(g+56,w(d)),d.Va(g+
|
||||
60,d.K),d.Va(g+64,d.I),d.Va(g+68,d.H),d.Va(g+72,d.pa.ja),d.Va(g+76,d.Ca.ja),d.Va(g+80,d.P.ja),d.Va(g+84,d.xa.ja),d.Va(g+88,d.Ta.ja),d.Va(g+92,d.Xa.ja),Pc.call(d,d.fa(h+28)),d.Zb.load(d.ga(h+96)),Mc(d,d.fa(h+36)|(c?16384:0)),d.J=d.fa(h+40),d.G=d.fa(h+44),d.M=d.fa(h+48),d.D=d.fa(h+52),d.K=d.fa(h+60),d.I=d.fa(h+64),d.H=d.fa(h+68),d.pa.load(d.ga(h+72)),d.xa.load(d.ga(h+84)),d.Ta.load(d.ga(h+88)),d.Xa.load(d.ga(h+92)),Oc(d,d.fa(h+32),d.ga(h+76)),b=80,g=56,a.sb<e&&(g=(a.sb<<3)+4,b=g+4),Dc(d,d.ga(h+b),!0),
|
||||
34,d.pa.ja),d.bb(g+36,d.Ca.ja),d.bb(g+38,d.P.ja),d.bb(g+40,d.xa.ja),d.Zb.load(d.ga(h+42)),Mc(d,d.ga(h+16)|(c?16384:0)),d.J=d.ga(h+18),d.G=d.ga(h+20),d.M=d.ga(h+22),d.D=d.ga(h+24),d.K=d.ga(h+28),d.I=d.ga(h+30),d.H=d.ga(h+32),d.pa.load(d.ga(h+34)),d.xa.load(d.ga(h+40)),Nc(d,d.ga(h+14),d.ga(h+36)),b=38,g=26,a.sb<e&&(g=(a.sb<<2)+2,b=g+2),Dc(d,d.ga(h+b),!0),v(d,d.ga(h+g))):(d.Va(g+28,d.dd),d.Va(g+32,A(d)),d.Va(g+36,Lc(d)),d.Va(g+40,d.J),d.Va(g+44,d.G),d.Va(g+48,d.M),d.Va(g+52,d.D),d.Va(g+56,w(d)),d.Va(g+
|
||||
60,d.K),d.Va(g+64,d.I),d.Va(g+68,d.H),d.Va(g+72,d.pa.ja),d.Va(g+76,d.Ca.ja),d.Va(g+80,d.P.ja),d.Va(g+84,d.xa.ja),d.Va(g+88,d.Ta.ja),d.Va(g+92,d.Xa.ja),Pc.call(d,d.fa(h+28)),d.Zb.load(d.ga(h+96)),Mc(d,d.fa(h+36)|(c?16384:0)),d.J=d.fa(h+40),d.G=d.fa(h+44),d.M=d.fa(h+48),d.D=d.fa(h+52),d.K=d.fa(h+60),d.I=d.fa(h+64),d.H=d.fa(h+68),d.pa.load(d.ga(h+72)),d.xa.load(d.ga(h+84)),d.Ta.load(d.ga(h+88)),d.Xa.load(d.ga(h+92)),Nc(d,d.fa(h+32),d.ga(h+76)),b=80,g=56,a.sb<e&&(g=(a.sb<<3)+4,b=g+4),Dc(d,d.ga(h+b),!0),
|
||||
v(d,d.fa(h+g)));c&&d.bb(h+0,f);d.Pa|=8;return!0}l.save=function(){return[this.ja,this.ya,this.Za,this.lb,this.id,this.Uf,this.sb,this.nc,this.hc,this.Nc,this.sa,this.U,this.N,this.type,this.C]};l.restore=function(a){"number"==typeof a?this.load(a):(this.ja=a[0],this.ya=a[1],this.Za=a[2],this.lb=a[3],this.id=a[4],this.Uf=a[5],this.sb=a[6],this.nc=a[7],this.hc=a[8],this.Nc=a[9]||2,this.sa=a[10]||65535,this.U=a[11]||2,this.N=a[12]||65535,this.type=a[13]||this.lb&7936,this.C=a[14]||(this.Za>>>0)+1)};
|
||||
function zc(a,b,c,d){void 0===c&&(c=!!(a.A.Pa&1));a.zd=!1;if(c)if(a.load=a.Df,a.Xh=a.Uk,a.Qb=a.Jh,a.Rb=a.Lh,void 0===d&&(d=!!(a.A.X&131072)),d)a.load=a.L,a.Qb=a.I,a.Rb=a.K,a.sb=a.nc=3,a.U=a.Nc=2,a.N=a.sa=65535,a.Za=65535,a.C=a.Za+1,a.Nc=a.U,a.hc=-1,a.pe=!1;else{if(!(a.ja&-4))a.Qb=a.xf,a.Rb=a.yf;else if(a.type&4096){6144==(a.type&6656)&&(a.Qb=a.xf);if(a.type&2048||!(a.type&512))a.Rb=a.yf;1024==(a.type&3072)&&(a.Qb==a.Jh&&(a.Qb=a.Aj),a.Rb==a.Lh&&(a.Rb=a.Bj),a.zd=!0);b&&6>a.id&&a.ja&-4&&-1!==a.hc&&(c=
|
||||
a.hc+5,d=a.A.Kb(c),d&1||a.A.Mc(c,d|1))}b&&(a.sb=a.ja&3,a.nc=(a.lb&24576)>>13,80386>a.A.ca||!(a.ext&64)?(a.U=2,a.N=65535):(a.U=4,a.N=-1),a.Nc=a.U,a.sa=a.N)}else a.load=a.Yh,a.Xh=a.Vk,a.Qb=a.Kh,a.Rb=a.Mh,a.sb=a.nc=0,a.hc=-1,a.pe=!1}
|
||||
|
|
@ -87,7 +87,7 @@ function Zb(a,b,c,d){var e=(b&-4194304)>>>20,f=a.vc[(a.dd+e&a.Fa)>>>a.ea],g=f.Gd
|
|||
e>>2;b.C=g;b.G=h>>2;db&&Ib&&c.V&&!c.controller&&!c.ge&&!c.he?(b.Ka=c.Ka,b.vd=c.vd,b.V=c.V,Fb(b,gc)):(b.K=c?Xb(32):0,b.P=c?Xb(96):0,Fb(b,ec));sb(b,a.Ia,k);a.R[d]=b;a.of.push(d);return b}function Ad(a){a.R!==a.vc&&(a.R=a.vc,a.qf=null,a.of=null,a.Zd=null)}l=Qc.prototype;l.reset=function(){this.da.Jb&&oc(this);yd(this);kc(this);this.da.Yc=!1};
|
||||
function Bd(a,b){var c;switch(b){case 0:c=a.J;break;case 1:c=a.G;break;case 2:c=a.M;break;case 3:c=a.D;break;case 4:c=w(a);break;case 5:c=a.K;break;case 6:c=a.I;break;case 7:c=a.H}return c}function Cd(a,b,c){switch(b){case 0:a.J=c;break;case 1:a.G=c;break;case 2:a.M=c;break;case 3:a.D=c;break;case 4:v(a,c);break;case 5:a.K=c;break;case 6:a.I=c;break;case 7:a.H=c}}
|
||||
function yd(a){a.J=0;a.D=0;a.G=0;a.M=0;a.Ob=0;a.K=0;a.I=0;a.H=0;a.Hb=!1;a.ua=a.Ga=0;a.oa=0;a.yh=0;a.W=0;a.Pa=65520;a.Ab=0;a.xc=1023;a.X=a.Cb=0;a.td=a.Kd=a.sd=a.Id=0;a.fc=-1;a.Gc=a.ic=-1;a.Ed=a.la=-1;a.Ca=new yc(a,1,"CS");a.xa=new yc(a,2,"DS");a.pa=new yc(a,2,"ES");a.P=new yc(a,3,"SS");v(a,0);Dc(a,0);if(80386<=a.ca){switch(a.pd){case 80562:case 80563:a.M=771;break;case 80578:a.M=772;break;case 80594:a.M=773;break;case 80595:case 80596:a.M=776}a.Pa=16;a.Ch=0;a.rd=0;a.dd=0;a.qb=[0,0,0,0,null,null,0,
|
||||
0];a.sf=[null,null,null,null,null,null,0,0];a.Ta=new yc(a,2,"FS");a.Xa=new yc(a,2,"GS");Ad(a)}a.Zf=new yc(a,0,"NULL");a.va=a.xa;a.rb=a.P;a.L=a.wa=0;a.F=a.C=-1;a.Eb=a.Zf;a.Ea=0;if(80286>a.ca)Oc(a,0,65535);else{a.ub=0;a.wc=65535;a.Zb=new yc(a,5,"LDT",!0);a.ia=new yc(a,4,"TSS",!0);a.Oa=new yc(a,6,"VER",!0);Oc(a,65520,61440);var b,c=A(a);b=a.Ca;var d=-65536;80386>b.A.ca&&(d&=16777215);b=b.ya=d;a.Y=b+c|0;a.Xf=(b>>>0)+(a.Ca.Za>>>0)+1}Mc(a,0);Fc(a)}
|
||||
0];a.sf=[null,null,null,null,null,null,0,0];a.Ta=new yc(a,2,"FS");a.Xa=new yc(a,2,"GS");Ad(a)}a.Zf=new yc(a,0,"NULL");a.va=a.xa;a.rb=a.P;a.L=a.wa=0;a.F=a.C=-1;a.Eb=a.Zf;a.Ea=0;if(80286>a.ca)Nc(a,0,65535);else{a.ub=0;a.wc=65535;a.Zb=new yc(a,5,"LDT",!0);a.ia=new yc(a,4,"TSS",!0);a.Oa=new yc(a,6,"VER",!0);Nc(a,65520,61440);var b,c=A(a);b=a.Ca;var d=-65536;80386>b.A.ca&&(d&=16777215);b=b.ya=d;a.Y=b+c|0;a.Xf=(b>>>0)+(a.Ca.Za>>>0)+1}Mc(a,0);Fc(a)}
|
||||
function Dd(a){2==a.Nc?(a.Bh=a.ga,a.Bb=Ed,a.Gb=Fd,a.yc=Gd,2==a.U?(a.Z=Hd,a.qa=Id,a.Ja=Jd):(a.Z=Kd,a.qa=Ld,a.Ja=Md)):(a.Bh=a.fa,a.Bb=Nd,a.Gb=Od,a.yc=Pd,2==a.U?(a.Z=Qd,a.qa=Rd,a.Ja=Sd):(a.Z=Td,a.qa=Ud,a.Ja=Vd))}function Gc(a,b){a.U!=b&&(a.wa|=1024,a.U=b,a.N=2==b?65535:-1,Wd(a))}function Wd(a){2==a.U?(a.fb=32768,a.Tb=a.ga,a.Xb=a.bb,2==a.Nc?(a.Z=Hd,a.qa=Id,a.Ja=Jd):(a.Z=Qd,a.qa=Rd,a.Ja=Sd)):(a.fb=-2147483648,a.Tb=a.fa,a.Xb=a.Va,2==a.Nc?(a.Z=Kd,a.qa=Ld,a.Ja=Md):(a.Z=Td,a.qa=Ud,a.Ja=Vd))}
|
||||
function Xd(a){a.Nc=a.Ca.Nc;a.sa=a.Ca.sa;Dd(a);a.U=a.Ca.U;a.N=a.Ca.N;Wd(a);a.wa&=-3073}l.Uh=function(){var a=this.J+this.D+this.G+this.M+w(this)+this.K+this.I+this.H|0;return a=a+A(this)+this.Ca.ja+this.xa.ja+this.P.ja+this.pa.ja+Lc(this)|0};function Yd(a,b,c){void 0===a.pf[b]&&(a.pf[b]=[]);a.pf[b].push(c)}function Zd(a,b){var c=a.uh[b];null!=c&&(c(--a.Wf),delete a.uh[b])}
|
||||
function $d(a,b){for(var c=a.qb[7],d=c>>16,e=0;4>e;e++){if(c&3){var f=!!(d&1),g=a.qb[e],g=g&~(d>>2&3);if(b){var g=a.R[g>>>a.ea],h=a;f?0===g.he++&&(h&&(g.A=h),cc(g,bc,!1)):0===g.ge++&&(h&&(g.A=h),ac(g,bc,!1))}else g=a.R[g>>>a.ea],f?0===--g.he&&(f=g,f.Yb=f.I?f.ha:f.lf,f.He=f.I?f.ba:f.qh,f.Ge=f.I?f.ka:f.oa):0===--g.ge&&(f=g,f.Wb=f.Fd,f.Ae=f.gf,f.Gd=f.jh)}c>>=2;d>>=4}}
|
||||
|
|
@ -95,9 +95,9 @@ function Yb(a,b,c,d){if(!(a.L&8192)&&a.qb[7]&255){c--;var e=a.qb[7],f=e>>16;d=d?
|
|||
l.save=function(){var a=new be(this);C(a,0,[this.J,this.D,this.G,this.M,w(this),this.K,this.I,this.H]);var b=A(this),c=this.Ca.save(),d=this.xa.save(),e=this.P.save(),f=this.pa.save(),g;null!=this.ub?(g=[this.Pa,this.ub,this.wc,this.Ab,this.xc,this.Zb.save(),this.ia.save(),this.Cb],80386<=this.ca&&(g.push(this.Ch),g.push(this.rd),g.push(this.dd),g.push(this.qb),g.push(this.sf))):g=null;b=[b,c,d,e,f,g,Lc(this)];80386<=this.ca&&(b.push(this.Ta.save()),b.push(this.Xa.save()));C(a,1,b);C(a,2,[this.va.Uf,
|
||||
this.rb.Uf,this.L,this.wa,this.Ea,this.F,this.C]);C(a,3,[0,this.$c,this.T.Cd]);b=this.ha;c=!!(this.Pa&-2147483648);d=0;e=[];(f=!b.G&&b.ba==b.Fa)||xb(b,!0);for(g=0;g<b.H;g++){var h=b.R[g];if(c&&h.type!=Hb||h.Ha||h.Qh){e[d++]=g;var k=d++;a:if(h=h.save()){for(var m=0,n=0,x=[];m<h.length;){for(var r=h[m],z=m+1;z<h.length&&h[z]===r;)z++;x[n++]=z-m;x[n++]=r;m=z}if(x.length<h.length){h=x;break a}}e[k]=h}}f||xb(b,!1);e[d]=f;C(a,4,e);return a.data()};
|
||||
l.restore=function(a){var b=a[0];this.J=b[0];this.D=b[1];this.G=b[2];this.M=b[3];var c=b[4];this.K=b[5];this.I=b[6];this.H=b[7];b=a[1];this.Ca.restore(b[1]);this.xa.restore(b[2]);this.P.restore(b[3]);this.pa.restore(b[4]);var d=b[5];d&&d.length&&(this.Pa=d[0],this.ub=d[1],this.wc=d[2],this.Ab=d[3],this.xc=d[4],this.Zb.restore(d[5]),this.ia.restore(d[6]),this.Cb=d[7],80386<=this.ca&&(this.Ch=d[8],this.rd=d[9],this.dd=d[10],this.qb=d[11],this.sf=d[12]),Fc(this));Mc(this,b[6]);var d=!1,e;a:{e=this.ha;
|
||||
var f=a[4],g;for(g=0;g<f.length-1;g+=2){var h=f[g],k=f[g+1];if(k&&k.length<e.ha){for(var m=0,n=Array(e.ha),x=0;x<k.length-1;)for(var r=k[x++],z=k[x++];r--;)n[m++]=z;k=n}m=e.R[h];if(!m||!m.restore(k)){p("Unable to restore memory block "+h);e=!1;break a}}void 0!==f[g]&&xb(e,f[g]);e=!0}e&&(Oc(this,b[0],this.Ca.ja),v(this,c),Dc(this,this.P.ja),80386<=this.ca&&(this.Ta.restore(b[7]),this.Xa.restore(b[8])),d=!0);b=a[2];this.va=null!=b[0]&&ce(this,b[0])||this.xa;this.rb=null!=b[1]&&ce(this,b[1])||this.P;
|
||||
this.L=b[2];this.wa=b[3];this.Ea=b[4];this.F=b[5];this.C=b[6];b=a[3];this.$c=b[1];pc(this,b[2]);return d};function ce(a,b){switch(b){case "CS":return a.Ca;case "DS":return a.xa;case "SS":return a.P;case "ES":return a.pa;case "NULL":return a.Zf;default:return[0,b,0,0,""]}}function de(a,b){null!=Oc(a,A(a),b)&&(a.L|=a.ae)}function Jc(a,b){-1!==a.xa.load(b)&&(a.L|=a.ae)}
|
||||
function Dc(a,b,c){var d=w(a);-1!==a.P.load(b)&&(v(a,d),a.P.zd?(a.Yf=a.P.ya+a.P.sa|0,a.$d=a.P.ya+a.P.Za|0):(a.Yf=a.P.ya+a.P.Za|0,a.$d=a.P.ya),c||(a.L|=4))}function Kc(a,b){-1!==a.pa.load(b)&&(a.L|=a.ae)}function A(a){return a.Y-a.Ca.ya|0}function D(a,b){a.Y=a.Ca.ya+(b&a.N)|0}function ee(a,b){a.Y=b;a.Xf=(a.Ca.ya>>>0)+(a.Ca.Za>>>0)+1;a.za=a.Ca.sb;Xd(a)}function Oc(a,b,c,d){var e=a.Ca;e.ef=b;e.D=d;b=e.load(c);return-1!==b?(ee(a,b+(a.Ca.ef&a.Ca.N)),a.Ca.pe):null}
|
||||
var f=a[4],g;for(g=0;g<f.length-1;g+=2){var h=f[g],k=f[g+1];if(k&&k.length<e.ha){for(var m=0,n=Array(e.ha),x=0;x<k.length-1;)for(var r=k[x++],z=k[x++];r--;)n[m++]=z;k=n}m=e.R[h];if(!m||!m.restore(k)){p("Unable to restore memory block "+h);e=!1;break a}}void 0!==f[g]&&xb(e,f[g]);e=!0}e&&(Nc(this,b[0],this.Ca.ja),v(this,c),Dc(this,this.P.ja),80386<=this.ca&&(this.Ta.restore(b[7]),this.Xa.restore(b[8])),d=!0);b=a[2];this.va=null!=b[0]&&ce(this,b[0])||this.xa;this.rb=null!=b[1]&&ce(this,b[1])||this.P;
|
||||
this.L=b[2];this.wa=b[3];this.Ea=b[4];this.F=b[5];this.C=b[6];b=a[3];this.$c=b[1];pc(this,b[2]);return d};function ce(a,b){switch(b){case "CS":return a.Ca;case "DS":return a.xa;case "SS":return a.P;case "ES":return a.pa;case "NULL":return a.Zf;default:return[0,b,0,0,""]}}function de(a,b){null!=Nc(a,A(a),b)&&(a.L|=a.ae)}function Jc(a,b){-1!==a.xa.load(b)&&(a.L|=a.ae)}
|
||||
function Dc(a,b,c){var d=w(a);-1!==a.P.load(b)&&(v(a,d),a.P.zd?(a.Yf=a.P.ya+a.P.sa|0,a.$d=a.P.ya+a.P.Za|0):(a.Yf=a.P.ya+a.P.Za|0,a.$d=a.P.ya),c||(a.L|=4))}function Kc(a,b){-1!==a.pa.load(b)&&(a.L|=a.ae)}function A(a){return a.Y-a.Ca.ya|0}function D(a,b){a.Y=a.Ca.ya+(b&a.N)|0}function ee(a,b){a.Y=b;a.Xf=(a.Ca.ya>>>0)+(a.Ca.Za>>>0)+1;a.za=a.Ca.sb;Xd(a)}function Nc(a,b,c,d){var e=a.Ca;e.ef=b;e.D=d;b=e.load(c);return-1!==b?(ee(a,b+(a.Ca.ef&a.Ca.N)),a.Ca.pe):null}
|
||||
function fe(a,b){var c=(a.Y>>>0)+b;c>a.Xf&&(8088>=a.ca||a.Ca.Za==a.Ca.sa?c=a.Ca.ya+(c-a.Xf&a.N):t.call(a,13,0));return c|0}function ge(a){a.Y=a.Ed}function w(a){return a.Ob&~a.P.sa|a.ra-a.P.ya}function v(a,b){a.Ob=b;a.ra=a.P.ya+(b&a.P.sa)|0}function he(a,b,c,d,e,f){if(63!=(e&63)&&e!=a.resultType){var g=(e^a.resultType)&a.resultType;g&&(g&1&&ie(a),g&2&&je(a),g&4&&ke(a),g&8&&le(a),g&16&&me(a),g&32&&ne(a))}f?(a.td=d,a.sd=b):(a.td=b,a.sd=d);a.Kd=c;a.Id=d;a.resultType=e}
|
||||
function F(a,b,c,d,e){a.resultType=c|26;a.Id=b;d?oe(a):pe(a);e?qe(a):re(a);return b}function se(a,b,c,d){c&d?oe(a):pe(a);(b^c)&d?qe(a):re(a)}function ve(a){return ie(a)?1:0}function ie(a){a.resultType&1&&(a.X&=-2,(a.td^(a.td^a.Kd)&(a.Kd^a.sd))&a.resultType&-2147450752&&(a.X|=1),a.resultType&=-2);return a.X&1}function je(a){a.resultType&2&&(a.X&=-5,38505>>((a.Id^a.Id>>4)&15)&1&&(a.X|=4),a.resultType&=-3);return a.X&4}
|
||||
function ke(a){a.resultType&4&&(a.X&=-17,(a.sd^a.td^a.Kd)&16&&(a.X|=16),a.resultType&=-5);return a.X&16}function le(a){a.resultType&8&&(a.X&=-65,a.Id&((a.resultType&-2147450752)-1|a.resultType&-2147450752)||(a.X|=64),a.resultType&=-9);return a.X&64}function me(a){a.resultType&16&&(a.X&=-129,a.Id&a.resultType&-2147450752&&(a.X|=128),a.resultType&=-17);return a.X&128}
|
||||
|
|
@ -170,8 +170,8 @@ function vh(a,b){var c=a^b;F(this,c,128);this.A-=-1===this.C?-1===this.F?this.B.
|
|||
function zh(a,b,c){c>>>=0;if(!c||c<=b>>>0)return!1;var d=0,e=1;c=[c>>>0,0];for(a=[a>>>0,b>>>0];0<xh(a,c);){var f=b=c;b[0]+=f[0];b[1]+=f[1];4294967295<b[0]&&(b[0]>>>=0,b[1]++);e+=e}do 0<=xh(a,c)&&(b=a,f=c,b[0]-=f[0],b[1]-=f[1],0>b[0]&&(b[0]>>>=0,b[1]--),d+=e),b=c,b[0]>>>=1,b[1]&1&&(b[0]=(b[0]|2147483648)>>>0),b[1]>>>=1,e/=2;while(1<=e);this.ua=d;this.Ga=a[0];return!0}function Ah(a){var b=a+1|0;he(this,a,1,b,this.fb|62);this.A-=2;return a&~this.N|b&this.N}
|
||||
function Pc(a){this.dd=a;this.Pa&-2147483648&&Bb(this)}function Bh(a){this.L|=1;this.Gb.call(this,a);this.A-=-1===this.F?4:5}function ch(a,b,c){if(c){16<c&&(a=b,c-=16);var d=a<<c-1;a=(d<<1|b>>>16-c)&65535;F(this,a,32768,d&32768)}return a}function eh(a,b,c){if(c){var d=a<<c-1;a=d<<1|b>>>32-c;F(this,a,-2147483648,d&-2147483648)}return a}function ih(a,b,c){if(c){16<c&&(a=b,c-=16);var d=a>>>c-1;a=(d>>>1|b<<16-c)&65535;F(this,a,32768,d&1)}return a}
|
||||
function kh(a,b,c){if(c){var d=a>>>c-1;a=d>>>1|b<<32-c;F(this,a,-2147483648,d&1)}return a}function Ch(){this.A-=-1===this.F?2:this.B.aj;return 1}function Dh(){var a=this.G&255;this.A-=(-1===this.F?this.B.Wg:this.B.Vg)+(a<<this.B.Xg);return a}function Eh(){var a=this.na();this.A-=(-1===this.F?this.B.Wg:this.B.Vg)+(a<<this.B.Xg);return a}function Fh(){return null}function Gh(){return this.oa}
|
||||
function Hh(a,b){this.Gc=this.Ca.ja;this.ic=this.P.ja;this.la=this.ra;var c=A(this),d=this.U;null!=Oc(this,a,b,!0)&&(Ic(this,this.Gc,d,2),Ic(this,c,d,d));this.Gc=this.ic=this.la=-1}function Ih(a,b,c){this.A-=this.B.zi+(c||0);c=Lc(this);var d=this.Ca.ja,e=A(this);a=this.Ca.Xh(a);-1!==a&&(y(this,c),y(this,d),y(this,e),null!=b&&y(this,b),this.fc=-1,ee(this,a))}
|
||||
function Jh(a){this.ic=this.P.ja;this.la=this.ra;var b=u(this),c=u(this);a&&v(this,w(this)+a);Oc(this,b,c,!1)&&(a&&v(this,w(this)+a),Kh.call(this,this.xa),Kh.call(this,this.pa),80386<=this.ca&&(Kh.call(this,this.Ta),Kh.call(this,this.Xa)));2==a&&this.Wf&&Zd(this,this.Y);this.ic=this.la=-1}function Lh(){8086==this.ca?(this.fc=-1,Ih.call(this,0,null,2)):t.call(this,0,null,2)}function Ke(a,b){this.fc=a;void 0===b&&(b=11);Ih.call(this,a,null,b)}
|
||||
function Hh(a,b){this.Gc=this.Ca.ja;this.ic=this.P.ja;this.la=this.ra;var c=A(this),d=this.U;null!=Nc(this,a,b,!0)&&(Ic(this,this.Gc,d,2),Ic(this,c,d,d));this.Gc=this.ic=this.la=-1}function Ih(a,b,c){this.A-=this.B.zi+(c||0);c=Lc(this);var d=this.Ca.ja,e=A(this);a=this.Ca.Xh(a);-1!==a&&(y(this,c),y(this,d),y(this,e),null!=b&&y(this,b),this.fc=-1,ee(this,a))}
|
||||
function Jh(a){this.ic=this.P.ja;this.la=this.ra;var b=u(this),c=u(this);a&&v(this,w(this)+a);Nc(this,b,c,!1)&&(a&&v(this,w(this)+a),Kh.call(this,this.xa),Kh.call(this,this.pa),80386<=this.ca&&(Kh.call(this,this.Ta),Kh.call(this,this.Xa)));2==a&&this.Wf&&Zd(this,this.Y);this.ic=this.la=-1}function Lh(){8086==this.ca?(this.fc=-1,Ih.call(this,0,null,2)):t.call(this,0,null,2)}function Ke(a,b){this.fc=a;void 0===b&&(b=11);Ih.call(this,a,null,b)}
|
||||
function t(a,b,c,d){var e=!1;this.da.Ne?80186<=this.ca&&(e=!0,0>this.fc?(-1!=this.Gc&&(this.Gc!==this.Ca.ja&&(this.Ca.sb=this.Gc&3,de(this,this.Gc)),this.Gc=-1),this.Ed!==this.Y&&ee(this,this.Ed),-1!=this.ic&&(this.ic!==this.P.ja&&Dc(this,this.ic),this.ic=-1),-1!==this.la&&(this.la!==this.ra&&v(this,this.Ob&~this.P.sa|this.la-this.P.ya),this.la=-1)):8!=this.fc?(b=0,a=8):(b=0,a=-1,yd(this),e=d=!1)):ee(this,this.Ed);var f=a,g=b,h=Ce(this,this.Y);204!=h||this.xc||(d=!1);this.X&131072&&(6==f&&99==h||
|
||||
13==f&&205==h)&&(d=!1);983040<=this.Y&&1048575>=this.Y&&(d=!1);if(d){var k=this.da.Jb,f="Fault 0x"+ea(f,2)+(null!=g?" (0x"+ea(g,4)+")":"")+" on opcode "+("0x"+ea(h,2));d&&k&&(f+=" (blocked)");this.Ba(f);oc(this)}if(d&&e)throw-1;if(e)throw this.fc=a,Ih.call(this,a,b,c),this.Ed=this.Y,this.L=1==a?this.L|8192:this.L|4096,a;}function zd(a,b,c){this.rd=a;a=0;b&&(a|=1);c&&(a|=2);3==this.za&&(a|=4);t.call(this,14,a)}
|
||||
function Kh(a){var b=a.lb&7680;a.ja&65528&&(6144==b||7168==b||7168>b&&a.nc<this.za&&a.nc<(a.ja&3))&&a.load(0)}
|
||||
|
|
@ -302,11 +302,11 @@ function(){var a=1,b=0,c=this.sa,d=this.B.Sg;this.wa&192&&(a=this.G&c,b=1,d=this
|
|||
-256|this.na();this.A-=this.B.Nb},function(){this.D=this.D&-256|this.na();this.A-=this.B.Nb},function(){this.J=this.J&-65281|this.na()<<8;this.A-=this.B.Nb},function(){this.G=this.G&-65281|this.na()<<8;this.A-=this.B.Nb},function(){this.M=this.M&-65281|this.na()<<8;this.A-=this.B.Nb},function(){this.D=this.D&-65281|this.na()<<8;this.A-=this.B.Nb},function(){this.J=this.J&~this.N|this.Aa();this.A-=this.B.Nb},function(){this.G=this.G&~this.N|this.Aa();this.A-=this.B.Nb},function(){this.M=this.M&~this.N|
|
||||
this.Aa();this.A-=this.B.Nb},function(){this.D=this.D&~this.N|this.Aa();this.A-=this.B.Nb},function(){v(this,w(this)&~this.N|this.Aa());this.A-=this.B.Nb},function(){this.K=this.K&~this.N|this.Aa();this.A-=this.B.Nb},function(){this.I=this.I&~this.N|this.Aa();this.A-=this.B.Nb},function(){this.H=this.H&~this.N|this.Aa();this.A-=this.B.Nb},li,mi,li,mi,function(){this.Z.call(this,zg)},function(){this.Z.call(this,xg)},function(){this.L|=1;this.yc.call(this,ti,this.na)},function(){this.L|=1;this.Ja.call(this,
|
||||
ti,this.Aa)},ni,oi,ni,oi,function(){if(this.X&131072&&3>this.Cb)t.call(this,13,0);else{var a=this.B.Ai;this.fc=-1;Ih.call(this,3,null,a)}},function(){var a=this.na();if(this.X&131072&&3>this.Cb)t.call(this,13,0);else{var b;a:{b=this.pf[a];if(void 0!==b)for(var c=0;c<b.length;c++)if(!b[c](this.Y)){b=!1;break a}b=!0}b?(this.fc=-1,Ih.call(this,a,null,0)):this.A--}},function(){if(ne(this))if(this.X&131072&&3>this.Cb)t.call(this,13,0);else{var a=this.B.Bi;this.fc=-1;Ih.call(this,4,null,a)}else this.A-=
|
||||
this.B.Ci},function(){if(this.X&131072&&3>this.Cb)t.call(this,13,0);else{this.ic=this.P.ja;this.la=this.ra;this.A-=this.B.yi;if(this.Pa&1&&this.X&16384){var a=this.ga(this.ia.ya+0);Ec(this.Ca,a,!1)}else{var a=this.za,b=u(this),c=u(this),d=u(this);if(this.X&131072)d=d&131071|this.X&-131072;else if(d&131072){var e=u(this),f=u(this),g=u(this),h=u(this),k=u(this),m=u(this);Fc(this,!0,!0);Dc(this,f);v(this,e);Kc(this,g);Jc(this,h);this.Ta.load(k);this.Xa.load(m)}null!=Oc(this,b,c,!1)&&(Mc(this,d,a),this.Wf&&
|
||||
this.B.Ci},function(){if(this.X&131072&&3>this.Cb)t.call(this,13,0);else{this.ic=this.P.ja;this.la=this.ra;this.A-=this.B.yi;if(this.Pa&1&&this.X&16384){var a=this.ga(this.ia.ya+0);Ec(this.Ca,a,!1)}else{var a=this.za,b=u(this),c=u(this),d=u(this);if(this.X&131072)d=d&131071|this.X&-131072;else if(d&131072){var e=u(this),f=u(this),g=u(this),h=u(this),k=u(this),m=u(this);Fc(this,!0,!0);Dc(this,f);v(this,e);Kc(this,g);Jc(this,h);this.Ta.load(k);this.Xa.load(m)}null!=Nc(this,b,c,!1)&&(Mc(this,d,a),this.Wf&&
|
||||
Zd(this,this.Y))}this.ic=this.la=-1}},function(){this.yc.call(this,ii,Ch)},function(){this.Ja.call(this,2==this.U?ji:ki,Ch)},function(){this.yc.call(this,ii,Dh)},function(){this.Ja.call(this,2==this.U?ji:ki,Dh)},function(){var a=this.na();if(a){var b=this.J&255;this.J=this.J&-65536|b/a<<8|b%a;F(this,this.J,128);this.A-=this.B.ci}else Lh.call(this)},function(){var a=this.J&255,b=(this.J>>8&255)*this.na()|0,c=a+b|0;this.J=this.J&-65536|c&255;he(this,a,b,c,191);this.A-=this.B.bi},function(){this.J=this.J&
|
||||
-256|(ie(this)?255:0);this.A-=2},function(){this.J=this.J&-256|De(this,this.va,this.D+(this.J&255));this.A-=this.B.bj},function(){pi.call(this,216)},function(){pi.call(this,217)},function(){pi.call(this,218)},function(){pi.call(this,219)},function(){pi.call(this,220)},function(){pi.call(this,221)},function(){pi.call(this,222)},function(){pi.call(this,223)},function(){var a=this.O(),b=this.G-1&this.sa;this.G=this.G&~this.sa|b;b&&!le(this)?(D(this,A(this)+a),this.A-=this.B.Ji):this.A-=this.B.Ig},function(){var a=
|
||||
this.O(),b=this.G-1&this.sa;this.G=this.G&~this.sa|b;b&&le(this)?(D(this,A(this)+a),this.A-=this.B.Jg):this.A-=this.B.Kg},function(){var a=this.O(),b=this.G-1&this.sa;this.G=this.G&~this.sa|b;b?(D(this,A(this)+a),this.A-=this.B.Ii):this.A-=this.B.Ig},function(){var a=this.O();this.G&this.sa?this.A-=this.B.Kg:(D(this,A(this)+a),this.A-=this.B.Jg)},function(){var a=this.na();Be(this,a,1)&&(this.J=this.J&-256|Pb(this.ha,a,1,this.Y-2)&255,this.A-=this.B.Dg)},function(){var a=this.na();Be(this,a,this.U)&&
|
||||
(this.J=this.J&~this.N|Pb(this.ha,a,this.U,this.Y-2)&this.N,this.A-=this.B.Dg)},function(){var a=this.na();Be(this,a,1)&&(Rb(this.ha,a,1,this.J&255,this.Y-2),this.A-=this.B.Rg)},function(){var a=this.na();Be(this,a,this.U)&&(Rb(this.ha,a,this.U,this.J&this.N,this.Y-2),this.A-=this.B.Rg)},function(){var a=this.Aa(),b=A(this),a=b+a;y(this,b);D(this,a);this.A-=this.B.gi},function(){var a=this.Aa();D(this,A(this)+a);this.A-=this.B.Eg},function(){Oc(this,this.Aa(),Ie(this));this.A-=this.B.Ei},function(){var a=
|
||||
(this.J=this.J&~this.N|Pb(this.ha,a,this.U,this.Y-2)&this.N,this.A-=this.B.Dg)},function(){var a=this.na();Be(this,a,1)&&(Rb(this.ha,a,1,this.J&255,this.Y-2),this.A-=this.B.Rg)},function(){var a=this.na();Be(this,a,this.U)&&(Rb(this.ha,a,this.U,this.J&this.N,this.Y-2),this.A-=this.B.Rg)},function(){var a=this.Aa(),b=A(this),a=b+a;y(this,b);D(this,a);this.A-=this.B.gi},function(){var a=this.Aa();D(this,A(this)+a);this.A-=this.B.Eg},function(){Nc(this,this.Aa(),Ie(this));this.A-=this.B.Ei},function(){var a=
|
||||
this.O();D(this,A(this)+a);this.A-=this.B.Eg},function(){var a=this.M&65535;Be(this,a,1)&&(this.J=this.J&-256|Pb(this.ha,a,1,this.Y-1)&255,this.A-=this.B.Cg)},function(){var a=this.M&65535;Be(this,a,this.U)&&(this.J=this.J&~this.N|Pb(this.ha,a,this.U,this.Y-1)&this.N,this.A-=this.B.Cg)},function(){var a=this.M&65535;Be(this,a,1)&&(Rb(this.ha,a,1,this.J&255,this.Y-1),this.A-=this.B.Qg)},function(){var a=this.M&65535;Be(this,a,2)&&(Rb(this.ha,a,this.U,this.J&this.N,this.Y-1),this.A-=this.B.Qg)},qi,
|
||||
qi,function(){this.L|=132;this.A-=this.B.Rc},function(){this.L|=68;this.A-=this.B.Rc},function(){this.X&131072?t.call(this,13,0):(this.Ea|=4,this.A-=2,this.X&512||oc(this))},function(){ie(this)?pe(this):oe(this);this.A-=2},function(){this.Hb=!1;this.yc.call(this,ui,Fh);this.Hb&&(this.J=this.J&~this.N|this.ua&this.N)},function(){this.Hb=!1;this.Ja.call(this,vi,Fh);this.Hb&&(this.J=this.J&~this.N|this.ua&this.N,this.M=this.M&~this.N|this.Ga&this.N)},function(){pe(this);this.A-=2},function(){oe(this);
|
||||
this.A-=2},function(){this.za>this.Cb?t.call(this,13,0):(this.X&=-513,this.A-=this.B.ei)},function(){this.za>this.Cb?t.call(this,13,0):(this.X|=512,this.L|=4,this.A-=2)},function(){this.X&=-1025;this.A-=2},function(){this.X|=1024;this.A-=2},function(){this.yc.call(this,Sc,Fh)},function(){this.Ja.call(this,Tc,Fh)}],di=[Xf,Jg,Vf,Lg,Zf,nh,vh,mg],ri=[Yf,Kg,Wf,Mg,$f,oh,wh,ng],si=[function(a,b){this.A-=-1===this.C?this.B.ec:this.B.Ui;return b},pg,pg,pg,pg,pg,pg,pg],ti=[function(a,b){this.A-=-1===this.C?
|
||||
|
|
@ -322,7 +322,7 @@ qe(this)):(pe(this),re(this));this.Hb=!0;this.A-=-1===this.F?this.B.Si:this.B.Ri
|
|||
c)return Lh.call(this),a;this.ua=c&65535;this.Ga=b%a&65535}else{if(!zh.call(this,this.J,this.M,a))return Lh.call(this),a;this.ua|=0;this.Ga|=0}this.Hb=!0;this.A-=-1===this.F?this.B.oi:this.B.ni;this.L|=2;return a},function(a,b){if(2==this.U){if(!a)return Lh.call(this),a;var c=a<<16>>16,d=(b=this.M<<16|this.J&65535)/c|0;if(d!=d<<16>>16||8086==this.ca&&-32768==d)return Lh.call(this),a;this.ua=d&65535;this.Ga=b%c&65535}else{var c=this.J,d=this.M,e=a,f=0,g=0;0>e&&(e=-e|0,f=1-f);0>d&&(c=-c|0,d=~d+(c?0:
|
||||
1)|0,g=1,f=1-f);!zh.call(this,c,d,e)||this.ua>2147483647+f||this.Ga>2147483647+g?c=!1:(f&&(this.ua=-this.ua),g&&(this.Ga=-this.Ga),c=!0);if(!c)return Lh.call(this),a;this.ua|=0;this.Ga|=0}this.Hb=!0;this.A-=-1===this.F?this.B.ti:this.B.si;this.L|=2;return a}],Sc=[function(a){var b=a+1|0;he(this,a,1,b,190);this.A-=-1===this.F?this.B.Ze:this.B.Ye;return b&255},function(a){var b=a-1|0;he(this,a,1,b,190,!0);this.A-=-1===this.F?this.B.Ze:this.B.Ye;return b&255},R,R,R,R,R,R],Tc=[function(a){var b=a+1|0;
|
||||
he(this,a,1,b,this.fb|62);this.A-=-1===this.F?this.B.Ze:this.B.Ye;return b&this.N},function(a){var b=a-1|0;he(this,a,1,b,this.fb|62,!0);this.A-=-1===this.F?this.B.Ze:this.B.Ye;return b&this.N},function(a){y(this,A(this));D(this,a);this.A-=-1===this.F?this.B.ki:this.B.ji;this.L|=2;return a},function(a){if(-1===this.F)return R.call(this,a);this.la=this.ra;Hh.call(this,a,this.ga(this.F+this.U));this.A-=this.B.hi;this.L|=2;this.la=-1;return a},function(a){D(this,a);this.A-=-1===this.F?this.B.Gi:this.B.Fi;
|
||||
this.L|=2;return a},function(a){if(-1===this.F)return R.call(this,a);Oc(this,a,this.ga(this.F+this.U));this.A-=this.B.Di;this.L|=2;return a},function(a){var b=a;this.L&512&&(a=a-2&65535,80286>this.ca&&(b=a));y(this,b);this.A-=-1===this.F?this.B.Ac:this.B.Wi;this.L|=2;return a},R];function wd(){this.Z.call(this,sh);this.A-=-1===this.F?6:13}function xd(){this.qa.call(this,rh);this.A-=-1===this.F?12:19}var nd=Array(256);
|
||||
this.L|=2;return a},function(a){if(-1===this.F)return R.call(this,a);Nc(this,a,this.ga(this.F+this.U));this.A-=this.B.Di;this.L|=2;return a},function(a){var b=a;this.L&512&&(a=a-2&65535,80286>this.ca&&(b=a));y(this,b);this.A-=-1===this.F?this.B.Ac:this.B.Wi;this.L|=2;return a},R];function wd(){this.Z.call(this,sh);this.A-=-1===this.F?6:13}function xd(){this.qa.call(this,rh);this.A-=-1===this.F?12:19}var nd=Array(256);
|
||||
nd[0]=function(){16>(this.Kb(this.Y)&56)&&(this.L|=1);this.Ja.call(this,this.xh,Fh)};nd[1]=function(){this.Kb(this.Y)&16||(this.L|=1);this.Ja.call(this,wi,Fh)};nd[2]=function(){!(this.Pa&1)||this.X&131072?t.call(this,6):this.Z.call(this,wg)};nd[3]=function(){!(this.Pa&1)||this.X&131072?t.call(this,6):this.Z.call(this,Cg)};
|
||||
nd[5]=function(){this.za?t.call(this,13,0,0,!0):(Ae(this,this.ga(2054)),this.H=this.ga(2086),this.I=this.ga(2088),this.K=this.ga(2090),this.D=this.ga(2094),this.M=this.ga(2096),this.G=this.ga(2098),this.J=this.ga(2100),Cc(this.pa,2102,this.ga(2084)),Cc(this.Ca,2108,this.ga(2082)),Cc(this.P,2114,this.ga(2080)),Cc(this.xa,2120,this.ga(2078)),Mc(this,this.ga(2072)),D(this,this.ga(2074)),v(this,this.ga(2092)),this.ub=this.ga(2126)|this.Kb(2128)<<16,this.wc=this.ub+this.ga(2130),this.Ab=this.ga(2138)|
|
||||
this.Kb(2140)<<16,this.xc=this.Ab+this.ga(2142),Cc(this.Zb,2132,this.ga(2076)),Cc(this.ia,2144,this.ga(2070)),this.A-=195)};nd[6]=function(){this.za?t.call(this,13,0):(this.Pa&=-9,this.A-=2)};nd[11]=Vc;nd[166]=Vc;nd[255]=Vc;var B=[];B[5]=Vc;
|
||||
|
|
@ -473,8 +473,8 @@ function Jk(a,b,c,d){if(d)a.Ba("Unable to load font ROM (error "+d+": "+b+")");e
|
|||
function sl(a,b){if(1==b)return a.oa[0]=Ok[0],a.oa[1]=Ok[7],a.oa;if(2==b){var c=a.D.hf;if(a.D===a.B){var d=a.B.Kc[0],c=d&7;d&16&&(c|=8);18!=a.B.Kc[1]&&(c|=32)}a.oa[0]=Ok[c&15];c=c&32?Qk:Pk;for(d=0;d<c.length;d++)a.oa[d+1]=Ok[c[d]];return a.oa}if(a.R===a.Cb)return Ok;a.La&&b&&!a.oa[16]&&(a.La=!1);if(!a.La){var c=a.B,d=c.Be,e,f,g,h,k;if(8==b)for(f=0;256>f;f++)g=d[f]||0,h=g<<2&252,k=g>>4&252,g=g>>10&252,a.oa[f]=[h,k,g,255];else{var m=d&&d[255];e=null!=c.Kc[15]?c.Kc:Rk;for(f=0;16>f;f++)g=e[f]&63,m?(g|=
|
||||
(c.Kc[20]&12)<<4,c.Kc[16]&128&&(g&=-49,g|=(c.Kc[20]&3)<<4),g=d[g],h=g<<2&252,k=g>>4&252,g=g>>10&252):(h=(g&4?170:0)|(g&32?85:0),k=(g&2?170:0)|(g&16?85:0),g=(g&1?170:0)|(g&8?85:0)),a.oa[f]=[h,k,g,255]}a.La=!0}return a.oa}function dk(a,b,c,d){a.Ab=b;a.Xa=c;a.Ja=d}
|
||||
function ol(a,b){var c=!1;if(window&&a.Ab&&(!b||a.I)){var d=0,e=a.Ja?a.Ja:8,f=sl(a);null!=a.Xa[0]&&tl(a,3,a.Xa[0],d,e,8,a.Ab,f)&&(c=!0);d=a.Ja?0:2048;e=a.Ja?a.Ja:9;null!=a.Xa[1]&&(tl(a,1,a.Xa[1],d,e,14,a.Ab,Mk,Nk)&&(c=!0),a.Ja&&tl(a,a.Ra,a.Xa[1],0,a.Ja,14,a.Ab,f)&&(c=!0))}return c}function tl(a,b,c,d,e,f,g,h,k){var m=!1;null!=c&&(ul(a,b,c,d,e,f,g,h,k)&&(m=!0),a.Zd&&ul(a,b<<1,c,d,e,f,g,h,k)&&(m=!0));return m}
|
||||
function ul(a,b,c,d,e,f,g,h,k){var m=!1,n=b&1?0:1,x=a.xa[b],r=16>h.length?h.length:16;x||(x={tc:e<<n,uc:f<<n,be:Array(r),Dh:h.slice(0,r),Ie:k,bg:Array(r)});for(k=0;k<r;k++){var z=h[k],E=x.be[k]?x.Dh[k]:[];if(z[0]!==E[0]||z[1]!==E[1]||z[2]!==E[2]){var m=x,E=k,J=n,W=c,da=d,ua=e,va=f,qd=g,an=[0,0,0,0],te=document.createElement("canvas");te.width=m.tc<<4;te.height=m.uc<<4;for(var sj=te.getContext("2d"),zb=void 0,Nc=void 0,$b=void 0,ue=8>va||!da?va:8,Ff=sj.createImageData(m.tc,m.uc),zb=0;256>zb;zb++){for($b=
|
||||
0;$b<va;$b++)for(var bn=m.Ie&&E&1&&$b>=va-2,cn=qd[$b<ue?W+zb*ue+$b:da+zb*ue+$b-ue],Gf=0;Gf<=J;Gf++)for(Nc=0;Nc<ua;Nc++){var tj=Nc<<J,uj=($b<<J)+Gf,vj=bn||cn&128>>(8<=Nc&&192<=zb&&223>=zb?7:Nc)?z:an;vl(Ff,tj,uj,vj);J&&vl(Ff,tj+1,uj,vj)}sj.putImageData(Ff,(zb&15)*m.tc,(zb>>4)*m.uc)}m.be[E]="#"+ea(z[0],2)+ea(z[1],2)+ea(z[2],2);m.Dh[E]=z;m.bg[E]=te;m=!0}}a.xa[b]=x;return m}function wl(a){0<a.za||0<=a.ia?0>a.Ea&&(a.Ea=0):a.Ea=-1}
|
||||
function ul(a,b,c,d,e,f,g,h,k){var m=!1,n=b&1?0:1,x=a.xa[b],r=16>h.length?h.length:16;x||(x={tc:e<<n,uc:f<<n,be:Array(r),Dh:h.slice(0,r),Ie:k,bg:Array(r)});for(k=0;k<r;k++){var z=h[k],E=x.be[k]?x.Dh[k]:[];if(z[0]!==E[0]||z[1]!==E[1]||z[2]!==E[2]){var m=x,E=k,J=n,W=c,da=d,ua=e,va=f,qd=g,an=[0,0,0,0],te=document.createElement("canvas");te.width=m.tc<<4;te.height=m.uc<<4;for(var sj=te.getContext("2d"),zb=void 0,Oc=void 0,$b=void 0,ue=8>va||!da?va:8,Ff=sj.createImageData(m.tc,m.uc),zb=0;256>zb;zb++){for($b=
|
||||
0;$b<va;$b++)for(var bn=m.Ie&&E&1&&$b>=va-2,cn=qd[$b<ue?W+zb*ue+$b:da+zb*ue+$b-ue],Gf=0;Gf<=J;Gf++)for(Oc=0;Oc<ua;Oc++){var tj=Oc<<J,uj=($b<<J)+Gf,vj=bn||cn&128>>(8<=Oc&&192<=zb&&223>=zb?7:Oc)?z:an;vl(Ff,tj,uj,vj);J&&vl(Ff,tj+1,uj,vj)}sj.putImageData(Ff,(zb&15)*m.tc,(zb>>4)*m.uc)}m.be[E]="#"+ea(z[0],2)+ea(z[1],2)+ea(z[2],2);m.Dh[E]=z;m.bg[E]=te;m=!0}}a.xa[b]=x;return m}function wl(a){0<a.za||0<=a.ia?0>a.Ea&&(a.Ea=0):a.Ea=-1}
|
||||
function rl(a){if(a.I){for(var b=10;15>=b;b++)if(null==a.D.ab[b])return;var c=a.D.ab[10],b=c&31,d=a.D.ab[11]&31,e=a.D.ab[9]&31,f=!1;a.D===a.B&&(f=!0,7!=e||4!=b||d||(d=7));if(c&32||b>d&&!f||b>e)xl(a);else{c=a.D.ab[15]+((a.D.ab[14]&63)<<8);a.ia!=c&&(xl(a),a.ia=c);d=d-b+1;if(a.td!=b||a.Gc!=d)a.td=b,a.Gc=d;a.Da=e+1;wl(a)}}}
|
||||
function xl(a){if(0<=a.ia){if(void 0!==a.ba){var b=a.ba[a.ia];if(b&131072){var b=b&-131073,c=a.ia%a.H,d=a.ia/a.H|0;a.I&&a.xa[a.I]&&(a.Ga&&yl(a,c,d,b,a.Ga),yl(a,c,d,b));a.ba[a.ia]=b}}a.ia=-1}}
|
||||
function zl(a){var b,c=a.D;a.Zc=!1;var d=c.Hd[5];if(null!=d){b=1024;var e=0,f=c.Hd[3]&31;switch(d&3){case 0:if(f){e=32;switch(f&24){case 8:e=96;break;case 16:e=160;break;case 24:e=224}c.Hc=f&7}break;case 1:e=1;break;case 2:switch(f&24){default:e=2;break;case 8:e=98;break;case 16:e=162;break;case 24:e=226}break;case 3:a.Ra==ek&&(e=3,c.Hc=f&7)}d&8&&(b=1280);c=c.De[4];null!=c&&(c&4||(b|=4096,e|=16),d&64&&(c&8&&(b|=16384,e|=4),a.Zc=!0));b|=e}return b}
|
||||
|
|
@ -595,33 +595,34 @@ function gn(a,b,c){b.errorCode=4;b.ee&&b.ee.length==b.vb||(b.ee=Array(b.vb));b.U
|
|||
l.ze=function(a,b,c){var d=-1,e=null,f=0;if(a.errorCode)return b&&b(d,!1,e,f),d;var g=!1!==c?1:0;if(a.Wa&&(f=a.Ua,d=a.ta.read(a.Wa,a.Ua),a.Ua+=g,0<=d))return e=a.Wa,b&&b(d,!1,e,f),d;if(b){if(a.ta)return a.ta.seek(a.Jd,a.Ya,a.mb+a.vf,!1,function(c,k){(a.Wa=c)?(e=c,f=a.Ua=0,hn(a),d=a.ta.read(a.Wa,a.Ua),a.Ua+=g):a.errorCode=20;b(d,k,e,f)}),d;a.errorCode=20;b(d,!1,e,f)}return d};
|
||||
function Xm(a,b){if(a.errorCode)return-1;do{if(a.Wa&&a.ta.write(a.Wa,a.Ua++,b))break;a.ta&&a.ta.seek(a.Jd,a.Ya,a.mb+a.vf,!0,function(b){a.Wa=b});if(!a.Wa){a.errorCode=20;b=-1;break}a.Ua=0;hn(a)}while(1);return b}function hn(a){a.mb++;var b=1-a.vf;a.mb>=a.eb+b&&(a.mb=b,a.Ya++,a.Ya>=a.jb&&(a.Ya=0,a.Jd++))}l.Sk=function(){var a=this.A.M&255;!(this.A.J>>8)&&128<a&&(this.Y=a-128);return!0};l.Tk=function(){var a;(a=this.A.J>>8||!this.S)||(a=!(this.S.gc[0].Vc&64));return a?!0:!1};
|
||||
var Nm={800:Z.prototype.Pk,801:Z.prototype.Qk,802:Z.prototype.Ok},Mm={496:Z.prototype.vj,497:Z.prototype.Vj,498:Z.prototype.Xj,499:Z.prototype.Yj,500:Z.prototype.Tj,501:Z.prototype.Sj,502:Z.prototype.Uj,503:Z.prototype.Zj},Pm={800:Z.prototype.Xl,801:Z.prototype.$l,802:Z.prototype.Zl,803:Z.prototype.Yl,807:Z.prototype.ih,811:Z.prototype.ih,815:Z.prototype.ih},Om={496:Z.prototype.hl,497:Z.prototype.ml,498:Z.prototype.kl,499:Z.prototype.ll,500:Z.prototype.gl,501:Z.prototype.fl,502:Z.prototype.il,503:Z.prototype.el,
|
||||
1014:Z.prototype.jl};Ea(function(){for(var a=Za(document,"pcx86","hdc"),b=0;b<a.length;b++){var c=a[b],d=Wa(c),d=new Z(d);Ya(d,c)}});function be(a,b,c){this.id=a.id;this.key=jn(a,b,c);this.Ia=a.Ia;kn(this,a.gj)}function jn(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
be.prototype={constructor:be,value:function(){return this[this.id]},data:function(){return this[this.id]},load:function(a){return a?(this[this.id]=a,this.A=!0):this.A?!0:ta()&&(a=wa(this.key))?(this[this.id]=a,this.A=!0):!1},toString:function(){var a=this[this.id];return"string"==typeof a?a:JSON.stringify(a)},clear:function(a){kn(this);var b=[];try{for(var c=0,d=window.localStorage.length;c<d;c++)b.push(window.localStorage.key(c))}catch(e){}for(c=0;c<b.length;c++)if((d=b[c])&&(a||d.substr(0,this.key.length)==
|
||||
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function kn(a,b){a[a.id]={};b&&C(a,"parms",b);a.A=!1}function ln(a){var b=!0;if(ta()){var c=JSON.stringify(a[a.id]);xa(a.key,c)||(p("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function mn(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){p(c.message||c),b=!1}return b}function nn(a,b){return a[a.id][b]||null}function C(a,b,c){try{a[a.id][b]=c}catch(d){}}
|
||||
function on(a,b,c){Ia.call(this,"Computer",a,on);this.da.Sb=!1;pn(this,b);this.ba=jc(this,"autoPower",a);this.G=0;this.ea=a.busWidth||a.buswidth;this.B=qn;this.R=null;this.K=this.Z=!1;this.ia=jc(this,"url")||"";this.ma=(Math.random()+.1).toString(36).substr(2,12);this.C=rn(this);if(this.A=Va("CPU",this.id)){this.Ia=Va("Debugger",this.id);this.I=[];for(b=null;b=kb(this,"Video",b);)this.I.push(b);this.ha=new rb({id:this.mf+".bus",busWidth:this.ea},this.A,this.Ia);var d,e=Ta(this.id);if((this.D=Va("Panel",
|
||||
this.id))&&this.D.hg)for(b=0;b<e.length;b++)d=e[b],d.Ba=this.D.Ba,d.rc=this.D.rc,d.hg=this.D.hg;this.rc("PCx86 v1.24.0\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>");for(b=0;b<e.length;b++)d=e[b],d.pc&&d.pc(this,this.ha,this.A,this.Ia);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.S=d:this.B=parseInt(d,10));var f;if(a=jc(this,"state")||(f=!0,a.state))b=this.W=a,f||(this.K=!0,this.B=qn),this.B&&(this.P=new be(this,"1.24.0"),
|
||||
this.P.load()?b=null:delete this.P);!b&&this.B&&(b=sn(this))&&(this.K=!0);if(b){var g=this;pa(b,null,!0,function(a,b,c){c?(g.S=null,g.K=!1,g.Ba("Unable to load machine state from server (error "+c+(b?": "+(String.prototype.trim?b.trim():b.replace(/^\s+|\s+$/g,"")):"")+")")):(g.R=b,g.Z=!0);ab(g)})}else ab(this);this.ka.power||(this.ba=!0);!c&&this.ba&&tn(this,this.ff)}else p("Unable to find CPU component")}Qa(on);var qn=0;l=on.prototype;l.se=function(){return this.ma};
|
||||
function pn(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){p(d.message+" ("+c+")")}}a.L=b}function jc(a,b,c){var d=b.toLowerCase(),d=La[b]||La[d];void 0===d&&a.L&&(d=a.L[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}l.Ad=function(){return this.C||""};function tn(a,b,c){for(var d=Ta(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!bb(f)){bb(f,function(){tn(a,b,c)});return}}b.call(a,c)}
|
||||
function un(a,b){var c=new be(a,"1.24.0","validate");if(c.load()&&mn(c)){var d=nn(c,"timestamp"),e=b?nn(b,"timestamp"):"unknown";d!=e&&(a.Ba("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
|
||||
l.ff=function(a){void 0===a&&(a=this.B||(this.R?1:qn));if(!this.G){this.G++;var b=!1,c=!1;this.Y=!1;var d=this.P||new be(this,"1.24.0");if(-1==a)b=!0;else if(a>qn){if(d.load(this.R)){this.H=new be(this,"1.24.0","failsafe");this.H.load()&&(vn(this,d),a=2,kn(this.H));C(this.H,"timestamp",la());ln(this.H);var e=this.B&&!this.K;if(1==a||ra("Click OK to restore the previous PCx86 machine state, or CANCEL to reset the machine.")){if(c=mn(d)){var f=nn(d,"code"),g=nn(d,"data");f&&("ok"==f?d.load(g):("error"==
|
||||
f&&"no machine state"!=g?(this.Ba("Error: "+g),"unable to verify user"==g&&(xa("user",""),this.C=null)):this.rc(f+": "+g),kn(d),d.load()?(c=mn(d),e=!0):c=!1))}e&&un(this,c?d:null)}else 2==a&&d.clear()}else un(this);delete this.R;delete this.P}e=Ta(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.A&&(c=wn(this,g,d,b,c));b=[d,a,c];-1!=a?tn(this,this.Oh,b):this.Oh(b)}};
|
||||
function wn(a,b,c,d,e){if(!b.da.Sb){b.da.Sb=!0;if(b.Vb){var f=null;e&&((f=nn(c,b.id))||(f=nn(c,b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.Vb(f,d)&&f&&(p("Unable to restore state for "+b.type),a.W&&!a.Z?(c.clear(),a.B=qn,window&&window.location.reload()):a.Y=!0,b.Vb(null),e=!1)}if(!d&&b.Ah)for(a=b.Ah.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
l.Oh=function(a){var b=a[0],c=0>a[1];a=a[2];this.la=!0;this.da.Sb=!0;var d=this.ka.power;d&&(d.textContent="Shutdown");this.A&&(wn(this,this.A,b,c,a),nc(this.A));this.Y&&(vn(this,b),b.clear());!c&&this.H&&(this.H.clear(),delete this.H);this.G=0};
|
||||
function vn(a,b){if(ra("There may be a problem with your PCx86 machine.\n\nTo help us diagnose it, click OK to send this PCx86 machine state to http://www.pcjs.org.")){var c=a.Ad(),d=b.toString(),e={app:"PCx86",ver:"1.24.0"};e.url=a.ia;e.user=c;e.type="bug";e.data=d;pa("http://www.pcjs.org/api/v1/report",e,!0)}}
|
||||
function xn(a,b,c){var d,e="none";if(a.G)return null;a.G--;var f=new be(a,"1.24.0"),g=new be(a,"1.24.0","validate"),h=la();C(g,"timestamp",h);C(f,"timestamp",h);C(f,"version","1.24.0");C(f,"url",window?window.location.href:null);C(f,"browser",window?window.navigator.userAgent:"");a.A&&a.A.Ub&&(c&&oc(a.A),d=a.A.Ub(b,c),"object"===typeof d&&C(f,a.A.id,d),c&&(a.A.da.Sb=!1,!1===d&&(e=null)));for(var h=Ta(a.id),k=0;k<h.length;k++){var m=h[k];m.da.Sb&&(m.Ub&&(d=m.Ub(b,c),"object"===typeof d&&C(f,m.id,d)),
|
||||
c&&(m.da.Sb=!1,!1===d&&(e=null)))}e&&(c?(h=d=!1,b?(a.C&&yn(a,a.C,f.toString()),ln(g)&&ln(f)||(e=null,d=h=!0)):a.B&&(d=!0,h=3==a.B),d&&f.clear(h)):e=f.toString());c&&(a.da.Sb=!1,b=a.ka.power)&&(b.textContent="Power");a.G=0;return e}l.reset=function(){this.ha&&this.ha.reset&&this.ha.reset();for(var a=Ta(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.ha&&c.reset&&c.reset()}};
|
||||
1014:Z.prototype.jl};Ea(function(){for(var a=Za(document,"pcx86","hdc"),b=0;b<a.length;b++){var c=a[b],d=Wa(c),d=new Z(d);Ya(d,c)}});
|
||||
function jn(a,b,c){Ia.call(this,"Computer",a,jn);this.da.Sb=!1;kn(this,b);this.ba=jc(this,"autoPower",a);this.G=0;this.ea=a.busWidth||a.buswidth;this.B=ln;this.R=null;this.K=this.Z=!1;this.ia=jc(this,"url")||"";this.ma=(Math.random()+.1).toString(36).substr(2,12);this.C=mn(this);if(this.A=Va("CPU",this.id)){this.Ia=Va("Debugger",this.id);this.I=[];for(b=null;b=kb(this,"Video",b);)this.I.push(b);this.ha=new rb({id:this.mf+".bus",busWidth:this.ea},this.A,this.Ia);var d,e=Ta(this.id);if((this.D=Va("Panel",
|
||||
this.id))&&this.D.hg)for(b=0;b<e.length;b++)d=e[b],d.Ba=this.D.Ba,d.rc=this.D.rc,d.hg=this.D.hg;this.rc("PCx86 v1.24.0\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>");for(b=0;b<e.length;b++)d=e[b],d.pc&&d.pc(this,this.ha,this.A,this.Ia);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.S=d:this.B=parseInt(d,10));var f;if(a=jc(this,"state")||(f=!0,a.state))b=this.W=a,f||(this.K=!0,this.B=ln),this.B&&(this.P=new be(this,"1.24.0"),
|
||||
this.P.load()?b=null:delete this.P);!b&&this.B&&(b=nn(this))&&(this.K=!0);if(b){var g=this;pa(b,null,!0,function(a,b,c){c?(g.S=null,g.K=!1,g.Ba("Unable to load machine state from server (error "+c+(b?": "+(String.prototype.trim?b.trim():b.replace(/^\s+|\s+$/g,"")):"")+")")):(g.R=b,g.Z=!0);ab(g)})}else ab(this);this.ka.power||(this.ba=!0);!c&&this.ba&&on(this,this.ff)}else p("Unable to find CPU component")}Qa(jn);var ln=0;l=jn.prototype;l.se=function(){return this.ma};
|
||||
function kn(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){p(d.message+" ("+c+")")}}a.L=b}function jc(a,b,c){var d=b.toLowerCase(),d=La[b]||La[d];void 0===d&&a.L&&(d=a.L[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}l.Ad=function(){return this.C||""};function on(a,b,c){for(var d=Ta(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!bb(f)){bb(f,function(){on(a,b,c)});return}}b.call(a,c)}
|
||||
function pn(a,b){var c=new be(a,"1.24.0","validate");if(c.load()&&qn(c)){var d=rn(c,"timestamp"),e=b?rn(b,"timestamp"):"unknown";d!=e&&(a.Ba("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
|
||||
l.ff=function(a){void 0===a&&(a=this.B||(this.R?1:ln));if(!this.G){this.G++;var b=!1,c=!1;this.Y=!1;var d=this.P||new be(this,"1.24.0");if(-1==a)b=!0;else if(a>ln){if(d.load(this.R)){this.H=new be(this,"1.24.0","failsafe");this.H.load()&&(sn(this,d),a=2,tn(this.H));C(this.H,"timestamp",la());un(this.H);var e=this.B&&!this.K;if(1==a||ra("Click OK to restore the previous PCx86 machine state, or CANCEL to reset the machine.")){if(c=qn(d)){var f=rn(d,"code"),g=rn(d,"data");f&&("ok"==f?d.load(g):("error"==
|
||||
f&&"no machine state"!=g?(this.Ba("Error: "+g),"unable to verify user"==g&&(xa("user",""),this.C=null)):this.rc(f+": "+g),tn(d),d.load()?(c=qn(d),e=!0):c=!1))}e&&pn(this,c?d:null)}else 2==a&&d.clear()}else pn(this);delete this.R;delete this.P}e=Ta(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.A&&(c=vn(this,g,d,b,c));b=[d,a,c];-1!=a?on(this,this.Oh,b):this.Oh(b)}};
|
||||
function vn(a,b,c,d,e){if(!b.da.Sb){b.da.Sb=!0;if(b.Vb){var f=null;e&&((f=rn(c,b.id))||(f=rn(c,b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.Vb(f,d)&&f&&(p("Unable to restore state for "+b.type),a.W&&!a.Z?(c.clear(),a.B=ln,window&&window.location.reload()):a.Y=!0,b.Vb(null),e=!1)}if(!d&&b.Ah)for(a=b.Ah.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
l.Oh=function(a){var b=a[0],c=0>a[1];a=a[2];this.la=!0;this.da.Sb=!0;var d=this.ka.power;d&&(d.textContent="Shutdown");this.A&&(vn(this,this.A,b,c,a),nc(this.A));this.Y&&(sn(this,b),b.clear());!c&&this.H&&(this.H.clear(),delete this.H);this.G=0};
|
||||
function sn(a,b){if(ra("There may be a problem with your PCx86 machine.\n\nTo help us diagnose it, click OK to send this PCx86 machine state to http://www.pcjs.org.")){var c=a.Ad(),d=b.toString(),e={app:"PCx86",ver:"1.24.0"};e.url=a.ia;e.user=c;e.type="bug";e.data=d;pa("http://www.pcjs.org/api/v1/report",e,!0)}}
|
||||
function wn(a,b,c){var d,e="none";if(a.G)return null;a.G--;var f=new be(a,"1.24.0"),g=new be(a,"1.24.0","validate"),h=la();C(g,"timestamp",h);C(f,"timestamp",h);C(f,"version","1.24.0");C(f,"url",window?window.location.href:null);C(f,"browser",window?window.navigator.userAgent:"");a.A&&a.A.Ub&&(c&&oc(a.A),d=a.A.Ub(b,c),"object"===typeof d&&C(f,a.A.id,d),c&&(a.A.da.Sb=!1,!1===d&&(e=null)));for(var h=Ta(a.id),k=0;k<h.length;k++){var m=h[k];m.da.Sb&&(m.Ub&&(d=m.Ub(b,c),"object"===typeof d&&C(f,m.id,d)),
|
||||
c&&(m.da.Sb=!1,!1===d&&(e=null)))}e&&(c?(h=d=!1,b?(a.C&&xn(a,a.C,f.toString()),un(g)&&un(f)||(e=null,d=h=!0)):a.B&&(d=!0,h=3==a.B),d&&f.clear(h)):e=f.toString());c&&(a.da.Sb=!1,b=a.ka.power)&&(b.textContent="Power");a.G=0;return e}l.reset=function(){this.ha&&this.ha.reset&&this.ha.reset();for(var a=Ta(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.ha&&c.reset&&c.reset()}};
|
||||
l.start=function(a,b){for(var c=Ta(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}};l.stop=function(a,b){for(var c=Ta(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.stop&&e.stop(a,b)}};
|
||||
l.zb=function(a,b,c){var d=this;switch(b){case "power":return this.ka[b]=c,c.onclick=function(){d.G||(d.da.Sb?xn(d,!1,!0):tn(d,d.ff))},!0;case "reset":return this.ka[b]=c,c.onclick=function(){if(d.da.Sb&&!d.G)if(d.B&&!d.S){var a=ra("Click OK to save changes to this PCx86 machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");xn(d,a,!0);!a&&d.W?window&&window.location.reload():(a||(d.kg=!0),d.ff(qn),d.kg=!1)}else d.reset(),d.A&&nc(d.A)},!0;case "save":if(ha(qa(),"pcjs.org")){c.parentNode.removeChild(c);
|
||||
break}this.ka[b]=c;c.onclick=function(){var a=rn(d,!0);if(a){var b=!!(d.B&&!d.S||d.W),c=xn(d,b);b?yn(d,a,c):d.Ba("Resume disabled, machine state not saved")}};return!0}return!1};
|
||||
function rn(a,b){var c=a.C;c||(c=wa("user"),void 0!==c?!c&&b&&(c=null,window&&(c=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c&&((c=zn(a,c))||a.Ba("The user ID is invalid."))):b&&a.Ba("Browser local storage is not available"));return c}
|
||||
function zn(a,b){a.C=null;var c=pa(qa()+"/api/v1/user?req=verify&user="+b),d=c[1];if(!c[0]&&d)try{c=eval("("+d+")"),c.code&&"ok"==c.code&&(xa("user",c.data),a.C=c.data)}catch(e){p(e.message+" ("+d+")")}return a.C}function sn(a){var b=null;a.C&&(b=qa()+"/api/v1/user?req=load&user="+a.C+"&state="+jn(a,"1.24.0"));return b}
|
||||
function yn(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=jn(a,"1.24.0");d.data=c;b=pa(qa()+"/api/v1/user",d);d=b[0];if(b[1]){if(d){var e=d.indexOf("\n");0<e&&(d=d.substr(0,e));d.indexOf("Error: ")||(d=d.substr(7))}d='{"code":'+b[1]+',"data":"'+d+'"}'}b=JSON.parse(d);b&&"ok"==b.code?a.Ba("Machine state saved to server"):c&&(c=b&&b.data||"unable to save machine state",c="error"==b.code?"Error: "+c:"Error "+b.code+": "+c,a.Ba(c),xa("user",""),a.C=null)}}
|
||||
l.zb=function(a,b,c){var d=this;switch(b){case "power":return this.ka[b]=c,c.onclick=function(){d.G||(d.da.Sb?wn(d,!1,!0):on(d,d.ff))},!0;case "reset":return this.ka[b]=c,c.onclick=function(){if(d.da.Sb&&!d.G)if(d.B&&!d.S){var a=ra("Click OK to save changes to this PCx86 machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");wn(d,a,!0);!a&&d.W?window&&window.location.reload():(a||(d.kg=!0),d.ff(ln),d.kg=!1)}else d.reset(),d.A&&nc(d.A)},!0;case "save":if(ha(qa(),"pcjs.org")){c.parentNode.removeChild(c);
|
||||
break}this.ka[b]=c;c.onclick=function(){var a=mn(d,!0);if(a){var b=!!(d.B&&!d.S||d.W),c=wn(d,b);b?xn(d,a,c):d.Ba("Resume disabled, machine state not saved")}};return!0}return!1};
|
||||
function mn(a,b){var c=a.C;c||(c=wa("user"),void 0!==c?!c&&b&&(c=null,window&&(c=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c&&((c=yn(a,c))||a.Ba("The user ID is invalid."))):b&&a.Ba("Browser local storage is not available"));return c}
|
||||
function yn(a,b){a.C=null;var c=pa(qa()+"/api/v1/user?req=verify&user="+b),d=c[1];if(!c[0]&&d)try{c=eval("("+d+")"),c.code&&"ok"==c.code&&(xa("user",c.data),a.C=c.data)}catch(e){p(e.message+" ("+d+")")}return a.C}function nn(a){var b=null;a.C&&(b=qa()+"/api/v1/user?req=load&user="+a.C+"&state="+zn(a,"1.24.0"));return b}
|
||||
function xn(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=zn(a,"1.24.0");d.data=c;b=pa(qa()+"/api/v1/user",d);d=b[0];if(b[1]){if(d){var e=d.indexOf("\n");0<e&&(d=d.substr(0,e));d.indexOf("Error: ")||(d=d.substr(7))}d='{"code":'+b[1]+',"data":"'+d+'"}'}b=JSON.parse(d);b&&"ok"==b.code?a.Ba("Machine state saved to server"):c&&(c=b&&b.data||"unable to save machine state",c="error"==b.code?"Error: "+c:"Error "+b.code+": "+c,a.Ba(c),xa("user",""),a.C=null)}}
|
||||
function kb(a,b,c){a=Ta(a.id);for(var d=0;d<a.length;d++){var e=a[d];if(c)c==e&&(c=null);else if(e.type==b)return e}return null}function uc(a,b){if(a.I.length){var c=0,d=0;b&&window&&(c=window.scrollX,d=window.scrollY);var e=a.I[0];e.G&&e.G.focus();b&&window&&window.scrollTo(c,d)}}l.Xd=function(a){this.A&&this.A.Xd(a);this.D&&this.D.Xd(a)};
|
||||
function xc(a,b){for(var c=0;c<a.I.length;c++)kl(a.I[c],b);if(a.D&&(c=a.D,c.ua)){ob(c,18,c.S,c.ra);if(c.Ga){var d=c.ha,e=c.B,f,g;null==f&&(f=0);null==g&&(g=d.L-f|0);null==e&&(e={gg:0,hd:0,ag:[]});var h=f>>>d.ea;f=f+g-1>>>d.ea;e.gg=0;for(e.hd=0;h<=f;)g=d.R[h],e.gg+=g.size,g.size&&(e.ag.push(na(nb,h,0,0,g.type)),e.hd++),h++;c.B=e;c.ma=c.B.hd*c.ha.xb/691200;d=0;c.B.Ih=0;c.B.Je||(c.B.Je=[]);var e=-1,h=0,k=-1;for(f=0;f<c.B.hd;f++){var m=c.B.ag[f];g=oa(nb.type,m);m=oa(nb.cj,m);if(g!=e||m!=k+1)(k=f-h)&&
|
||||
(d+=qb(c,h,k,e)),e=g,h=f;k=m}d+=qb(c,h,f-h,e);e=c.B.Cj!=d;c.B.Cj=d;if(e){e=new ib(0,0,c.S.width,c.S.height);c.B.ce=[];h=c.B.hd;for(d=0;d<c.B.Ih;d++)f=c.B.Je[d].hd,c.B.ce.push(jb(e,f,h,!d)),h-=f;for(d=0;d<c.B.ce.length;d++)e=c.B.Je[d],h=f=c.B.ce[d],g=c.ra,(k=Wb[e.type])||(k=new hb),g.strokeStyle="black",g.strokeRect(h.x,h.y,h.Fc,h.A),g.fillStyle="string"==typeof k?k:k.toString(),g.fillRect(h.x,h.y,h.Fc,h.A),h=c,g=f,h.P=h.ia,h.L=h.la,f=g.x+(g.Fc>>1),k=g.y+(g.A>>1),m=g.A,g.Fc<g.A&&(m=g.Fc,h.ea=!0,h.G.save(),
|
||||
h.G.translate(f,k),h.G.rotate(-Math.PI/2),f=k=0),m<h.L&&(h.L=m,h.P=h.L+"px Monaco, Lucida Console, Courier New"),g=k,h.D=f,h.K=g,h=c,e=Cb[e.type]+" ("+(e.hd*c.ha.xb/1024|0)+"Kb)",h.G.font=h.P,h.D-=h.G.measureText(e).width>>1,h.K+=(h.L>>1)-2,pb(h,e),h.ea&&(h.G.restore(),h.ea=!1)}}else pb(c,"This space intentionally left blank");c.context.drawImage(c.S,0,0,c.S.width,c.S.height,c.Oa,c.Xa,c.Da,c.Fa);c.ua=!1}}
|
||||
Ea(function(){for(var a=Za(document,"pcx86-machine"),b=0;b<a.length;b++)for(var c=a[b],d=Wa(c),c=Za(c,"pcx86","computer"),e=0;e<c.length;e++){var f=c[e],g=Wa(f),g=new on(g,d,!0);Ya(g,f);g.ba&&tn(g,g.ff)}});Aa.show.push(function(){for(var a=Za(document,"pcx86","computer"),b=0;b<a.length;b++){var c=Wa(a[b]);(c=Va("Computer",c.id))&&c.la&&!c.da.Sb&&c.ff(-1)}});
|
||||
Aa.exit.push(function(){for(var a=Za(document,"pcx86","computer"),b=0;b<a.length;b++){var c=Wa(a[b]);(c=Va("Computer",c.id))&&c.da.Sb&&xn(c,!(!c.B||c.S),!0)}});var An=0;function Bn(a,b,c,d,e,f){e("Loading "+a+"...");pa(a,null,!0,function(g,h,k){k?(h||(h="unable to load "+a+" ("+k+")"),f(h,null)):Cn(h,a,b,c,d,e,f)})}
|
||||
Ea(function(){for(var a=Za(document,"pcx86-machine"),b=0;b<a.length;b++)for(var c=a[b],d=Wa(c),c=Za(c,"pcx86","computer"),e=0;e<c.length;e++){var f=c[e],g=Wa(f),g=new jn(g,d,!0);Ya(g,f);g.ba&&on(g,g.ff)}});Aa.show.push(function(){for(var a=Za(document,"pcx86","computer"),b=0;b<a.length;b++){var c=Wa(a[b]);(c=Va("Computer",c.id))&&c.la&&!c.da.Sb&&c.ff(-1)}});
|
||||
Aa.exit.push(function(){for(var a=Za(document,"pcx86","computer"),b=0;b<a.length;b++){var c=Wa(a[b]);(c=Va("Computer",c.id))&&c.da.Sb&&wn(c,!(!c.B||c.S),!0)}});function be(a,b,c){this.id=a.id;this.key=zn(a,b,c);this.Ia=a.Ia;tn(this,a.gj)}function zn(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
be.prototype={constructor:be,value:function(){return this[this.id]},data:function(){return this[this.id]},load:function(a){return a?(this[this.id]=a,this.A=!0):this.A?!0:ta()&&(a=wa(this.key))?(this[this.id]=a,this.A=!0):!1},toString:function(){var a=this[this.id];return"string"==typeof a?a:JSON.stringify(a)},clear:function(a){tn(this);var b=[];try{for(var c=0,d=window.localStorage.length;c<d;c++)b.push(window.localStorage.key(c))}catch(e){}for(c=0;c<b.length;c++)if((d=b[c])&&(a||d.substr(0,this.key.length)==
|
||||
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function tn(a,b){a[a.id]={};b&&C(a,"parms",b);a.A=!1}function un(a){var b=!0;if(ta()){var c=JSON.stringify(a[a.id]);xa(a.key,c)||(p("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function qn(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){p(c.message||c),b=!1}return b}function rn(a,b){return a[a.id][b]||null}function C(a,b,c){try{a[a.id][b]=c}catch(d){}}var An=0;
|
||||
function Bn(a,b,c,d,e,f){e("Loading "+a+"...");pa(a,null,!0,function(g,h,k){k?(h||(h="unable to load "+a+" ("+k+")"),f(h,null)):Cn(h,a,b,c,d,e,f)})}
|
||||
function Cn(a,b,c,d,e,f,g){function h(a,f){if(f)g(f,null);else{if(c){Sa(c,b,a);var h=b;h&&0>h.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(h=window.location.pathname+h);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1<d.length&&(d+=",")):d='{state:"'+d+'",':d="{";d+='url:"'+h+'"}';"object"==typeof resources&&(h=null);a=a.replace(/(<machine[^>]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(h?' url="'+h+'"':""))}e||(a=a.replace(/(<xsl:variable name="APPCLASS">).*?(<\/xsl:variable>)/,"$1pcx86$2"));
|
||||
h=null;if("<"==a.charAt(0))try{e||(a=a.replace(/<!DOCTYPE(.|[\r\n])*]>\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(h=new window.ActiveXObject("Microsoft.XMLDOM"),h.async=!1,h.loadXML(a)):h=(new window.DOMParser).parseFromString(a,"text/xml")}catch(x){h=null,a=x.message}else a="unrecognized XML: "+(255<a.length?a.substr(0,255)+"...":a);g(a,h)}}a?e?Dn(a,f,h):h(a,null):g("no data"+(b?" for file: "+b:""),null)}
|
||||
function Dn(a,b,c){var d;if(d=/<([a-z]+)\s+ref="(.*?)"(.*?)\/>/g.exec(a)){var e=d[2];b("Loading "+e+"...");pa(e,null,!0,function(f,g,h){if(h||!g)c(a,"unable to resolve XML reference: "+d[0]+" ("+h+")");else{if(f=d[3])if(h=g.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var k=h[0],m,n=/( [a-z]+=)(['"])(.*?)\2/g;m=n.exec(f);)k=0>k.indexOf(m[1])?k.replace(">",m[0]+">"):k.replace(new RegExp(m[1]+"(['\"])(.*?)\\1"),m[0]);h[0]!=k&&(g=g.replace(h[0],k))}else{c(a,"missing <"+d[1]+"> in "+e);return}g=g.replace(/<\?xml[^>]*>[\r\n]*/,
|
||||
|
|
@ -632,4 +633,4 @@ a):f("transformToFragment failed")):f("unable to transform XML: unsupported brow
|
|||
function Gn(a,b,c,d){if(!c&&b){d.push(b);a=Ra[d[0]];b=null;for(var e in a)if(ha(e,"components.xsl")){b=e.replace(".xsl",".css");break}b?pa(b,null,!0,function(a,b){Hn(b,d)}):Hn(null,d)}else p("Error ("+c+") requesting "+a)}
|
||||
function Hn(a,b){var c,d,e,f=b[0],g=b[1];c=b[4];c=c.match(/^(\s*\(function\(\)\{)([\s\S]*)(}\)\(\);\s*)$/);var h=Ra[f],k={},m;for(m in h){var n=h[m],x=ga(m);if("xml"==x){for(x=/[ \t]*<disk [^>]*path=(['"])(.*?)\1.*?<\/disk>\n?/g;d=x.exec(h[m]);){var r=d[2];r&&(h[r]||(n=n.replace(d[0],"")))}d=m=fa(m)}else"xsl"==x&&(e=m=fa(m));k[m]=n}a&&(k[m="css"]=a);b[2]&&(k[m="parms"]=b[2]);b[3]&&(k[m="state"]=b[3]);d&&e?(m=JSON.stringify(k),g+=".js",c=c[1]+"var resources="+m+";"+c[2]+c[3],c=c.replace(/\u00A9/g,
|
||||
"©"),c=za(c,"javascript",!1,g),c=c+(', copy it to your web server as "'+g+'", and then add the following to your web page:\n\n')+('<div id="'+f+'"></div>\n'),c+="...\n",c+='<script type="text/javascript" src="'+g+'">\x3c/script>\n',c+='<script type="text/javascript">embedPC("'+f+'","'+d+'","'+e+'");\x3c/script>\n\n',c+="The machine should appear where the <div> is located.",p(c)):p("Missing XML/XSL resources")}
|
||||
window.savePC=function(a,b,c){var d=Va("Computer",a),e=Va("Debugger",a);if(d){var f=xn(d,!0),g=d.L?JSON.stringify(d.L):null;b||(b="/versions/pcjs/1.24.0/pc"+(e?"-dbg":"")+".js");if(c&&c({state:f,gj:g}))return!0;pa(b,null,!0,function(c,d,e){Gn(c,d,e,[a,fa(b,!0),g,f])});return!0}p("Unable to identify machine '"+a+"'");return!1};})();
|
||||
window.savePC=function(a,b,c){var d=Va("Computer",a),e=Va("Debugger",a);if(d){var f=wn(d,!0),g=d.L?JSON.stringify(d.L):null;b||(b="/versions/pcjs/1.24.0/pc"+(e?"-dbg":"")+".js");if(c&&c({state:f,gj:g}))return!0;pa(b,null,!0,function(c,d,e){Gn(c,d,e,[a,fa(b,!0),g,f])});return!0}p("Unable to identify machine '"+a+"'");return!1};})();
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ var sTemplateFile = "./modules/shared/templates/common.html";
|
|||
* HTML template file; sMachineXMLFile is a fallback file to look for when sReadMeFile doesn't exist.
|
||||
*/
|
||||
var sReadMeFile = "README.md";
|
||||
var sMachineMDFile = "machine.md";
|
||||
var sMachineXMLFile = "machine.xml";
|
||||
var sManifestXMLFile = "manifest.xml";
|
||||
|
||||
|
|
@ -1713,12 +1714,20 @@ HTMLOut.prototype.getMarkdownFile = function(sFile, sToken, sIndent, aParms, sPr
|
|||
{
|
||||
var obj = this;
|
||||
|
||||
sFile = path.join(this.sDir, sFile);
|
||||
var sFilePath = path.join(this.sDir, sFile);
|
||||
|
||||
HTMLOut.logConsole('HTMLOut.getMarkdownFile("' + sFile + '")');
|
||||
HTMLOut.logConsole('HTMLOut.getMarkdownFile("' + sFilePath + '")');
|
||||
|
||||
fs.readFile(sFile, {encoding: "utf8"}, function doneMarkdownFile(err, s) {
|
||||
fs.readFile(sFilePath, {encoding: "utf8"}, function doneMarkdownFile(err, s) {
|
||||
if (err) {
|
||||
/*
|
||||
* HACK to look for a "machine.md" if our attempt to load a "README.md" failed.
|
||||
*/
|
||||
if (sFile.indexOf(sReadMeFile) >= 0) {
|
||||
sFile = sFile.replace(sReadMeFile, sMachineMDFile);
|
||||
obj.getMarkdownFile(sFile, sToken, sIndent, aParms, sPrevious, sMachineFile);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Instead of displaying a cryptic error message inside our beautiful HTML template, eg:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -33,5 +33,4 @@ PC8080 is comprised of the following non-shared components, as listed in [packag
|
|||
* [video.js](/modules/pc8080/lib/video.js)
|
||||
* [serialport.js](/modules/pc8080/lib/serialport.js)
|
||||
* [debugger.js](/modules/pc8080/lib/debugger.js)
|
||||
* [state.js](/modules/pc8080/lib/state.js)
|
||||
* [computer.js](/modules/pc8080/lib/computer.js)
|
||||
|
|
|
|||
|
|
@ -35,23 +35,23 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var usr = require("../../shared/lib/usrlib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Memory = require("./memory");
|
||||
var Messages = require("./messages");
|
||||
var State = require("./state");
|
||||
var Memory8080 = require("./memory");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
* Bus(cpu, dbg)
|
||||
* Bus8080(cpu, dbg)
|
||||
*
|
||||
* The Bus component manages physical memory and I/O address spaces.
|
||||
* The Bus8080 component manages physical memory and I/O address spaces.
|
||||
*
|
||||
* The Bus component has no UI elements, so it does not require an init() handler,
|
||||
* The Bus8080 component has no UI elements, so it does not require an init() handler,
|
||||
* but it still inherits from the Component class and must be allocated like any
|
||||
* other device component. It's currently allocated by the Computer's init() handler,
|
||||
* which then calls the initBus() method of all the other components.
|
||||
*
|
||||
* For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped
|
||||
* devices), the address space must still be allocated through the Bus component via
|
||||
* devices), the address space must still be allocated through the Bus8080 component via
|
||||
* addMemory(). If the component needs something more than simple read/write storage,
|
||||
* it must provide a custom controller.
|
||||
*
|
||||
|
|
@ -63,12 +63,12 @@ if (NODE) {
|
|||
* @constructor
|
||||
* @extends Component
|
||||
* @param {Object} parmsBus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
function Bus(parmsBus, cpu, dbg)
|
||||
function Bus8080(parmsBus, cpu, dbg)
|
||||
{
|
||||
Component.call(this, "Bus", parmsBus, Bus);
|
||||
Component.call(this, "Bus", parmsBus, Bus8080);
|
||||
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
|
|
@ -76,7 +76,7 @@ function Bus(parmsBus, cpu, dbg)
|
|||
this.nBusWidth = parmsBus['busWidth'] || 16;
|
||||
|
||||
/*
|
||||
* Compute all Bus memory block parameters, based on the width of the bus.
|
||||
* Compute all Bus8080 memory block parameters, based on the width of the bus.
|
||||
*
|
||||
* Regarding blockTotal, we want to avoid using block overflow expressions like:
|
||||
*
|
||||
|
|
@ -121,7 +121,7 @@ function Bus(parmsBus, cpu, dbg)
|
|||
this.nBlockLimit = this.nBlockSize - 1;
|
||||
this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;
|
||||
this.nBlockMask = this.nBlockTotal - 1;
|
||||
this.assert(this.nBlockMask <= Bus.BlockInfo.num.mask);
|
||||
this.assert(this.nBlockMask <= Bus8080.BlockInfo.num.mask);
|
||||
|
||||
/*
|
||||
* Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by
|
||||
|
|
@ -164,9 +164,9 @@ function Bus(parmsBus, cpu, dbg)
|
|||
this.setReady();
|
||||
}
|
||||
|
||||
Component.subclass(Bus);
|
||||
Component.subclass(Bus8080);
|
||||
|
||||
Bus.ERROR = {
|
||||
Bus8080.ERROR = {
|
||||
ADD_MEM_INUSE: 1,
|
||||
ADD_MEM_BADRANGE: 2,
|
||||
SET_MEM_BADRANGE: 4,
|
||||
|
|
@ -188,10 +188,10 @@ var BlockInfo;
|
|||
* type: BitField
|
||||
* }}
|
||||
*/
|
||||
Bus.BlockInfo = usr.defineBitFields({num:20, count:8, btmod:1, type:3});
|
||||
Bus8080.BlockInfo = usr.defineBitFields({num:20, count:8, btmod:1, type:3});
|
||||
|
||||
/**
|
||||
* BusInfo object definition (returned by scanMemory())
|
||||
* Bus8080Info object definition (returned by scanMemory())
|
||||
*
|
||||
* cbTotal: total bytes allocated
|
||||
* cBlocks: total Memory blocks allocated
|
||||
|
|
@ -203,18 +203,18 @@ Bus.BlockInfo = usr.defineBitFields({num:20, count:8, btmod:1, type:3});
|
|||
* aBlocks: Array.<BlockInfo>
|
||||
* }}
|
||||
*/
|
||||
var BusInfo;
|
||||
var Bus8080Info;
|
||||
|
||||
/**
|
||||
* initMemory()
|
||||
*
|
||||
* Allocate enough (empty) Memory blocks to span the entire physical address space.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
*/
|
||||
Bus.prototype.initMemory = function()
|
||||
Bus8080.prototype.initMemory = function()
|
||||
{
|
||||
var block = new Memory();
|
||||
var block = new Memory8080();
|
||||
block.copyBreakpoints(this.dbg);
|
||||
this.aMemBlocks = new Array(this.nBlockTotal);
|
||||
for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {
|
||||
|
|
@ -225,9 +225,9 @@ Bus.prototype.initMemory = function()
|
|||
/**
|
||||
* reset()
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
*/
|
||||
Bus.prototype.reset = function()
|
||||
Bus8080.prototype.reset = function()
|
||||
{
|
||||
};
|
||||
|
||||
|
|
@ -243,12 +243,12 @@ Bus.prototype.reset = function()
|
|||
* TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler.
|
||||
* In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {Object|null} data (always null because we supply no powerDown() handler)
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
Bus.prototype.powerUp = function(data, fRepower)
|
||||
Bus8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) this.reset();
|
||||
return true;
|
||||
|
|
@ -267,7 +267,7 @@ Bus.prototype.powerUp = function(data, fRepower)
|
|||
* because machines with large block sizes can make it impossible to load certain ROMs at
|
||||
* their required addresses. Every allocation still allocates a whole number of blocks.
|
||||
*
|
||||
* Even so, Bus memory management does NOT provide a general-purpose heap. Most memory
|
||||
* Even so, Bus8080 memory management does NOT provide a general-purpose heap. Most memory
|
||||
* allocations occur during machine initialization and never change. In particular, there
|
||||
* is NO support for removing partial-block allocations.
|
||||
*
|
||||
|
|
@ -277,13 +277,13 @@ Bus.prototype.powerUp = function(data, fRepower)
|
|||
* space. However, any holes that might have existed between the original allocation and an
|
||||
* extension are subsumed by the extension.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is the starting physical address of the request
|
||||
* @param {number} size of the request, in bytes
|
||||
* @param {number} type is one of the Memory.TYPE constants
|
||||
* @param {number} type is one of the Memory8080.TYPE constants
|
||||
* @return {boolean} true if successful, false if not
|
||||
*/
|
||||
Bus.prototype.addMemory = function(addr, size, type)
|
||||
Bus8080.prototype.addMemory = function(addr, size, type)
|
||||
{
|
||||
var addrNext = addr;
|
||||
var sizeLeft = size;
|
||||
|
|
@ -319,10 +319,10 @@ Bus.prototype.addMemory = function(addr, size, type)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
return this.reportError(Bus.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft);
|
||||
return this.reportError(Bus8080.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft);
|
||||
}
|
||||
|
||||
var blockNew = new Memory(addrNext, sizeBlock, this.nBlockSize, type);
|
||||
var blockNew = new Memory8080(addrNext, sizeBlock, this.nBlockSize, type);
|
||||
blockNew.copyBreakpoints(this.dbg, block);
|
||||
this.aMemBlocks[iBlock++] = blockNew;
|
||||
|
||||
|
|
@ -331,22 +331,22 @@ Bus.prototype.addMemory = function(addr, size, type)
|
|||
}
|
||||
|
||||
if (sizeLeft <= 0) {
|
||||
this.status(Math.floor(size / 1024) + "Kb " + Memory.TYPE.NAMES[type] + " at " + str.toHexWord(addr));
|
||||
this.status(Math.floor(size / 1024) + "Kb " + Memory8080.TYPE.NAMES[type] + " at " + str.toHexWord(addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.reportError(Bus.ERROR.ADD_MEM_BADRANGE, addr, size);
|
||||
return this.reportError(Bus8080.ERROR.ADD_MEM_BADRANGE, addr, size);
|
||||
};
|
||||
|
||||
/**
|
||||
* cleanMemory(addr, size)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr
|
||||
* @param {number} size
|
||||
* @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process
|
||||
*/
|
||||
Bus.prototype.cleanMemory = function(addr, size)
|
||||
Bus8080.prototype.cleanMemory = function(addr, size)
|
||||
{
|
||||
var fClean = true;
|
||||
var iBlock = addr >>> this.nBlockShift;
|
||||
|
|
@ -364,15 +364,15 @@ Bus.prototype.cleanMemory = function(addr, size)
|
|||
/**
|
||||
* scanMemory(info, addr, size)
|
||||
*
|
||||
* Returns a BusInfo object for the specified address range.
|
||||
* Returns a Bus8080Info object for the specified address range.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @param {Object} [info] previous BusInfo, if any
|
||||
* @this {Bus8080}
|
||||
* @param {Object} [info] previous Bus8080Info, if any
|
||||
* @param {number} [addr] starting address of range (0 if none provided)
|
||||
* @param {number} [size] size of range, in bytes (up to end of address space if none provided)
|
||||
* @return {Object} updated info (or new info if no previous info provided)
|
||||
*/
|
||||
Bus.prototype.scanMemory = function(info, addr, size)
|
||||
Bus8080.prototype.scanMemory = function(info, addr, size)
|
||||
{
|
||||
if (addr == null) addr = 0;
|
||||
if (size == null) size = (this.addrTotal - addr) | 0;
|
||||
|
|
@ -387,7 +387,7 @@ Bus.prototype.scanMemory = function(info, addr, size)
|
|||
var block = this.aMemBlocks[iBlock];
|
||||
info.cbTotal += block.size;
|
||||
if (block.size) {
|
||||
info.aBlocks.push(usr.initBitFields(Bus.BlockInfo, iBlock, 0, 0, block.type));
|
||||
info.aBlocks.push(usr.initBitFields(Bus8080.BlockInfo, iBlock, 0, 0, block.type));
|
||||
info.cBlocks++
|
||||
}
|
||||
iBlock++;
|
||||
|
|
@ -398,10 +398,10 @@ Bus.prototype.scanMemory = function(info, addr, size)
|
|||
/**
|
||||
* getWidth()
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @return {number}
|
||||
*/
|
||||
Bus.prototype.getWidth = function()
|
||||
Bus8080.prototype.getWidth = function()
|
||||
{
|
||||
return this.nBusWidth;
|
||||
};
|
||||
|
|
@ -413,18 +413,18 @@ Bus.prototype.getWidth = function()
|
|||
*
|
||||
* TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr
|
||||
* @param {number} size
|
||||
* @return {boolean} true if successful, false if not
|
||||
*/
|
||||
Bus.prototype.removeMemory = function(addr, size)
|
||||
Bus8080.prototype.removeMemory = function(addr, size)
|
||||
{
|
||||
if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {
|
||||
var iBlock = addr >>> this.nBlockShift;
|
||||
while (size > 0) {
|
||||
var blockOld = this.aMemBlocks[iBlock];
|
||||
var blockNew = new Memory(addr);
|
||||
var blockNew = new Memory8080(addr);
|
||||
blockNew.copyBreakpoints(this.dbg, blockOld);
|
||||
this.aMemBlocks[iBlock++] = blockNew;
|
||||
addr = iBlock * this.nBlockSize;
|
||||
|
|
@ -432,18 +432,18 @@ Bus.prototype.removeMemory = function(addr, size)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
return this.reportError(Bus.ERROR.REM_MEM_BADRANGE, addr, size);
|
||||
return this.reportError(Bus8080.ERROR.REM_MEM_BADRANGE, addr, size);
|
||||
};
|
||||
|
||||
/**
|
||||
* getMemoryBlocks(addr, size)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is the starting physical address
|
||||
* @param {number} size of the request, in bytes
|
||||
* @return {Array} of Memory blocks
|
||||
*/
|
||||
Bus.prototype.getMemoryBlocks = function(addr, size)
|
||||
Bus8080.prototype.getMemoryBlocks = function(addr, size)
|
||||
{
|
||||
var aBlocks = [];
|
||||
var iBlock = addr >>> this.nBlockShift;
|
||||
|
|
@ -463,13 +463,13 @@ Bus.prototype.getMemoryBlocks = function(addr, size)
|
|||
* Otherwise, new blocks are allocated with the specified type; the underlying memory from the
|
||||
* provided blocks is still used, but the new blocks may have different access to that memory.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is the starting physical address
|
||||
* @param {number} size of the request, in bytes
|
||||
* @param {Array} aBlocks as returned by getMemoryBlocks()
|
||||
* @param {number} [type] is one of the Memory.TYPE constants
|
||||
* @param {number} [type] is one of the Memory8080.TYPE constants
|
||||
*/
|
||||
Bus.prototype.setMemoryBlocks = function(addr, size, aBlocks, type)
|
||||
Bus8080.prototype.setMemoryBlocks = function(addr, size, aBlocks, type)
|
||||
{
|
||||
var i = 0;
|
||||
var iBlock = addr >>> this.nBlockShift;
|
||||
|
|
@ -478,7 +478,7 @@ Bus.prototype.setMemoryBlocks = function(addr, size, aBlocks, type)
|
|||
this.assert(block);
|
||||
if (!block) break;
|
||||
if (type !== undefined) {
|
||||
var blockNew = new Memory(addr);
|
||||
var blockNew = new Memory8080(addr);
|
||||
blockNew.clone(block, type, this.dbg);
|
||||
block = blockNew;
|
||||
}
|
||||
|
|
@ -490,11 +490,11 @@ Bus.prototype.setMemoryBlocks = function(addr, size, aBlocks, type)
|
|||
/**
|
||||
* getByte(addr)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
Bus.prototype.getByte = function(addr)
|
||||
Bus8080.prototype.getByte = function(addr)
|
||||
{
|
||||
return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);
|
||||
};
|
||||
|
|
@ -504,11 +504,11 @@ Bus.prototype.getByte = function(addr)
|
|||
*
|
||||
* This is useful for the Debugger and other components that want to bypass getByte() breakpoint detection.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
Bus.prototype.getByteDirect = function(addr)
|
||||
Bus8080.prototype.getByteDirect = function(addr)
|
||||
{
|
||||
return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr);
|
||||
};
|
||||
|
|
@ -516,11 +516,11 @@ Bus.prototype.getByteDirect = function(addr)
|
|||
/**
|
||||
* getShort(addr)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @return {number} word (16-bit) value at that address
|
||||
*/
|
||||
Bus.prototype.getShort = function(addr)
|
||||
Bus8080.prototype.getShort = function(addr)
|
||||
{
|
||||
var off = addr & this.nBlockLimit;
|
||||
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
|
||||
|
|
@ -535,11 +535,11 @@ Bus.prototype.getShort = function(addr)
|
|||
*
|
||||
* This is useful for the Debugger and other components that want to bypass getShort() breakpoint detection.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @return {number} word (16-bit) value at that address
|
||||
*/
|
||||
Bus.prototype.getShortDirect = function(addr)
|
||||
Bus8080.prototype.getShortDirect = function(addr)
|
||||
{
|
||||
var off = addr & this.nBlockLimit;
|
||||
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
|
||||
|
|
@ -552,11 +552,11 @@ Bus.prototype.getShortDirect = function(addr)
|
|||
/**
|
||||
* setByte(addr, b)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)
|
||||
*/
|
||||
Bus.prototype.setByte = function(addr, b)
|
||||
Bus8080.prototype.setByte = function(addr, b)
|
||||
{
|
||||
this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);
|
||||
};
|
||||
|
|
@ -567,11 +567,11 @@ Bus.prototype.setByte = function(addr, b)
|
|||
* This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only
|
||||
* memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)
|
||||
*/
|
||||
Bus.prototype.setByteDirect = function(addr, b)
|
||||
Bus8080.prototype.setByteDirect = function(addr, b)
|
||||
{
|
||||
this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);
|
||||
};
|
||||
|
|
@ -579,11 +579,11 @@ Bus.prototype.setByteDirect = function(addr, b)
|
|||
/**
|
||||
* setShort(addr, w)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)
|
||||
*/
|
||||
Bus.prototype.setShort = function(addr, w)
|
||||
Bus8080.prototype.setShort = function(addr, w)
|
||||
{
|
||||
var off = addr & this.nBlockLimit;
|
||||
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
|
||||
|
|
@ -601,11 +601,11 @@ Bus.prototype.setShort = function(addr, w)
|
|||
* This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only
|
||||
* memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr is a physical address
|
||||
* @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)
|
||||
*/
|
||||
Bus.prototype.setShortDirect = function(addr, w)
|
||||
Bus8080.prototype.setShortDirect = function(addr, w)
|
||||
{
|
||||
var off = addr & this.nBlockLimit;
|
||||
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
|
||||
|
|
@ -620,11 +620,11 @@ Bus.prototype.setShortDirect = function(addr, w)
|
|||
/**
|
||||
* addMemBreak(addr, fWrite)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr
|
||||
* @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint
|
||||
*/
|
||||
Bus.prototype.addMemBreak = function(addr, fWrite)
|
||||
Bus8080.prototype.addMemBreak = function(addr, fWrite)
|
||||
{
|
||||
if (DEBUGGER) {
|
||||
var iBlock = addr >>> this.nBlockShift;
|
||||
|
|
@ -635,11 +635,11 @@ Bus.prototype.addMemBreak = function(addr, fWrite)
|
|||
/**
|
||||
* removeMemBreak(addr, fWrite)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} addr
|
||||
* @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint
|
||||
*/
|
||||
Bus.prototype.removeMemBreak = function(addr, fWrite)
|
||||
Bus8080.prototype.removeMemBreak = function(addr, fWrite)
|
||||
{
|
||||
if (DEBUGGER) {
|
||||
var iBlock = addr >>> this.nBlockShift;
|
||||
|
|
@ -672,11 +672,11 @@ Bus.prototype.removeMemBreak = function(addr, fWrite)
|
|||
* that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State
|
||||
* helper methods compress() and decompress() to create and expand the compressed data arrays.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)
|
||||
* @return {Array} a
|
||||
*/
|
||||
Bus.prototype.saveMemory = function(fAll)
|
||||
Bus8080.prototype.saveMemory = function(fAll)
|
||||
{
|
||||
var i = 0;
|
||||
var a = [];
|
||||
|
|
@ -688,7 +688,7 @@ Bus.prototype.saveMemory = function(fAll)
|
|||
* the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,
|
||||
* it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.
|
||||
*/
|
||||
if (fAll && block.type != Memory.TYPE.ROM || block.fDirty || block.fDirtyEver) {
|
||||
if (fAll && block.type != Memory8080.TYPE.ROM || block.fDirty || block.fDirtyEver) {
|
||||
a[i++] = iBlock;
|
||||
a[i++] = State.compress(block.save());
|
||||
}
|
||||
|
|
@ -710,11 +710,11 @@ Bus.prototype.saveMemory = function(fAll)
|
|||
*
|
||||
* See saveMemory() for more information on how the memory block contents are saved.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {Array} a
|
||||
* @return {boolean} true if successful, false if not
|
||||
*/
|
||||
Bus.prototype.restoreMemory = function(a)
|
||||
Bus8080.prototype.restoreMemory = function(a)
|
||||
{
|
||||
var i;
|
||||
for (i = 0; i < a.length - 1; i += 2) {
|
||||
|
|
@ -740,11 +740,11 @@ Bus.prototype.restoreMemory = function(a)
|
|||
/**
|
||||
* addPortInputBreak(port)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} [port]
|
||||
* @return {boolean} true if break on port input enabled, false if disabled
|
||||
*/
|
||||
Bus.prototype.addPortInputBreak = function(port)
|
||||
Bus8080.prototype.addPortInputBreak = function(port)
|
||||
{
|
||||
if (port === undefined) {
|
||||
this.fPortInputBreakAll = !this.fPortInputBreakAll;
|
||||
|
|
@ -762,12 +762,12 @@ Bus.prototype.addPortInputBreak = function(port)
|
|||
*
|
||||
* Add a port input-notification handler to the list of such handlers.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} start port address
|
||||
* @param {number} end port address
|
||||
* @param {function(number,number)} fn is called with the port and IP values at the time of the input
|
||||
*/
|
||||
Bus.prototype.addPortInputNotify = function(start, end, fn)
|
||||
Bus8080.prototype.addPortInputNotify = function(start, end, fn)
|
||||
{
|
||||
if (fn !== undefined) {
|
||||
for (var port = start; port <= end; port++) {
|
||||
|
|
@ -786,12 +786,12 @@ Bus.prototype.addPortInputNotify = function(start, end, fn)
|
|||
*
|
||||
* Add port input-notification handlers from the specified table (a batch version of addPortInputNotify)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {Component} component
|
||||
* @param {Object} table
|
||||
* @param {number} [offset] is an optional port offset
|
||||
*/
|
||||
Bus.prototype.addPortInputTable = function(component, table, offset)
|
||||
Bus8080.prototype.addPortInputTable = function(component, table, offset)
|
||||
{
|
||||
if (offset === undefined) offset = 0;
|
||||
if (table) {
|
||||
|
|
@ -806,11 +806,11 @@ Bus.prototype.addPortInputTable = function(component, table, offset)
|
|||
*
|
||||
* By default, all input ports are 1 byte wide; ports that are wider must call this function.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} port
|
||||
* @param {number} size (1, 2 or 4)
|
||||
*/
|
||||
Bus.prototype.addPortInputWidth = function(port, size)
|
||||
Bus8080.prototype.addPortInputWidth = function(port, size)
|
||||
{
|
||||
this.aPortInputWidth[port] = size;
|
||||
};
|
||||
|
|
@ -818,7 +818,7 @@ Bus.prototype.addPortInputWidth = function(port, size)
|
|||
/**
|
||||
* checkPortInputNotify(port, size, addrIP)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} port
|
||||
* @param {number} size (1, 2 or 4)
|
||||
* @param {number} [addrIP] is the IP value at the time of the input
|
||||
|
|
@ -827,7 +827,7 @@ Bus.prototype.addPortInputWidth = function(port, size)
|
|||
* NOTE: It seems that parts of the ROM BIOS (like the RS-232 probes around F000:E5D7 in the 5150 BIOS)
|
||||
* assume that ports for non-existent hardware return 0xff rather than 0x00, hence my new default (0xff) below.
|
||||
*/
|
||||
Bus.prototype.checkPortInputNotify = function(port, size, addrIP)
|
||||
Bus8080.prototype.checkPortInputNotify = function(port, size, addrIP)
|
||||
{
|
||||
var data = 0, shift = 0;
|
||||
|
||||
|
|
@ -882,11 +882,11 @@ Bus.prototype.checkPortInputNotify = function(port, size, addrIP)
|
|||
*
|
||||
* Remove port input-notification handler(s) (to be ENABLED later if needed)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} start address
|
||||
* @param {number} end address
|
||||
*
|
||||
Bus.prototype.removePortInputNotify = function(start, end)
|
||||
Bus8080.prototype.removePortInputNotify = function(start, end)
|
||||
{
|
||||
for (var port = start; port < end; port++) {
|
||||
if (this.aPortInputNotify[port]) {
|
||||
|
|
@ -899,11 +899,11 @@ Bus.prototype.removePortInputNotify = function(start, end)
|
|||
/**
|
||||
* addPortOutputBreak(port)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} [port]
|
||||
* @return {boolean} true if break on port output enabled, false if disabled
|
||||
*/
|
||||
Bus.prototype.addPortOutputBreak = function(port)
|
||||
Bus8080.prototype.addPortOutputBreak = function(port)
|
||||
{
|
||||
if (port === undefined) {
|
||||
this.fPortOutputBreakAll = !this.fPortOutputBreakAll;
|
||||
|
|
@ -921,12 +921,12 @@ Bus.prototype.addPortOutputBreak = function(port)
|
|||
*
|
||||
* Add a port output-notification handler to the list of such handlers.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} start port address
|
||||
* @param {number} end port address
|
||||
* @param {function(number,number)} fn is called with the port and IP values at the time of the output
|
||||
*/
|
||||
Bus.prototype.addPortOutputNotify = function(start, end, fn)
|
||||
Bus8080.prototype.addPortOutputNotify = function(start, end, fn)
|
||||
{
|
||||
if (fn !== undefined) {
|
||||
for (var port = start; port <= end; port++) {
|
||||
|
|
@ -945,12 +945,12 @@ Bus.prototype.addPortOutputNotify = function(start, end, fn)
|
|||
*
|
||||
* Add port output-notification handlers from the specified table (a batch version of addPortOutputNotify)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {Component} component
|
||||
* @param {Object} table
|
||||
* @param {number} [offset] is an optional port offset
|
||||
*/
|
||||
Bus.prototype.addPortOutputTable = function(component, table, offset)
|
||||
Bus8080.prototype.addPortOutputTable = function(component, table, offset)
|
||||
{
|
||||
if (offset === undefined) offset = 0;
|
||||
if (table) {
|
||||
|
|
@ -965,11 +965,11 @@ Bus.prototype.addPortOutputTable = function(component, table, offset)
|
|||
*
|
||||
* By default, all output ports are 1 byte wide; ports that are wider must call this function.
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} port
|
||||
* @param {number} size (1, 2 or 4)
|
||||
*/
|
||||
Bus.prototype.addPortOutputWidth = function(port, size)
|
||||
Bus8080.prototype.addPortOutputWidth = function(port, size)
|
||||
{
|
||||
this.aPortOutputWidth[port] = size;
|
||||
};
|
||||
|
|
@ -977,13 +977,13 @@ Bus.prototype.addPortOutputWidth = function(port, size)
|
|||
/**
|
||||
* checkPortOutputNotify(port, size, data, addrIP)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} port
|
||||
* @param {number} size
|
||||
* @param {number} data
|
||||
* @param {number} [addrIP] is the IP value at the time of the output
|
||||
*/
|
||||
Bus.prototype.checkPortOutputNotify = function(port, size, data, addrIP)
|
||||
Bus8080.prototype.checkPortOutputNotify = function(port, size, data, addrIP)
|
||||
{
|
||||
var shift = 0;
|
||||
|
||||
|
|
@ -1030,11 +1030,11 @@ Bus.prototype.checkPortOutputNotify = function(port, size, data, addrIP)
|
|||
*
|
||||
* Remove port output-notification handler(s) (to be ENABLED later if needed)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} start address
|
||||
* @param {number} end address
|
||||
*
|
||||
Bus.prototype.removePortOutputNotify = function(start, end)
|
||||
Bus8080.prototype.removePortOutputNotify = function(start, end)
|
||||
{
|
||||
for (var port = start; port < end; port++) {
|
||||
if (this.aPortOutputNotify[port]) {
|
||||
|
|
@ -1047,14 +1047,14 @@ Bus.prototype.removePortOutputNotify = function(start, end)
|
|||
/**
|
||||
* reportError(op, addr, size, fQuiet)
|
||||
*
|
||||
* @this {Bus}
|
||||
* @this {Bus8080}
|
||||
* @param {number} op
|
||||
* @param {number} addr
|
||||
* @param {number} size
|
||||
* @param {boolean} [fQuiet] (true if any error should be quietly logged)
|
||||
* @return {boolean} false
|
||||
*/
|
||||
Bus.prototype.reportError = function(op, addr, size, fQuiet)
|
||||
Bus8080.prototype.reportError = function(op, addr, size, fQuiet)
|
||||
{
|
||||
var sError = "Memory block error (" + op + ": " + str.toHex(addr) + "," + str.toHex(size) + ")";
|
||||
if (fQuiet) {
|
||||
|
|
@ -1069,4 +1069,4 @@ Bus.prototype.reportError = function(op, addr, size, fQuiet)
|
|||
return false;
|
||||
};
|
||||
|
||||
if (NODE) module.exports = Bus;
|
||||
if (NODE) module.exports = Bus8080;
|
||||
|
|
|
|||
|
|
@ -36,34 +36,34 @@ if (NODE) {
|
|||
var usr = require("../../shared/lib/usrlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
var State = require("./state");
|
||||
var CPUDef = require("./cpudef");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
* ChipSet(parmsChipSet)
|
||||
* ChipSet8080(parmsChipSet)
|
||||
*
|
||||
* The ChipSet component has the following component-specific (parmsChipSet) properties:
|
||||
* The ChipSet8080 component has the following component-specific (parmsChipSet) properties:
|
||||
*
|
||||
* model: eg, "SI1978" (should be a member of ChipSet.MODELS)
|
||||
* model: eg, "SI1978" (should be a member of ChipSet8080.MODELS)
|
||||
* swDIP: eg, "00000000", where swDIP[0] is DIP0, swDIP[1] is DIP1, etc.
|
||||
*
|
||||
* @constructor
|
||||
* @extends Component
|
||||
* @param {Object} parmsChipSet
|
||||
*/
|
||||
function ChipSet(parmsChipSet)
|
||||
function ChipSet8080(parmsChipSet)
|
||||
{
|
||||
Component.call(this, "ChipSet", parmsChipSet, ChipSet, Messages.CHIPSET);
|
||||
Component.call(this, "ChipSet", parmsChipSet, ChipSet8080, Messages8080.CHIPSET);
|
||||
|
||||
var model = parmsChipSet['model'];
|
||||
|
||||
if (model && !ChipSet.MODELS[model]) {
|
||||
if (model && !ChipSet8080.MODELS[model]) {
|
||||
Component.notice("Unrecognized ChipSet model: " + model);
|
||||
}
|
||||
|
||||
this.config = ChipSet.MODELS[model] || {};
|
||||
this.config = ChipSet8080.MODELS[model] || {};
|
||||
|
||||
this.bSwitches = this.parseDIPSwitches(parmsChipSet['swDIP']);
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ function ChipSet(parmsChipSet)
|
|||
this.setReady();
|
||||
}
|
||||
|
||||
Component.subclass(ChipSet);
|
||||
Component.subclass(ChipSet8080);
|
||||
|
||||
/*
|
||||
* NOTE: The STATUS1 port could have been handled entirely by the Keyboard component, but it was just as easy
|
||||
|
|
@ -106,7 +106,7 @@ Component.subclass(ChipSet);
|
|||
* button press or release. It's a six-of-one, half-a-dozen-of-another choice, since technically, Space Invaders
|
||||
* doesn't have a keyboard.
|
||||
*/
|
||||
ChipSet.SI1978 = {
|
||||
ChipSet8080.SI1978 = {
|
||||
MODEL: 1978.1,
|
||||
STATUS0: { // NOTE: STATUS0 not used by the SI1978 ROMs; refer to STATUS1 instead
|
||||
PORT: 0,
|
||||
|
|
@ -218,7 +218,7 @@ ChipSet.SI1978 = {
|
|||
* but some are more appropriately handled by other components; eg, port 0x82 is handled by the Keyboard component,
|
||||
* so it's defined there instead of here.
|
||||
*/
|
||||
ChipSet.VT100 = {
|
||||
ChipSet8080.VT100 = {
|
||||
MODEL: 100.0,
|
||||
FLAGS: {
|
||||
PORT: 0x42, // read-only
|
||||
|
|
@ -363,20 +363,20 @@ ChipSet.VT100 = {
|
|||
/*
|
||||
* Supported models and their configurations
|
||||
*/
|
||||
ChipSet.MODELS = {
|
||||
"SI1978": ChipSet.SI1978,
|
||||
"VT100": ChipSet.VT100
|
||||
ChipSet8080.MODELS = {
|
||||
"SI1978": ChipSet8080.SI1978,
|
||||
"VT100": ChipSet8080.VT100
|
||||
};
|
||||
|
||||
/**
|
||||
* parseDIPSwitches(sBits, bDefault)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {string} sBits describing switch settings
|
||||
* @param {number} [bDefault]
|
||||
* @return {number|undefined}
|
||||
*/
|
||||
ChipSet.prototype.parseDIPSwitches = function(sBits, bDefault)
|
||||
ChipSet8080.prototype.parseDIPSwitches = function(sBits, bDefault)
|
||||
{
|
||||
var b = bDefault;
|
||||
if (sBits) {
|
||||
|
|
@ -396,14 +396,14 @@ ChipSet.prototype.parseDIPSwitches = function(sBits, bDefault)
|
|||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "sw1")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
ChipSet.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
ChipSet8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
|
@ -411,21 +411,21 @@ ChipSet.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {ChipSet8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
ChipSet.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
ChipSet8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
this.cmp = cmp;
|
||||
this.kbd = /** @type {Keyboard} */ (cmp.getMachineComponent("Keyboard"));
|
||||
this.serial = /** @type {SerialPort} */ (cmp.getMachineComponent("SerialPort"));
|
||||
this.video = /** @type {Video} */ (cmp.getMachineComponent("Video"));
|
||||
this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent("Keyboard"));
|
||||
this.serial = /** @type {SerialPort8080} */ (cmp.getMachineComponent("SerialPort"));
|
||||
this.video = /** @type {Video8080} */ (cmp.getMachineComponent("Video"));
|
||||
bus.addPortInputTable(this, this.config.portsInput);
|
||||
bus.addPortOutputTable(this, this.config.portsOutput);
|
||||
};
|
||||
|
|
@ -433,12 +433,12 @@ ChipSet.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
ChipSet.prototype.powerUp = function(data, fRepower)
|
||||
ChipSet8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) {
|
||||
if (!data) {
|
||||
|
|
@ -453,39 +453,39 @@ ChipSet.prototype.powerUp = function(data, fRepower)
|
|||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
ChipSet.prototype.powerDown = function(fSave, fShutdown)
|
||||
ChipSet8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
return fSave? this.save() : true;
|
||||
};
|
||||
|
||||
ChipSet.SI1978.INIT = [
|
||||
ChipSet8080.SI1978.INIT = [
|
||||
[
|
||||
ChipSet.SI1978.STATUS0.ALWAYS_SET,
|
||||
ChipSet.SI1978.STATUS1.ALWAYS_SET,
|
||||
ChipSet.SI1978.STATUS2.ALWAYS_SET,
|
||||
ChipSet8080.SI1978.STATUS0.ALWAYS_SET,
|
||||
ChipSet8080.SI1978.STATUS1.ALWAYS_SET,
|
||||
ChipSet8080.SI1978.STATUS2.ALWAYS_SET,
|
||||
0, 0, 0, 0
|
||||
]
|
||||
];
|
||||
|
||||
ChipSet.VT100.INIT = [
|
||||
ChipSet8080.VT100.INIT = [
|
||||
[
|
||||
ChipSet.VT100.BRIGHTNESS.INIT,
|
||||
ChipSet.VT100.FLAGS.NO_AVO | ChipSet.VT100.FLAGS.NO_GFX
|
||||
ChipSet8080.VT100.BRIGHTNESS.INIT,
|
||||
ChipSet8080.VT100.FLAGS.NO_AVO | ChipSet8080.VT100.FLAGS.NO_GFX
|
||||
],
|
||||
[
|
||||
ChipSet.VT100.DC011.INITCOLS,
|
||||
ChipSet.VT100.DC011.INITRATE
|
||||
ChipSet8080.VT100.DC011.INITCOLS,
|
||||
ChipSet8080.VT100.DC011.INITRATE
|
||||
],
|
||||
[
|
||||
ChipSet.VT100.DC012.INITSCROLL,
|
||||
ChipSet.VT100.DC012.INITBLINK,
|
||||
ChipSet.VT100.DC012.INITREVERSE,
|
||||
ChipSet.VT100.DC012.INITATTR
|
||||
ChipSet8080.VT100.DC012.INITSCROLL,
|
||||
ChipSet8080.VT100.DC012.INITBLINK,
|
||||
ChipSet8080.VT100.DC012.INITREVERSE,
|
||||
ChipSet8080.VT100.DC012.INITATTR
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0,
|
||||
|
|
@ -507,9 +507,9 @@ ChipSet.VT100.INIT = [
|
|||
/**
|
||||
* reset()
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
*/
|
||||
ChipSet.prototype.reset = function()
|
||||
ChipSet8080.prototype.reset = function()
|
||||
{
|
||||
if (this.config.INIT && !this.restore(this.config.INIT)) {
|
||||
this.notice("reset error");
|
||||
|
|
@ -521,17 +521,17 @@ ChipSet.prototype.reset = function()
|
|||
*
|
||||
* This implements save support for the ChipSet component.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @return {Object}
|
||||
*/
|
||||
ChipSet.prototype.save = function()
|
||||
ChipSet8080.prototype.save = function()
|
||||
{
|
||||
var state = new State(this);
|
||||
switch(this.config.MODEL) {
|
||||
case ChipSet.SI1978.MODEL:
|
||||
case ChipSet8080.SI1978.MODEL:
|
||||
state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.wShiftData, this.bShiftCount, this.bSound1, this.bSound2]);
|
||||
break;
|
||||
case ChipSet.VT100.MODEL:
|
||||
case ChipSet8080.VT100.MODEL:
|
||||
state.set(0, [this.bBrightness, this.bFlags]);
|
||||
state.set(1, [this.bDC011Cols, this.bDC011Rate]);
|
||||
state.set(2, [this.bDC012Scroll, this.bDC012Blink, this.bDC012Reverse, this.bDC012Attr]);
|
||||
|
|
@ -546,16 +546,16 @@ ChipSet.prototype.save = function()
|
|||
*
|
||||
* This implements restore support for the ChipSet component.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
ChipSet.prototype.restore = function(data)
|
||||
ChipSet8080.prototype.restore = function(data)
|
||||
{
|
||||
var a;
|
||||
if (data && (a = data[0]) && a.length) {
|
||||
switch(this.config.MODEL) {
|
||||
case ChipSet.SI1978.MODEL:
|
||||
case ChipSet8080.SI1978.MODEL:
|
||||
this.bStatus0 = a[0];
|
||||
this.bStatus1 = a[1];
|
||||
this.bStatus2 = a[2];
|
||||
|
|
@ -564,7 +564,7 @@ ChipSet.prototype.restore = function(data)
|
|||
this.bSound1 = a[5];
|
||||
this.bSound2 = a[6];
|
||||
return true;
|
||||
case ChipSet.VT100.MODEL:
|
||||
case ChipSet8080.VT100.MODEL:
|
||||
this.bBrightness = a[0];
|
||||
this.bFlags = a[1];
|
||||
a = data[1];
|
||||
|
|
@ -592,9 +592,9 @@ ChipSet.prototype.restore = function(data)
|
|||
*
|
||||
* Notification from the CPU that it's starting.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
*/
|
||||
ChipSet.prototype.start = function()
|
||||
ChipSet8080.prototype.start = function()
|
||||
{
|
||||
/*
|
||||
* Currently, all we (may) do with this notification is allow the speaker to make noise.
|
||||
|
|
@ -606,9 +606,9 @@ ChipSet.prototype.start = function()
|
|||
*
|
||||
* Notification from the CPU that it's stopping.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
*/
|
||||
ChipSet.prototype.stop = function()
|
||||
ChipSet8080.prototype.stop = function()
|
||||
{
|
||||
/*
|
||||
* Currently, all we (may) do with this notification is prevent the speaker from making noise.
|
||||
|
|
@ -618,11 +618,11 @@ ChipSet.prototype.stop = function()
|
|||
/**
|
||||
* updateStatus0(bit, fSet)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} bit
|
||||
* @param {boolean} fSet
|
||||
*/
|
||||
ChipSet.prototype.updateStatus0 = function(bit, fSet)
|
||||
ChipSet8080.prototype.updateStatus0 = function(bit, fSet)
|
||||
{
|
||||
this.bStatus0 &= ~bit;
|
||||
if (fSet) this.bStatus0 |= bit;
|
||||
|
|
@ -631,11 +631,11 @@ ChipSet.prototype.updateStatus0 = function(bit, fSet)
|
|||
/**
|
||||
* updateStatus1(bit, fSet)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} bit
|
||||
* @param {boolean} fSet
|
||||
*/
|
||||
ChipSet.prototype.updateStatus1 = function(bit, fSet)
|
||||
ChipSet8080.prototype.updateStatus1 = function(bit, fSet)
|
||||
{
|
||||
this.bStatus1 &= ~bit;
|
||||
if (fSet) this.bStatus1 |= bit;
|
||||
|
|
@ -644,11 +644,11 @@ ChipSet.prototype.updateStatus1 = function(bit, fSet)
|
|||
/**
|
||||
* updateStatus2(bit, fSet)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} bit
|
||||
* @param {boolean} fSet
|
||||
*/
|
||||
ChipSet.prototype.updateStatus2 = function(bit, fSet)
|
||||
ChipSet8080.prototype.updateStatus2 = function(bit, fSet)
|
||||
{
|
||||
this.bStatus2 &= ~bit;
|
||||
if (fSet) this.bStatus2 |= bit;
|
||||
|
|
@ -657,12 +657,12 @@ ChipSet.prototype.updateStatus2 = function(bit, fSet)
|
|||
/**
|
||||
* inSIStatus0(port, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x00)
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
ChipSet.prototype.inSIStatus0 = function(port, addrFrom)
|
||||
ChipSet8080.prototype.inSIStatus0 = function(port, addrFrom)
|
||||
{
|
||||
var b = this.bStatus0;
|
||||
this.printMessageIO(port, null, addrFrom, "STATUS0", b, true);
|
||||
|
|
@ -672,12 +672,12 @@ ChipSet.prototype.inSIStatus0 = function(port, addrFrom)
|
|||
/**
|
||||
* inSIStatus1(port, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x01)
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
ChipSet.prototype.inSIStatus1 = function(port, addrFrom)
|
||||
ChipSet8080.prototype.inSIStatus1 = function(port, addrFrom)
|
||||
{
|
||||
var b = this.bStatus1;
|
||||
this.printMessageIO(port, null, addrFrom, "STATUS1", b, true);
|
||||
|
|
@ -687,12 +687,12 @@ ChipSet.prototype.inSIStatus1 = function(port, addrFrom)
|
|||
/**
|
||||
* inSIStatus2(port, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x02)
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
ChipSet.prototype.inSIStatus2 = function(port, addrFrom)
|
||||
ChipSet8080.prototype.inSIStatus2 = function(port, addrFrom)
|
||||
{
|
||||
var b = this.bStatus2;
|
||||
this.printMessageIO(port, null, addrFrom, "STATUS2", b, true);
|
||||
|
|
@ -702,12 +702,12 @@ ChipSet.prototype.inSIStatus2 = function(port, addrFrom)
|
|||
/**
|
||||
* inSIShiftResult(port, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x03)
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
ChipSet.prototype.inSIShiftResult = function(port, addrFrom)
|
||||
ChipSet8080.prototype.inSIShiftResult = function(port, addrFrom)
|
||||
{
|
||||
var b = (this.wShiftData >> (8 - this.bShiftCount)) & 0xff;
|
||||
this.printMessageIO(port, null, addrFrom, "SHIFT.RESULT", b, true);
|
||||
|
|
@ -717,12 +717,12 @@ ChipSet.prototype.inSIShiftResult = function(port, addrFrom)
|
|||
/**
|
||||
* outSIShiftCount(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x02)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outSIShiftCount = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outSIShiftCount = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "SHIFT.COUNT", null, true);
|
||||
this.bShiftCount = b;
|
||||
|
|
@ -731,12 +731,12 @@ ChipSet.prototype.outSIShiftCount = function(port, b, addrFrom)
|
|||
/**
|
||||
* outSISound1(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x03)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outSISound1 = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outSISound1 = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "SOUND1", null, true);
|
||||
this.bSound1 = b;
|
||||
|
|
@ -745,12 +745,12 @@ ChipSet.prototype.outSISound1 = function(port, b, addrFrom)
|
|||
/**
|
||||
* outSIShiftData(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x04)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outSIShiftData = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outSIShiftData = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "SHIFT.DATA", null, true);
|
||||
this.wShiftData = (b << 8) | (this.wShiftData >> 8);
|
||||
|
|
@ -759,12 +759,12 @@ ChipSet.prototype.outSIShiftData = function(port, b, addrFrom)
|
|||
/**
|
||||
* outSISound2(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x05)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outSISound2 = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outSISound2 = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "SOUND2", null, true);
|
||||
this.bSound2 = b;
|
||||
|
|
@ -773,12 +773,12 @@ ChipSet.prototype.outSISound2 = function(port, b, addrFrom)
|
|||
/**
|
||||
* outSIWatchdog(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x06)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outSIWatchdog = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outSIWatchdog = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "WATCHDOG", null, true);
|
||||
};
|
||||
|
|
@ -796,7 +796,7 @@ ChipSet.prototype.outSIWatchdog = function(port, b, addrFrom)
|
|||
* @param {number} iBit
|
||||
* @return {number}
|
||||
*/
|
||||
ChipSet.prototype.getVT100LBA = function(iBit)
|
||||
ChipSet8080.prototype.getVT100LBA = function(iBit)
|
||||
{
|
||||
return (this.cpu.getCycles() & (1 << (iBit - 1))) << 1;
|
||||
};
|
||||
|
|
@ -806,7 +806,7 @@ ChipSet.prototype.getVT100LBA = function(iBit)
|
|||
*
|
||||
* @return {number}
|
||||
*/
|
||||
ChipSet.prototype.getNVRAddr = function()
|
||||
ChipSet8080.prototype.getNVRAddr = function()
|
||||
{
|
||||
var i;
|
||||
var tens = 0, ones = 0;
|
||||
|
|
@ -827,54 +827,54 @@ ChipSet.prototype.getNVRAddr = function()
|
|||
/**
|
||||
* doNVRCommand()
|
||||
*/
|
||||
ChipSet.prototype.doNVRCommand = function()
|
||||
ChipSet8080.prototype.doNVRCommand = function()
|
||||
{
|
||||
var addr, data;
|
||||
var bit = this.bNVRLatch & 0x1;
|
||||
var bCmd = (this.bNVRLatch >> 1) & 0x7;
|
||||
|
||||
switch(bCmd) {
|
||||
case ChipSet.VT100.NVR.CMD.STANDBY:
|
||||
case ChipSet8080.VT100.NVR.CMD.STANDBY:
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.ACCEPT_ADDR:
|
||||
case ChipSet8080.VT100.NVR.CMD.ACCEPT_ADDR:
|
||||
this.dNVRAddr = (this.dNVRAddr << 1) | bit;
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.ERASE:
|
||||
case ChipSet8080.VT100.NVR.CMD.ERASE:
|
||||
addr = this.getNVRAddr();
|
||||
this.aNVRWords[addr] = ChipSet.VT100.NVR.WORDMASK;
|
||||
this.aNVRWords[addr] = ChipSet8080.VT100.NVR.WORDMASK;
|
||||
this.printMessage("doNVRCommand(): erase data at addr " + str.toHexWord(addr));
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.ACCEPT_DATA:
|
||||
case ChipSet8080.VT100.NVR.CMD.ACCEPT_DATA:
|
||||
this.wNVRData = (this.wNVRData << 1) | bit;
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.WRITE:
|
||||
case ChipSet8080.VT100.NVR.CMD.WRITE:
|
||||
addr = this.getNVRAddr();
|
||||
data = this.wNVRData & ChipSet.VT100.NVR.WORDMASK;
|
||||
data = this.wNVRData & ChipSet8080.VT100.NVR.WORDMASK;
|
||||
this.aNVRWords[addr] = data;
|
||||
this.printMessage("doNVRCommand(): write data " + str.toHexWord(data) + " to addr " + str.toHexWord(addr));
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.READ:
|
||||
case ChipSet8080.VT100.NVR.CMD.READ:
|
||||
addr = this.getNVRAddr();
|
||||
data = this.aNVRWords[addr];
|
||||
/*
|
||||
* If we don't explicitly initialize aNVRWords[], pretend any uninitialized words contains WORDMASK.
|
||||
*/
|
||||
if (data == null) data = ChipSet.VT100.NVR.WORDMASK;
|
||||
if (data == null) data = ChipSet8080.VT100.NVR.WORDMASK;
|
||||
this.wNVRData = data;
|
||||
this.printMessage("doNVRCommand(): read data " + str.toHexWord(data) + " from addr " + str.toHexWord(addr));
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.SHIFT_OUT:
|
||||
case ChipSet8080.VT100.NVR.CMD.SHIFT_OUT:
|
||||
this.wNVRData <<= 1;
|
||||
/*
|
||||
* Since WORDMASK is 0x3fff, this will mask the shifted data with 0x4000, which is the bit we want to isolate.
|
||||
*/
|
||||
this.bNVROut = this.wNVRData & (ChipSet.VT100.NVR.WORDMASK + 1);
|
||||
this.bNVROut = this.wNVRData & (ChipSet8080.VT100.NVR.WORDMASK + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -886,35 +886,35 @@ ChipSet.prototype.doNVRCommand = function()
|
|||
/**
|
||||
* inVT100Flags(port, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x42)
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
ChipSet.prototype.inVT100Flags = function(port, addrFrom)
|
||||
ChipSet8080.prototype.inVT100Flags = function(port, addrFrom)
|
||||
{
|
||||
/*
|
||||
* The NVR_CLK bit is driven by LBA7 (ie, bit 7 from Line Buffer Address generation); see the DC011 discussion above.
|
||||
*/
|
||||
var b = this.bFlags;
|
||||
b &= ~ChipSet.VT100.FLAGS.NVR_CLK;
|
||||
b &= ~ChipSet8080.VT100.FLAGS.NVR_CLK;
|
||||
if (this.getVT100LBA(7)) {
|
||||
b |= ChipSet.VT100.FLAGS.NVR_CLK;
|
||||
b |= ChipSet8080.VT100.FLAGS.NVR_CLK;
|
||||
if (b != this.bFlags) {
|
||||
this.doNVRCommand();
|
||||
}
|
||||
}
|
||||
b &= ~ChipSet.VT100.FLAGS.NVR_DATA;
|
||||
b &= ~ChipSet8080.VT100.FLAGS.NVR_DATA;
|
||||
if (this.bNVROut) {
|
||||
b |= ChipSet.VT100.FLAGS.NVR_DATA;
|
||||
b |= ChipSet8080.VT100.FLAGS.NVR_DATA;
|
||||
}
|
||||
b &= ~ChipSet.VT100.FLAGS.KBD_XMIT;
|
||||
b &= ~ChipSet8080.VT100.FLAGS.KBD_XMIT;
|
||||
if (this.kbd && this.kbd.isTransmitterReady()) {
|
||||
b |= ChipSet.VT100.FLAGS.KBD_XMIT;
|
||||
b |= ChipSet8080.VT100.FLAGS.KBD_XMIT;
|
||||
}
|
||||
b &= ~ChipSet.VT100.FLAGS.UART_XMIT;
|
||||
b &= ~ChipSet8080.VT100.FLAGS.UART_XMIT;
|
||||
if (this.serial && this.serial.isTransmitterReady()) {
|
||||
b |= ChipSet.VT100.FLAGS.UART_XMIT;
|
||||
b |= ChipSet8080.VT100.FLAGS.UART_XMIT;
|
||||
}
|
||||
this.bFlags = b;
|
||||
this.printMessageIO(port, null, addrFrom, "FLAGS", b);
|
||||
|
|
@ -924,12 +924,12 @@ ChipSet.prototype.inVT100Flags = function(port, addrFrom)
|
|||
/**
|
||||
* outVT100Brightness(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x42)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outVT100Brightness = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outVT100Brightness = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "BRIGHTNESS");
|
||||
this.bBrightness = b;
|
||||
|
|
@ -938,12 +938,12 @@ ChipSet.prototype.outVT100Brightness = function(port, b, addrFrom)
|
|||
/**
|
||||
* outVT100NVRLatch(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0x62)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outVT100NVRLatch = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outVT100NVRLatch = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "NVR.LATCH");
|
||||
this.bNVRLatch = b;
|
||||
|
|
@ -955,12 +955,12 @@ ChipSet.prototype.outVT100NVRLatch = function(port, b, addrFrom)
|
|||
* TODO: Consider whether we should disable any interrupts (eg, vertical retrace) until
|
||||
* this port is initialized at runtime.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0xA2)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outVT100DC012 = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outVT100DC012 = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "DC012");
|
||||
|
||||
|
|
@ -997,29 +997,29 @@ ChipSet.prototype.outVT100DC012 = function(port, b, addrFrom)
|
|||
/**
|
||||
* outVT100DC011(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @this {ChipSet8080}
|
||||
* @param {number} port (0xC2)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outVT100DC011 = function(port, b, addrFrom)
|
||||
ChipSet8080.prototype.outVT100DC011 = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "DC011");
|
||||
if (b & ChipSet.VT100.DC011.RATE60) {
|
||||
b &= ChipSet.VT100.DC011.RATE50;
|
||||
if (b & ChipSet8080.VT100.DC011.RATE60) {
|
||||
b &= ChipSet8080.VT100.DC011.RATE50;
|
||||
if (this.bDC011Rate != b) {
|
||||
this.bDC011Rate = b;
|
||||
if (this.video) {
|
||||
this.video.updateRate(this.bDC011Rate == ChipSet.VT100.DC011.RATE50? 50 : 60);
|
||||
this.video.updateRate(this.bDC011Rate == ChipSet8080.VT100.DC011.RATE50? 50 : 60);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
b &= ChipSet.VT100.DC011.COLS132;
|
||||
b &= ChipSet8080.VT100.DC011.COLS132;
|
||||
if (this.bDC011Cols != b) {
|
||||
this.bDC011Cols = b;
|
||||
if (this.video) {
|
||||
var nCols = (this.bDC011Cols == ChipSet.VT100.DC011.COLS132? 132 : 80);
|
||||
var nRows = (nCols > 80 && (this.bFlags & ChipSet.VT100.FLAGS.NO_AVO)? 14 : 24);
|
||||
var nCols = (this.bDC011Cols == ChipSet8080.VT100.DC011.COLS132? 132 : 80);
|
||||
var nRows = (nCols > 80 && (this.bFlags & ChipSet8080.VT100.FLAGS.NO_AVO)? 14 : 24);
|
||||
this.video.updateDimensions(nCols, nRows);
|
||||
}
|
||||
}
|
||||
|
|
@ -1029,47 +1029,47 @@ ChipSet.prototype.outVT100DC011 = function(port, b, addrFrom)
|
|||
/*
|
||||
* Port notification tables
|
||||
*/
|
||||
ChipSet.SI1978.portsInput = {
|
||||
0x00: ChipSet.prototype.inSIStatus0,
|
||||
0x01: ChipSet.prototype.inSIStatus1,
|
||||
0x02: ChipSet.prototype.inSIStatus2,
|
||||
0x03: ChipSet.prototype.inSIShiftResult
|
||||
ChipSet8080.SI1978.portsInput = {
|
||||
0x00: ChipSet8080.prototype.inSIStatus0,
|
||||
0x01: ChipSet8080.prototype.inSIStatus1,
|
||||
0x02: ChipSet8080.prototype.inSIStatus2,
|
||||
0x03: ChipSet8080.prototype.inSIShiftResult
|
||||
};
|
||||
|
||||
ChipSet.SI1978.portsOutput = {
|
||||
0x02: ChipSet.prototype.outSIShiftCount,
|
||||
0x03: ChipSet.prototype.outSISound1,
|
||||
0x04: ChipSet.prototype.outSIShiftData,
|
||||
0x05: ChipSet.prototype.outSISound2,
|
||||
0x06: ChipSet.prototype.outSIWatchdog
|
||||
ChipSet8080.SI1978.portsOutput = {
|
||||
0x02: ChipSet8080.prototype.outSIShiftCount,
|
||||
0x03: ChipSet8080.prototype.outSISound1,
|
||||
0x04: ChipSet8080.prototype.outSIShiftData,
|
||||
0x05: ChipSet8080.prototype.outSISound2,
|
||||
0x06: ChipSet8080.prototype.outSIWatchdog
|
||||
};
|
||||
|
||||
ChipSet.VT100.portsInput = {
|
||||
0x42: ChipSet.prototype.inVT100Flags
|
||||
ChipSet8080.VT100.portsInput = {
|
||||
0x42: ChipSet8080.prototype.inVT100Flags
|
||||
};
|
||||
|
||||
ChipSet.VT100.portsOutput = {
|
||||
0x42: ChipSet.prototype.outVT100Brightness,
|
||||
0x62: ChipSet.prototype.outVT100NVRLatch,
|
||||
0xA2: ChipSet.prototype.outVT100DC012,
|
||||
0xC2: ChipSet.prototype.outVT100DC011
|
||||
ChipSet8080.VT100.portsOutput = {
|
||||
0x42: ChipSet8080.prototype.outVT100Brightness,
|
||||
0x62: ChipSet8080.prototype.outVT100NVRLatch,
|
||||
0xA2: ChipSet8080.prototype.outVT100DC012,
|
||||
0xC2: ChipSet8080.prototype.outVT100DC011
|
||||
};
|
||||
|
||||
/**
|
||||
* ChipSet.init()
|
||||
* ChipSet8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "chipset", extracting the
|
||||
* JSON-encoded parameters for the ChipSet constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a ChipSet component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*/
|
||||
ChipSet.init = function()
|
||||
ChipSet8080.init = function()
|
||||
{
|
||||
var aeChipSet = Component.getElementsByClass(document, PC8080.APPCLASS, "chipset");
|
||||
for (var iChip = 0; iChip < aeChipSet.length; iChip++) {
|
||||
var eChipSet = aeChipSet[iChip];
|
||||
var parmsChipSet = Component.getComponentParms(eChipSet);
|
||||
var chipset = new ChipSet(parmsChipSet);
|
||||
var chipset = new ChipSet8080(parmsChipSet);
|
||||
Component.bindComponentControls(chipset, eChipSet, PC8080.APPCLASS);
|
||||
}
|
||||
};
|
||||
|
|
@ -1077,6 +1077,6 @@ ChipSet.init = function()
|
|||
/*
|
||||
* Initialize every ChipSet module on the page.
|
||||
*/
|
||||
web.onInit(ChipSet.init);
|
||||
web.onInit(ChipSet8080.init);
|
||||
|
||||
if (NODE) module.exports = ChipSet;
|
||||
if (NODE) module.exports = ChipSet8080;
|
||||
|
|
|
|||
|
|
@ -42,13 +42,13 @@ if (NODE) {
|
|||
* TODO: I'm confused why WebStorm complains if the following require() is missing in THIS file but not other files.
|
||||
*/
|
||||
var PC8080 = require("./defines");
|
||||
var Messages = require("./messages");
|
||||
var Bus = require("./bus");
|
||||
var State = require("./state");
|
||||
var Bus8080 = require("./bus");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
* Computer(parmsComputer, parmsMachine, fSuspended)
|
||||
* Computer8080(parmsComputer, parmsMachine, fSuspended)
|
||||
*
|
||||
* @constructor
|
||||
* @extends Component
|
||||
|
|
@ -56,7 +56,7 @@ if (NODE) {
|
|||
* @param {Object} [parmsMachine]
|
||||
* @param {boolean} [fSuspended]
|
||||
*
|
||||
* The Computer component has no required (parmsComputer) properties, but it does
|
||||
* The Computer8080 component has no required (parmsComputer) properties, but it does
|
||||
* support the following:
|
||||
*
|
||||
* autoPower: true to automatically power the computer (default), false to wait;
|
||||
|
|
@ -67,7 +67,7 @@ if (NODE) {
|
|||
* while 24 is required for 80286 protected-mode addressing. This value is passed
|
||||
* directly through to the Bus component; see that component for more details.
|
||||
*
|
||||
* resume: one of the Computer.RESUME constants, which are as follows:
|
||||
* resume: one of the Computer8080.RESUME constants, which are as follows:
|
||||
* '0' if resume disabled (default)
|
||||
* '1' if enabled without prompting
|
||||
* '2' if enabled with prompting
|
||||
|
|
@ -81,13 +81,13 @@ if (NODE) {
|
|||
* autoMount: if set, this should override any 'autoMount' property in the FDC's
|
||||
* parmsFDC object.
|
||||
*
|
||||
* autoPower: if set, this should override any 'autoPower' property in the Computer's
|
||||
* autoPower: if set, this should override any 'autoPower' property in the Computer8080's
|
||||
* parmsComputer object.
|
||||
*
|
||||
* messages: if set, this should override any 'messages' property in the Debugger's
|
||||
* parmsDbg object.
|
||||
*
|
||||
* state: if set, this should override any 'state' property in the Computer's
|
||||
* state: if set, this should override any 'state' property in the Computer8080's
|
||||
* parmsComputer object.
|
||||
*
|
||||
* url: the location of the machine XML file
|
||||
|
|
@ -109,9 +109,9 @@ if (NODE) {
|
|||
* function (if it has one--it's optional). We call the CPU's powerUp() function last,
|
||||
* so that the CPU is assured that all other components are ready and "powered".
|
||||
*/
|
||||
function Computer(parmsComputer, parmsMachine, fSuspended) {
|
||||
function Computer8080(parmsComputer, parmsMachine, fSuspended) {
|
||||
|
||||
Component.call(this, "Computer", parmsComputer, Computer, Messages.COMPUTER);
|
||||
Component.call(this, "Computer", parmsComputer, Computer8080, Messages8080.COMPUTER);
|
||||
|
||||
this.flags.fPowered = false;
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
*/
|
||||
this.nBusWidth = parmsComputer['busWidth'] || parmsComputer['buswidth'];
|
||||
|
||||
this.resume = Computer.RESUME_NONE;
|
||||
this.resume = Computer8080.RESUME_NONE;
|
||||
this.sStateData = null;
|
||||
this.fStateData = false; // remembers if sStateData was loaded
|
||||
this.fServerState = false;
|
||||
|
|
@ -151,12 +151,12 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
* where we know getComponentByType() will only return an CPUState object or null), wrap the expression
|
||||
* in parentheses. I never knew this until I stumbled across it in "Closure: The Definitive Guide".
|
||||
*/
|
||||
this.cpu = /** @type {CPUState} */ (Component.getComponentByType("CPU", this.id));
|
||||
this.cpu = /** @type {CPUState8080} */ (Component.getComponentByType("CPU", this.id));
|
||||
if (!this.cpu) {
|
||||
Component.error("Unable to find CPU component");
|
||||
return;
|
||||
}
|
||||
this.dbg = /** @type {Debugger} */ (Component.getComponentByType("Debugger", this.id));
|
||||
this.dbg = /** @type {Debugger8080} */ (Component.getComponentByType("Debugger", this.id));
|
||||
|
||||
/*
|
||||
* Enumerate all Video components for future updateVideo() calls.
|
||||
|
|
@ -169,14 +169,14 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
/*
|
||||
* Initialize the Bus component
|
||||
*/
|
||||
this.bus = new Bus({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);
|
||||
this.bus = new Bus8080({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);
|
||||
|
||||
/*
|
||||
* Iterate through all the components and connect them to the Control Panel, if any
|
||||
*/
|
||||
var iComponent, component;
|
||||
var aComponents = Component.getComponents(this.id);
|
||||
this.panel = /** @type {Panel} */ (Component.getComponentByType("Panel", this.id));
|
||||
this.panel = /** @type {Panel8080} */ (Component.getComponentByType("Panel", this.id));
|
||||
|
||||
if (this.panel && this.panel.controlPrint) {
|
||||
for (iComponent = 0; iComponent < aComponents.length; iComponent++) {
|
||||
|
|
@ -240,7 +240,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
sStatePath = this.sStatePath = sState;
|
||||
if (!fAllowResume) {
|
||||
this.fServerState = true;
|
||||
this.resume = Computer.RESUME_NONE;
|
||||
this.resume = Computer8080.RESUME_NONE;
|
||||
}
|
||||
if (this.resume) {
|
||||
this.stateComputer = new State(this, PC8080.APPVERSION);
|
||||
|
|
@ -278,33 +278,33 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);
|
||||
}
|
||||
|
||||
Component.subclass(Computer);
|
||||
Component.subclass(Computer8080);
|
||||
|
||||
Computer.STATE_FAILSAFE = "failsafe";
|
||||
Computer.STATE_VALIDATE = "validate";
|
||||
Computer.STATE_TIMESTAMP = "timestamp";
|
||||
Computer.STATE_VERSION = "version";
|
||||
Computer.STATE_HOSTURL = "url";
|
||||
Computer.STATE_BROWSER = "browser";
|
||||
Computer.STATE_USERID = "user";
|
||||
Computer8080.STATE_FAILSAFE = "failsafe";
|
||||
Computer8080.STATE_VALIDATE = "validate";
|
||||
Computer8080.STATE_TIMESTAMP = "timestamp";
|
||||
Computer8080.STATE_VERSION = "version";
|
||||
Computer8080.STATE_HOSTURL = "url";
|
||||
Computer8080.STATE_BROWSER = "browser";
|
||||
Computer8080.STATE_USERID = "user";
|
||||
|
||||
/*
|
||||
* The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for
|
||||
* internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states
|
||||
* whenever a resume is declined). As a result, the only "end-user" values are 0, 1 and 2.
|
||||
*/
|
||||
Computer.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)
|
||||
Computer.RESUME_NONE = 0; // default (no resume)
|
||||
Computer.RESUME_AUTO = 1; // automatically save/restore state
|
||||
Computer.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)
|
||||
Computer.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)
|
||||
Computer8080.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)
|
||||
Computer8080.RESUME_NONE = 0; // default (no resume)
|
||||
Computer8080.RESUME_AUTO = 1; // automatically save/restore state
|
||||
Computer8080.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)
|
||||
Computer8080.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)
|
||||
|
||||
/**
|
||||
* getMachineID()
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
Computer.prototype.getMachineID = function()
|
||||
Computer8080.prototype.getMachineID = function()
|
||||
{
|
||||
return this.sMachineID;
|
||||
};
|
||||
|
|
@ -316,7 +316,7 @@ Computer.prototype.getMachineID = function()
|
|||
*
|
||||
* @param {Object} [parmsMachine]
|
||||
*/
|
||||
Computer.prototype.setMachineParms = function(parmsMachine)
|
||||
Computer8080.prototype.setMachineParms = function(parmsMachine)
|
||||
{
|
||||
if (!parmsMachine) {
|
||||
var sParms;
|
||||
|
|
@ -345,7 +345,7 @@ Computer.prototype.setMachineParms = function(parmsMachine)
|
|||
* @param {Object} [parmsComponent]
|
||||
* @return {string|undefined}
|
||||
*/
|
||||
Computer.prototype.getMachineParm = function(sParm, parmsComponent)
|
||||
Computer8080.prototype.getMachineParm = function(sParm, parmsComponent)
|
||||
{
|
||||
/*
|
||||
* When checking parmsURL, the check is allowed be a bit looser, because URL parameters are
|
||||
|
|
@ -373,7 +373,7 @@ Computer.prototype.getMachineParm = function(sParm, parmsComponent)
|
|||
*
|
||||
* @return {string|null}
|
||||
*/
|
||||
Computer.prototype.saveMachineParms = function()
|
||||
Computer8080.prototype.saveMachineParms = function()
|
||||
{
|
||||
return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;
|
||||
};
|
||||
|
|
@ -383,7 +383,7 @@ Computer.prototype.saveMachineParms = function()
|
|||
*
|
||||
* @return {string}
|
||||
*/
|
||||
Computer.prototype.getUserID = function()
|
||||
Computer8080.prototype.getUserID = function()
|
||||
{
|
||||
return this.sUserID || "";
|
||||
};
|
||||
|
|
@ -391,12 +391,12 @@ Computer.prototype.getUserID = function()
|
|||
/**
|
||||
* doneLoad(sURL, sStateData, nErrorCode)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {string} sURL
|
||||
* @param {string} sStateData
|
||||
* @param {number} nErrorCode
|
||||
*/
|
||||
Computer.prototype.doneLoad = function(sURL, sStateData, nErrorCode)
|
||||
Computer8080.prototype.doneLoad = function(sURL, sStateData, nErrorCode)
|
||||
{
|
||||
if (!nErrorCode) {
|
||||
this.sStateData = sStateData;
|
||||
|
|
@ -426,11 +426,11 @@ Computer.prototype.doneLoad = function(sURL, sStateData, nErrorCode)
|
|||
*
|
||||
* param {function(this:Computer, (number|Array|undefined)): undefined} fn
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {function(...)} fn
|
||||
* @param {number|Array} [parms] optional parameters
|
||||
*/
|
||||
Computer.prototype.wait = function(fn, parms)
|
||||
Computer8080.prototype.wait = function(fn, parms)
|
||||
{
|
||||
var computer = this;
|
||||
var aComponents = Component.getComponents(this.id);
|
||||
|
|
@ -443,7 +443,7 @@ Computer.prototype.wait = function(fn, parms)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) this.printMessage("Computer.wait(ready)");
|
||||
if (DEBUG && this.messageEnabled()) this.printMessage("Computer8080.wait(ready)");
|
||||
fn.call(this, parms);
|
||||
};
|
||||
|
||||
|
|
@ -452,17 +452,17 @@ Computer.prototype.wait = function(fn, parms)
|
|||
*
|
||||
* NOTE: We clear() stateValidate only when there's no stateComputer.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {State|null} [stateComputer]
|
||||
* @return {boolean} true if state passes validation, false if not
|
||||
*/
|
||||
Computer.prototype.validateState = function(stateComputer)
|
||||
Computer8080.prototype.validateState = function(stateComputer)
|
||||
{
|
||||
var fValid = true;
|
||||
var stateValidate = new State(this, PC8080.APPVERSION, Computer.STATE_VALIDATE);
|
||||
var stateValidate = new State(this, PC8080.APPVERSION, Computer8080.STATE_VALIDATE);
|
||||
if (stateValidate.load() && stateValidate.parse()) {
|
||||
var sTimestampValidate = stateValidate.get(Computer.STATE_TIMESTAMP);
|
||||
var sTimestampComputer = stateComputer ? stateComputer.get(Computer.STATE_TIMESTAMP) : "unknown";
|
||||
var sTimestampValidate = stateValidate.get(Computer8080.STATE_TIMESTAMP);
|
||||
var sTimestampComputer = stateComputer? stateComputer.get(Computer8080.STATE_TIMESTAMP) : "unknown";
|
||||
if (sTimestampValidate != sTimestampComputer) {
|
||||
this.notice("Machine state may be out-of-date\n(" + sTimestampValidate + " vs. " + sTimestampComputer + ")\nCheck your browser's local storage limits");
|
||||
fValid = false;
|
||||
|
|
@ -481,17 +481,17 @@ Computer.prototype.validateState = function(stateComputer)
|
|||
*
|
||||
* Power every component "up", applying any previously available state information.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {number} [resume] is a valid RESUME value; default is this.resume
|
||||
*/
|
||||
Computer.prototype.powerOn = function(resume)
|
||||
Computer8080.prototype.powerOn = function(resume)
|
||||
{
|
||||
if (resume === undefined) {
|
||||
resume = this.resume || (this.sStateData? Computer.RESUME_AUTO : Computer.RESUME_NONE);
|
||||
resume = this.resume || (this.sStateData? Computer8080.RESUME_AUTO : Computer8080.RESUME_NONE);
|
||||
}
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage("Computer.powerOn(" + (resume == Computer.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")");
|
||||
this.printMessage("Computer8080.powerOn(" + (resume == Computer8080.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")");
|
||||
}
|
||||
|
||||
if (this.nPowerChange) {
|
||||
|
|
@ -504,10 +504,10 @@ Computer.prototype.powerOn = function(resume)
|
|||
this.fRestoreError = false;
|
||||
var stateComputer = this.stateComputer || new State(this, PC8080.APPVERSION);
|
||||
|
||||
if (resume == Computer.RESUME_REPOWER) {
|
||||
if (resume == Computer8080.RESUME_REPOWER) {
|
||||
fRepower = true;
|
||||
}
|
||||
else if (resume > Computer.RESUME_NONE) {
|
||||
else if (resume > Computer8080.RESUME_NONE) {
|
||||
if (stateComputer.load(this.sStateData)) {
|
||||
/*
|
||||
* Since we're resuming something (either a predefined state or a state from localStorage), let's
|
||||
|
|
@ -515,7 +515,7 @@ Computer.prototype.powerOn = function(resume)
|
|||
* Which means, of course, that if a previous "failsafe" checkpoint already exists, something bad
|
||||
* may have happened the last time around.
|
||||
*/
|
||||
this.stateFailSafe = new State(this, PC8080.APPVERSION, Computer.STATE_FAILSAFE);
|
||||
this.stateFailSafe = new State(this, PC8080.APPVERSION, Computer8080.STATE_FAILSAFE);
|
||||
if (this.stateFailSafe.load()) {
|
||||
this.powerReport(stateComputer);
|
||||
/*
|
||||
|
|
@ -523,7 +523,7 @@ Computer.prototype.powerOn = function(resume)
|
|||
* all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to
|
||||
* restore, the state will be removed.
|
||||
*/
|
||||
resume = Computer.RESUME_PROMPT;
|
||||
resume = Computer8080.RESUME_PROMPT;
|
||||
/*
|
||||
* To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail
|
||||
* with a "read only" error (eg, "TypeError: Cannot assign to read only property 'timestamp'").
|
||||
|
|
@ -531,11 +531,11 @@ Computer.prototype.powerOn = function(resume)
|
|||
this.stateFailSafe.unload();
|
||||
}
|
||||
|
||||
this.stateFailSafe.set(Computer.STATE_TIMESTAMP, usr.getTimestamp());
|
||||
this.stateFailSafe.set(Computer8080.STATE_TIMESTAMP, usr.getTimestamp());
|
||||
this.stateFailSafe.store();
|
||||
|
||||
var fValidate = this.resume && !this.fServerState;
|
||||
if (resume == Computer.RESUME_AUTO || web.confirmUser("Click OK to restore the previous " + PC8080.APPNAME + " machine state, or CANCEL to reset the machine.")) {
|
||||
if (resume == Computer8080.RESUME_AUTO || web.confirmUser("Click OK to restore the previous " + PC8080.APPNAME + " machine state, or CANCEL to reset the machine.")) {
|
||||
fRestore = stateComputer.parse();
|
||||
if (fRestore) {
|
||||
var sCode = stateComputer.get(UserAPI.RES.CODE);
|
||||
|
|
@ -578,7 +578,7 @@ Computer.prototype.powerOn = function(resume)
|
|||
/*
|
||||
* RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.
|
||||
*/
|
||||
if (resume == Computer.RESUME_PROMPT) stateComputer.clear();
|
||||
if (resume == Computer8080.RESUME_PROMPT) stateComputer.clear();
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -610,7 +610,7 @@ Computer.prototype.powerOn = function(resume)
|
|||
*/
|
||||
var aParms = [stateComputer, resume, fRestore];
|
||||
|
||||
if (resume != Computer.RESUME_REPOWER) {
|
||||
if (resume != Computer8080.RESUME_REPOWER) {
|
||||
this.wait(this.donePowerOn, aParms);
|
||||
return;
|
||||
}
|
||||
|
|
@ -620,14 +620,14 @@ Computer.prototype.powerOn = function(resume)
|
|||
/**
|
||||
* powerRestore(component, stateComputer, fRepower, fRestore)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {Component} component
|
||||
* @param {State} stateComputer
|
||||
* @param {boolean} fRepower
|
||||
* @param {boolean} fRestore
|
||||
* @return {boolean} true if restore should continue, false if not
|
||||
*/
|
||||
Computer.prototype.powerRestore = function(component, stateComputer, fRepower, fRestore)
|
||||
Computer8080.prototype.powerRestore = function(component, stateComputer, fRepower, fRestore)
|
||||
{
|
||||
if (!component.flags.fPowered) {
|
||||
|
||||
|
|
@ -685,7 +685,7 @@ Computer.prototype.powerRestore = function(component, stateComputer, fRepower, f
|
|||
*/
|
||||
if (this.sStatePath && !this.fStateData) {
|
||||
stateComputer.clear();
|
||||
this.resume = Computer.RESUME_NONE;
|
||||
this.resume = Computer8080.RESUME_NONE;
|
||||
web.reloadPage();
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -725,17 +725,17 @@ Computer.prototype.powerRestore = function(component, stateComputer, fRepower, f
|
|||
*
|
||||
* This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {Array} aParms containing [stateComputer, resume, fRestore]
|
||||
*/
|
||||
Computer.prototype.donePowerOn = function(aParms)
|
||||
Computer8080.prototype.donePowerOn = function(aParms)
|
||||
{
|
||||
var stateComputer = aParms[0];
|
||||
var fRepower = (aParms[1] < 0);
|
||||
var fRestore = aParms[2];
|
||||
|
||||
if (DEBUG && this.flags.fPowered && this.messageEnabled()) {
|
||||
this.printMessage("Computer.donePowerOn(): redundant");
|
||||
this.printMessage("Computer8080.donePowerOn(): redundant");
|
||||
}
|
||||
|
||||
this.fInitialized = true;
|
||||
|
|
@ -775,10 +775,10 @@ Computer.prototype.donePowerOn = function(aParms)
|
|||
/**
|
||||
* checkPower()
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @return {boolean} true if the computer is fully powered, false otherwise
|
||||
*/
|
||||
Computer.prototype.checkPower = function()
|
||||
Computer8080.prototype.checkPower = function()
|
||||
{
|
||||
if (this.flags.fPowered) return true;
|
||||
|
||||
|
|
@ -803,10 +803,10 @@ Computer.prototype.checkPower = function()
|
|||
/**
|
||||
* powerReport(stateComputer)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {State} stateComputer
|
||||
*/
|
||||
Computer.prototype.powerReport = function(stateComputer)
|
||||
Computer8080.prototype.powerReport = function(stateComputer)
|
||||
{
|
||||
if (web.confirmUser("There may be a problem with your " + PC8080.APPNAME + " machine.\n\nTo help us diagnose it, click OK to send this " + PC8080.APPNAME + " machine state to http://" + SITEHOST + ".")) {
|
||||
web.sendReport(PC8080.APPNAME, PC8080.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());
|
||||
|
|
@ -839,18 +839,18 @@ Computer.prototype.powerReport = function(stateComputer)
|
|||
* As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,
|
||||
* which doesn't seem like a huge problem.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {boolean} [fSave] is true to request a saved state
|
||||
* @param {boolean} [fShutdown] is true if the machine is being shut down
|
||||
* @return {string|null} string representing the saved state (or null if error)
|
||||
*/
|
||||
Computer.prototype.powerOff = function(fSave, fShutdown)
|
||||
Computer8080.prototype.powerOff = function(fSave, fShutdown)
|
||||
{
|
||||
var data;
|
||||
var sState = "none";
|
||||
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage("Computer.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")");
|
||||
this.printMessage("Computer8080.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")");
|
||||
}
|
||||
|
||||
if (this.nPowerChange) {
|
||||
|
|
@ -859,14 +859,14 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
|
|||
this.nPowerChange--;
|
||||
|
||||
var stateComputer = new State(this, PC8080.APPVERSION);
|
||||
var stateValidate = new State(this, PC8080.APPVERSION, Computer.STATE_VALIDATE);
|
||||
var stateValidate = new State(this, PC8080.APPVERSION, Computer8080.STATE_VALIDATE);
|
||||
|
||||
var sTimestamp = usr.getTimestamp();
|
||||
stateValidate.set(Computer.STATE_TIMESTAMP, sTimestamp);
|
||||
stateComputer.set(Computer.STATE_TIMESTAMP, sTimestamp);
|
||||
stateComputer.set(Computer.STATE_VERSION, APPVERSION);
|
||||
stateComputer.set(Computer.STATE_HOSTURL, web.getHostURL());
|
||||
stateComputer.set(Computer.STATE_BROWSER, web.getUserAgent());
|
||||
stateValidate.set(Computer8080.STATE_TIMESTAMP, sTimestamp);
|
||||
stateComputer.set(Computer8080.STATE_TIMESTAMP, sTimestamp);
|
||||
stateComputer.set(Computer8080.STATE_VERSION, APPVERSION);
|
||||
stateComputer.set(Computer8080.STATE_HOSTURL, web.getHostURL());
|
||||
stateComputer.set(Computer8080.STATE_BROWSER, web.getUserAgent());
|
||||
|
||||
/*
|
||||
* Always power the CPU "down" first, just to help insure it doesn't ask other components to do anything
|
||||
|
|
@ -932,7 +932,7 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
|
|||
*/
|
||||
if (this.resume) {
|
||||
fClear = true;
|
||||
fClearAll = (this.resume == Computer.RESUME_DELETE);
|
||||
fClearAll = (this.resume == Computer8080.RESUME_DELETE);
|
||||
}
|
||||
}
|
||||
if (fClear) {
|
||||
|
|
@ -963,9 +963,9 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
|
|||
* allocated the Bus object ourselves, after all the other components were allocated, it ends
|
||||
* up near the end of Component's list of components. Hence the special case for this.bus below.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
*/
|
||||
Computer.prototype.reset = function()
|
||||
Computer8080.prototype.reset = function()
|
||||
{
|
||||
if (this.bus && this.bus.reset) {
|
||||
/*
|
||||
|
|
@ -993,11 +993,11 @@ Computer.prototype.reset = function()
|
|||
* Note that we're called by runCPU(), which is why we exclude the CPU component,
|
||||
* as well as ourselves.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {number} ms
|
||||
* @param {number} nCycles
|
||||
*/
|
||||
Computer.prototype.start = function(ms, nCycles)
|
||||
Computer8080.prototype.start = function(ms, nCycles)
|
||||
{
|
||||
var aComponents = Component.getComponents(this.id);
|
||||
for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {
|
||||
|
|
@ -1017,11 +1017,11 @@ Computer.prototype.start = function(ms, nCycles)
|
|||
* Note that we're called by runCPU(), which is why we exclude the CPU component,
|
||||
* as well as ourselves.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {number} ms
|
||||
* @param {number} nCycles
|
||||
*/
|
||||
Computer.prototype.stop = function(ms, nCycles)
|
||||
Computer8080.prototype.stop = function(ms, nCycles)
|
||||
{
|
||||
var aComponents = Component.getComponents(this.id);
|
||||
for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {
|
||||
|
|
@ -1036,14 +1036,14 @@ Computer.prototype.stop = function(ms, nCycles)
|
|||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
Computer.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
Computer8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
var computer = this;
|
||||
|
||||
|
|
@ -1130,9 +1130,9 @@ Computer.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
/**
|
||||
* resetUserID()
|
||||
*/
|
||||
Computer.prototype.resetUserID = function()
|
||||
Computer8080.prototype.resetUserID = function()
|
||||
{
|
||||
web.setLocalStorageItem(Computer.STATE_USERID, "");
|
||||
web.setLocalStorageItem(Computer8080.STATE_USERID, "");
|
||||
this.sUserID = null;
|
||||
};
|
||||
|
||||
|
|
@ -1142,11 +1142,11 @@ Computer.prototype.resetUserID = function()
|
|||
* @param {boolean} [fPrompt]
|
||||
* @returns {string|null|undefined}
|
||||
*/
|
||||
Computer.prototype.queryUserID = function(fPrompt)
|
||||
Computer8080.prototype.queryUserID = function(fPrompt)
|
||||
{
|
||||
var sUserID = this.sUserID;
|
||||
if (!sUserID) {
|
||||
sUserID = web.getLocalStorageItem(Computer.STATE_USERID);
|
||||
sUserID = web.getLocalStorageItem(Computer8080.STATE_USERID);
|
||||
if (sUserID !== undefined) {
|
||||
if (!sUserID && fPrompt) {
|
||||
/*
|
||||
|
|
@ -1170,11 +1170,11 @@ Computer.prototype.queryUserID = function(fPrompt)
|
|||
/**
|
||||
* verifyUserID(sUserID)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {string} sUserID
|
||||
* @return {string} validated user ID, or null if error
|
||||
*/
|
||||
Computer.prototype.verifyUserID = function(sUserID)
|
||||
Computer8080.prototype.verifyUserID = function(sUserID)
|
||||
{
|
||||
this.sUserID = null;
|
||||
var fMessages = DEBUG && this.messageEnabled();
|
||||
|
|
@ -1187,8 +1187,8 @@ Computer.prototype.verifyUserID = function(sUserID)
|
|||
try {
|
||||
response = eval("(" + sResponse + ")");
|
||||
if (response.code && response.code == UserAPI.CODE.OK) {
|
||||
web.setLocalStorageItem(Computer.STATE_USERID, response.data);
|
||||
if (fMessages) this.printMessage(Computer.STATE_USERID + " updated: " + response.data);
|
||||
web.setLocalStorageItem(Computer8080.STATE_USERID, response.data);
|
||||
if (fMessages) this.printMessage(Computer8080.STATE_USERID + " updated: " + response.data);
|
||||
this.sUserID = response.data;
|
||||
} else {
|
||||
if (fMessages) this.printMessage(response.code + ": " + response.data);
|
||||
|
|
@ -1205,20 +1205,20 @@ Computer.prototype.verifyUserID = function(sUserID)
|
|||
/**
|
||||
* getServerStatePath()
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)
|
||||
*/
|
||||
Computer.prototype.getServerStatePath = function()
|
||||
Computer8080.prototype.getServerStatePath = function()
|
||||
{
|
||||
var sStatePath = null;
|
||||
if (this.sUserID) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(Computer.STATE_USERID + " for load: " + this.sUserID);
|
||||
this.printMessage(Computer8080.STATE_USERID + " for load: " + this.sUserID);
|
||||
}
|
||||
sStatePath = web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PC8080.APPVERSION);
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(Computer.STATE_USERID + " unavailable");
|
||||
this.printMessage(Computer8080.STATE_USERID + " unavailable");
|
||||
}
|
||||
}
|
||||
return sStatePath;
|
||||
|
|
@ -1230,7 +1230,7 @@ Computer.prototype.getServerStatePath = function()
|
|||
* @param {string} sUserID
|
||||
* @param {string|null} sState
|
||||
*/
|
||||
Computer.prototype.saveServerState = function(sUserID, sState)
|
||||
Computer8080.prototype.saveServerState = function(sUserID, sState)
|
||||
{
|
||||
/*
|
||||
* We must pass fSync == true, because (as I understand it) browsers will blow off any async
|
||||
|
|
@ -1265,16 +1265,16 @@ Computer.prototype.saveServerState = function(sUserID, sState)
|
|||
/**
|
||||
* storeServerState(sUserID, sState, fSync)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {string} sUserID
|
||||
* @param {string} sState
|
||||
* @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)
|
||||
* @return {*} server response if fSync is true and a response was received; otherwise null
|
||||
*/
|
||||
Computer.prototype.storeServerState = function(sUserID, sState, fSync)
|
||||
Computer8080.prototype.storeServerState = function(sUserID, sState, fSync)
|
||||
{
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage(Computer.STATE_USERID + " for store: " + sUserID);
|
||||
this.printMessage(Computer8080.STATE_USERID + " for store: " + sUserID);
|
||||
}
|
||||
/*
|
||||
* TODO: Determine whether or not any browsers cancel our request if we're called during a browser "shutdown" event,
|
||||
|
|
@ -1310,9 +1310,9 @@ Computer.prototype.storeServerState = function(sUserID, sState, fSync)
|
|||
*
|
||||
* This handles UI requests to toggle the computer's power (eg, see the "power" button binding).
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
*/
|
||||
Computer.prototype.onPower = function()
|
||||
Computer8080.prototype.onPower = function()
|
||||
{
|
||||
if (!this.nPowerChange) {
|
||||
if (!this.flags.fPowered) {
|
||||
|
|
@ -1328,9 +1328,9 @@ Computer.prototype.onPower = function()
|
|||
*
|
||||
* This handles UI requests to reset the computer's state (eg, see the "reset" button binding).
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
*/
|
||||
Computer.prototype.onReset = function()
|
||||
Computer8080.prototype.onReset = function()
|
||||
{
|
||||
/*
|
||||
* I'm going to start with the presumption that it makes little sense for an "unpowered" computer to be "reset";
|
||||
|
|
@ -1349,10 +1349,10 @@ Computer.prototype.onReset = function()
|
|||
*/
|
||||
if (this.resume && !this.sResumePath) {
|
||||
/*
|
||||
* I used to bypass the prompt if this.resume == Computer.RESUME_AUTO, setting fSave to true automatically,
|
||||
* I used to bypass the prompt if this.resume == Computer8080.RESUME_AUTO, setting fSave to true automatically,
|
||||
* but that gives the user no means of resetting a resumable machine that contains errors in its resume state.
|
||||
*/
|
||||
var fSave = (/* this.resume == Computer.RESUME_AUTO || */ web.confirmUser("Click OK to save changes to this " + PC8080.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded."));
|
||||
var fSave = (/* this.resume == Computer8080.RESUME_AUTO || */ web.confirmUser("Click OK to save changes to this " + PC8080.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded."));
|
||||
this.powerOff(fSave, true);
|
||||
/*
|
||||
* Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()
|
||||
|
|
@ -1371,7 +1371,7 @@ Computer.prototype.onReset = function()
|
|||
return;
|
||||
}
|
||||
if (!fSave) this.fReload = true;
|
||||
this.powerOn(Computer.RESUME_NONE);
|
||||
this.powerOn(Computer8080.RESUME_NONE);
|
||||
this.fReload = false;
|
||||
} else {
|
||||
this.reset();
|
||||
|
|
@ -1382,13 +1382,14 @@ Computer.prototype.onReset = function()
|
|||
/**
|
||||
* getMachineComponent(sType, componentPrev)
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {string} sType
|
||||
* @param {Component|null} [componentPrev] of previously returned component, if any
|
||||
* @return {Component|null}
|
||||
*/
|
||||
Computer.prototype.getMachineComponent = function(sType, componentPrev)
|
||||
Computer8080.prototype.getMachineComponent = function(sType, componentPrev)
|
||||
{
|
||||
var componentLast = componentPrev;
|
||||
var aComponents = Component.getComponents(this.id);
|
||||
for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {
|
||||
var component = aComponents[iComponent];
|
||||
|
|
@ -1398,6 +1399,7 @@ Computer.prototype.getMachineComponent = function(sType, componentPrev)
|
|||
}
|
||||
if (component.type == sType) return component;
|
||||
}
|
||||
if (!componentLast) Component.log("Machine component type '" + sType + "' not found", "warning");
|
||||
return null;
|
||||
};
|
||||
|
||||
|
|
@ -1407,10 +1409,10 @@ Computer.prototype.getMachineComponent = function(sType, componentPrev)
|
|||
* NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),
|
||||
* the scroll feature has annoying effect on iOS, so we no longer do it by default (fScroll must be true).
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {boolean} [fScroll]
|
||||
*/
|
||||
Computer.prototype.updateFocus = function(fScroll)
|
||||
Computer8080.prototype.updateFocus = function(fScroll)
|
||||
{
|
||||
if (this.aVideo.length) {
|
||||
/*
|
||||
|
|
@ -1450,10 +1452,10 @@ Computer.prototype.updateFocus = function(fScroll)
|
|||
* knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,
|
||||
* but Panel is an optional component; generally, only machines that include Debugger also include Panel.
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {boolean} [fForce] (true will display registers even if the CPU is running and "live" registers are not enabled)
|
||||
*/
|
||||
Computer.prototype.updateStatus = function(fForce)
|
||||
Computer8080.prototype.updateStatus = function(fForce)
|
||||
{
|
||||
/*
|
||||
* fForce is generally set to true whenever the CPU is transitioning to/from a running state, in which case
|
||||
|
|
@ -1473,10 +1475,10 @@ Computer.prototype.updateStatus = function(fForce)
|
|||
*
|
||||
* Any high-frequency updates should be performed here (avoid updating DOM elements).
|
||||
*
|
||||
* @this {Computer}
|
||||
* @this {Computer8080}
|
||||
* @param {number} n (where 0 <= n < VIDEO_UPDATES_PER_SECOND for a normal update, or -1 for a forced update)
|
||||
*/
|
||||
Computer.prototype.updateVideo = function(n)
|
||||
Computer8080.prototype.updateVideo = function(n)
|
||||
{
|
||||
for (var i = 0; i < this.aVideo.length; i++) {
|
||||
this.aVideo[i].updateScreen(n);
|
||||
|
|
@ -1484,14 +1486,14 @@ Computer.prototype.updateVideo = function(n)
|
|||
};
|
||||
|
||||
/**
|
||||
* Computer.init()
|
||||
* Computer8080.init()
|
||||
*
|
||||
* For every machine represented by an HTML element of class "pcjs-machine", this function
|
||||
* locates the HTML element of class "computer", extracting the JSON-encoded parameters for the
|
||||
* Computer constructor from the element's "data-value" attribute, invoking the constructor to
|
||||
* create a Computer component, and then binding any associated HTML controls to the new component.
|
||||
*/
|
||||
Computer.init = function()
|
||||
Computer8080.init = function()
|
||||
{
|
||||
/*
|
||||
* In non-COMPILED builds, embedMachine() may have set XMLVERSION.
|
||||
|
|
@ -1516,7 +1518,7 @@ Computer.init = function()
|
|||
* We set fSuspended in the Computer constructor because we want to "power up" the
|
||||
* computer ourselves, after any/all bindings are in place.
|
||||
*/
|
||||
var computer = new Computer(parmsComputer, parmsMachine, true);
|
||||
var computer = new Computer8080(parmsComputer, parmsMachine, true);
|
||||
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
computer.printMessage("onInit(" + computer.flags.fPowered + ")");
|
||||
|
|
@ -1538,7 +1540,7 @@ Computer.init = function()
|
|||
};
|
||||
|
||||
/**
|
||||
* Computer.show()
|
||||
* Computer8080.show()
|
||||
*
|
||||
* When exit() is using an "onbeforeunload" handler, this "onpageshow" handler allows us to repower everything,
|
||||
* without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the
|
||||
|
|
@ -1546,13 +1548,13 @@ Computer.init = function()
|
|||
* should be very quick, essentially just marking all components as powered again (so that, for example, the Video
|
||||
* component will start drawing again) and firing the CPU up again.
|
||||
*/
|
||||
Computer.show = function()
|
||||
Computer8080.show = function()
|
||||
{
|
||||
var aeComputers = Component.getElementsByClass(document, PC8080.APPCLASS, "computer");
|
||||
for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {
|
||||
var eComputer = aeComputers[iComputer];
|
||||
var parmsComputer = Component.getComponentParms(eComputer);
|
||||
var computer = /** @type {Computer} */ (Component.getComponentByType("Computer", parmsComputer['id']));
|
||||
var computer = /** @type {Computer8080} */ (Component.getComponentByType("Computer", parmsComputer['id']));
|
||||
if (computer) {
|
||||
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
|
|
@ -1563,14 +1565,14 @@ Computer.show = function()
|
|||
/**
|
||||
* Repower the computer, notifying every component to continue running as-is.
|
||||
*/
|
||||
computer.powerOn(Computer.RESUME_REPOWER);
|
||||
computer.powerOn(Computer8080.RESUME_REPOWER);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Computer.exit()
|
||||
* Computer8080.exit()
|
||||
*
|
||||
* The Computer is currently the only component that uses an "exit" handler, which web.onExit() defines as
|
||||
* either an "unload" or "onbeforeunload" handler. This gives us the opportunity to save the machine state,
|
||||
|
|
@ -1586,7 +1588,7 @@ Computer.show = function()
|
|||
* presence of an "onunload" handler generally causes a browser to throw the page away once the handler returns.
|
||||
*
|
||||
* However, in order to safely use "onbeforeunload", we must add yet another handler ("onpageshow") to repower
|
||||
* everything, without either resetting or restoring. Hence, the Computer.show() function, which calls powerOn()
|
||||
* everything, without either resetting or restoring. Hence, the Computer8080.show() function, which calls powerOn()
|
||||
* with a special resume value (RESUME_REPOWER) if the computer is already marked as "ready", meaning the browser
|
||||
* didn't change anything. This "repower" process should be very quick, essentially just marking all components as
|
||||
* powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.
|
||||
|
|
@ -1595,13 +1597,13 @@ Computer.show = function()
|
|||
* "unload" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and
|
||||
* localStorage means the simulation should be restored and become operational almost immediately.
|
||||
*/
|
||||
Computer.exit = function()
|
||||
Computer8080.exit = function()
|
||||
{
|
||||
var aeComputers = Component.getElementsByClass(document, PC8080.APPCLASS, "computer");
|
||||
for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {
|
||||
var eComputer = aeComputers[iComputer];
|
||||
var parmsComputer = Component.getComponentParms(eComputer);
|
||||
var computer = /** @type {Computer} */ (Component.getComponentByType("Computer", parmsComputer['id']));
|
||||
var computer = /** @type {Computer8080} */ (Component.getComponentByType("Computer", parmsComputer['id']));
|
||||
if (computer) {
|
||||
|
||||
if (DEBUG && computer.messageEnabled()) {
|
||||
|
|
@ -1623,8 +1625,8 @@ Computer.exit = function()
|
|||
/*
|
||||
* Initialize every Computer on the page.
|
||||
*/
|
||||
web.onInit(Computer.init);
|
||||
web.onShow(Computer.show);
|
||||
web.onExit(Computer.exit);
|
||||
web.onInit(Computer8080.init);
|
||||
web.onShow(Computer8080.show);
|
||||
web.onExit(Computer8080.exit);
|
||||
|
||||
if (NODE) module.exports = Computer;
|
||||
if (NODE) module.exports = Computer8080;
|
||||
|
|
|
|||
|
|
@ -35,15 +35,15 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var usr = require("../../shared/lib/usrlib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
var Messages8080= require("./messages");
|
||||
}
|
||||
|
||||
/**
|
||||
* CPU(parmsCPU, nCyclesDefault)
|
||||
* CPU8080(parmsCPU, nCyclesDefault)
|
||||
*
|
||||
* The CPU class supports the following (parmsCPU) properties:
|
||||
* The CPU8080 class supports the following (parmsCPU) properties:
|
||||
*
|
||||
* cycles: the machine's base cycles per second; the CPUState constructor will
|
||||
* cycles: the machine's base cycles per second; the CPUState8080 constructor will
|
||||
* provide us with a default (based on the CPU model) to use as a fallback.
|
||||
*
|
||||
* multiplier: base cycle multiplier; default is 1.
|
||||
|
|
@ -64,16 +64,16 @@ if (NODE) {
|
|||
* This component is primarily responsible for interfacing the CPU with the outside
|
||||
* world (eg, Panel and Debugger components), and managing overall CPU operation.
|
||||
*
|
||||
* It is extended by the CPUState component, where the simulation control logic resides.
|
||||
* It is extended by the CPUState8080 component, where the simulation control logic resides.
|
||||
*
|
||||
* @constructor
|
||||
* @extends Component
|
||||
* @param {Object} parmsCPU
|
||||
* @param {number} nCyclesDefault
|
||||
*/
|
||||
function CPU(parmsCPU, nCyclesDefault)
|
||||
function CPU8080(parmsCPU, nCyclesDefault)
|
||||
{
|
||||
Component.call(this, "CPU", parmsCPU, CPU, Messages.CPU);
|
||||
Component.call(this, "CPU", parmsCPU, CPU8080, Messages8080.CPU);
|
||||
|
||||
var nCycles = parmsCPU['cycles'] || nCyclesDefault;
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ function CPU(parmsCPU, nCyclesDefault)
|
|||
this.setReady();
|
||||
}
|
||||
|
||||
Component.subclass(CPU);
|
||||
Component.subclass(CPU8080);
|
||||
|
||||
/*
|
||||
* Constants that control the frequency at which various updates should occur.
|
||||
|
|
@ -141,9 +141,9 @@ Component.subclass(CPU);
|
|||
* calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting
|
||||
* point and computes the following variables:
|
||||
*
|
||||
* this.aCounts.nCyclesPerYield (this.aCounts.nCyclesPerSecond / CPU.YIELDS_PER_SECOND)
|
||||
* this.aCounts.nCyclesPerVideoUpdate (this.aCounts.nCyclesPerSecond / CPU.VIDEO_UPDATES_PER_SECOND)
|
||||
* this.aCounts.nCyclesPerStatusUpdate (this.aCounts.nCyclesPerSecond / CPU.STATUS_UPDATES_PER_SECOND)
|
||||
* this.aCounts.nCyclesPerYield (this.aCounts.nCyclesPerSecond / CPU8080.YIELDS_PER_SECOND)
|
||||
* this.aCounts.nCyclesPerVideoUpdate (this.aCounts.nCyclesPerSecond / CPU8080.VIDEO_UPDATES_PER_SECOND)
|
||||
* this.aCounts.nCyclesPerStatusUpdate (this.aCounts.nCyclesPerSecond / CPU8080.STATUS_UPDATES_PER_SECOND)
|
||||
*
|
||||
* The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),
|
||||
* and then they're used to initialize another set of variables for each runCPU() iteration:
|
||||
|
|
@ -152,42 +152,42 @@ Component.subclass(CPU);
|
|||
* this.aCounts.nCyclesNextVideoUpdate <= this.aCounts.nCyclesPerVideoUpdate
|
||||
* this.aCounts.nCyclesNextStatusUpdate <= this.aCounts.nCyclesPerStatusUpdate
|
||||
*/
|
||||
CPU.YIELDS_PER_SECOND = 30;
|
||||
CPU.VIDEO_UPDATES_PER_SECOND = 60;
|
||||
CPU.STATUS_UPDATES_PER_SECOND = 2;
|
||||
CPU8080.YIELDS_PER_SECOND = 30;
|
||||
CPU8080.VIDEO_UPDATES_PER_SECOND = 60;
|
||||
CPU8080.STATUS_UPDATES_PER_SECOND = 2;
|
||||
|
||||
CPU.BUTTONS = ["power", "reset"];
|
||||
CPU8080.BUTTONS = ["power", "reset"];
|
||||
|
||||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPU} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {CPU8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPU8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
CPU.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
CPU8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.bus = bus;
|
||||
this.dbg = dbg;
|
||||
|
||||
for (var i = 0; i < CPU.BUTTONS.length; i++) {
|
||||
var control = this.bindings[CPU.BUTTONS[i]];
|
||||
if (control) this.cmp.setBinding(null, CPU.BUTTONS[i], control);
|
||||
for (var i = 0; i < CPU8080.BUTTONS.length; i++) {
|
||||
var control = this.bindings[CPU8080.BUTTONS[i]];
|
||||
if (control) this.cmp.setBinding(null, CPU8080.BUTTONS[i], control);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to know the refresh rate (and corresponding interrupt rate, if any) of the Video component.
|
||||
*/
|
||||
var video = /** @type {Video} */ (cmp.getMachineComponent("Video"));
|
||||
this.refreshRate = video && video.getRefreshRate() || CPU.VIDEO_UPDATES_PER_SECOND;
|
||||
var video = /** @type {Video8080} */ (cmp.getMachineComponent("Video"));
|
||||
this.refreshRate = video && video.getRefreshRate() || CPU8080.VIDEO_UPDATES_PER_SECOND;
|
||||
|
||||
/*
|
||||
* Attach the ChipSet component to the CPU so that it can be notified whenever the CPU stops and starts.
|
||||
*/
|
||||
this.chipset = /** @type {ChipSet} */ (cmp.getMachineComponent("ChipSet"));
|
||||
this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent("ChipSet"));
|
||||
|
||||
/*
|
||||
* We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.
|
||||
|
|
@ -203,9 +203,9 @@ CPU.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* reset()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
*/
|
||||
CPU.prototype.reset = function()
|
||||
CPU8080.prototype.reset = function()
|
||||
{
|
||||
this.aCounts.nVideoUpdates = 0;
|
||||
};
|
||||
|
|
@ -215,10 +215,10 @@ CPU.prototype.reset = function()
|
|||
*
|
||||
* This is a placeholder for save support (overridden by the CPUState component).
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {Object|null}
|
||||
*/
|
||||
CPU.prototype.save = function()
|
||||
CPU8080.prototype.save = function()
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
|
@ -228,11 +228,11 @@ CPU.prototype.save = function()
|
|||
*
|
||||
* This is a placeholder for restore support (overridden by the CPUState component).
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if restore successful, false if not
|
||||
*/
|
||||
CPU.prototype.restore = function(data)
|
||||
CPU8080.prototype.restore = function(data)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
|
@ -240,12 +240,12 @@ CPU.prototype.restore = function(data)
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
CPU.prototype.powerUp = function(data, fRepower)
|
||||
CPU8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) {
|
||||
if (!data || !this.restore) {
|
||||
|
|
@ -286,12 +286,12 @@ CPU.prototype.powerUp = function(data, fRepower)
|
|||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
CPU.prototype.powerDown = function(fSave, fShutdown)
|
||||
CPU8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
/*
|
||||
* The Computer component (which is responsible for all powerDown and powerUp notifications)
|
||||
|
|
@ -305,10 +305,10 @@ CPU.prototype.powerDown = function(fSave, fShutdown)
|
|||
/**
|
||||
* autoStart()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {boolean} true if started, false if not
|
||||
*/
|
||||
CPU.prototype.autoStart = function()
|
||||
CPU8080.prototype.autoStart = function()
|
||||
{
|
||||
/*
|
||||
* Start running automatically on power-up, assuming there's no Debugger and no "Run" button
|
||||
|
|
@ -327,10 +327,10 @@ CPU.prototype.autoStart = function()
|
|||
/**
|
||||
* isPowered()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {boolean}
|
||||
*/
|
||||
CPU.prototype.isPowered = function()
|
||||
CPU8080.prototype.isPowered = function()
|
||||
{
|
||||
if (!this.flags.fPowered) {
|
||||
this.println(this.toString() + " not powered");
|
||||
|
|
@ -342,10 +342,10 @@ CPU.prototype.isPowered = function()
|
|||
/**
|
||||
* isRunning()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {boolean}
|
||||
*/
|
||||
CPU.prototype.isRunning = function()
|
||||
CPU8080.prototype.isRunning = function()
|
||||
{
|
||||
return this.flags.fRunning;
|
||||
};
|
||||
|
|
@ -355,10 +355,10 @@ CPU.prototype.isRunning = function()
|
|||
*
|
||||
* This will be implemented by the CPUState component.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)
|
||||
*/
|
||||
CPU.prototype.getChecksum = function()
|
||||
CPU8080.prototype.getChecksum = function()
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
|
@ -370,10 +370,10 @@ CPU.prototype.getChecksum = function()
|
|||
* cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever
|
||||
* the CPU is reset or restored.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {boolean} true if checksum generation enabled, false if not
|
||||
*/
|
||||
CPU.prototype.resetChecksum = function()
|
||||
CPU8080.prototype.resetChecksum = function()
|
||||
{
|
||||
if (this.aCounts.nCyclesChecksumStart === undefined) this.aCounts.nCyclesChecksumStart = 0;
|
||||
if (this.aCounts.nCyclesChecksumInterval === undefined) this.aCounts.nCyclesChecksumInterval = -1;
|
||||
|
|
@ -399,10 +399,10 @@ CPU.prototype.resetChecksum = function()
|
|||
* the exact number cycles that were actually executed. This should give us instruction-granular checksums
|
||||
* at precise intervals that are 100% repeatable.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nCycles
|
||||
*/
|
||||
CPU.prototype.updateChecksum = function(nCycles)
|
||||
CPU8080.prototype.updateChecksum = function(nCycles)
|
||||
{
|
||||
if (this.flags.fChecksum) {
|
||||
/*
|
||||
|
|
@ -434,9 +434,9 @@ CPU.prototype.updateChecksum = function(nCycles)
|
|||
* checksums generated at the specified cycle intervals, as specified by the "csStart" and "csInterval" parmsCPU
|
||||
* properties).
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
*/
|
||||
CPU.prototype.displayChecksum = function()
|
||||
CPU8080.prototype.displayChecksum = function()
|
||||
{
|
||||
this.println(this.getCycles() + " cycles: " + "checksum=" + str.toHex(this.aCounts.nChecksum));
|
||||
};
|
||||
|
|
@ -447,12 +447,12 @@ CPU.prototype.displayChecksum = function()
|
|||
* This is principally for displaying register values, but in reality, it can be used to display any
|
||||
* numeric (hex) value bound to the given label.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {string} sLabel
|
||||
* @param {number} nValue
|
||||
* @param {number} cch
|
||||
*/
|
||||
CPU.prototype.displayValue = function(sLabel, nValue, cch)
|
||||
CPU8080.prototype.displayValue = function(sLabel, nValue, cch)
|
||||
{
|
||||
if (this.bindings[sLabel]) {
|
||||
if (nValue === undefined) {
|
||||
|
|
@ -478,14 +478,14 @@ CPU.prototype.displayValue = function(sLabel, nValue, cch)
|
|||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
CPU.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
CPU8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
var cpu = this;
|
||||
var fBound = false;
|
||||
|
|
@ -544,11 +544,11 @@ CPU.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
* NOTE: In this context, "timer" refers to a timer chip (eg, an Intel 8253) being emulated by
|
||||
* by the ChipSet component, not the timers managed by the CPU (eg, addTimer(), setTimer(), etc).
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nCycles is the target number of cycles to drop the current burst to
|
||||
* @return {boolean}
|
||||
*/
|
||||
CPU.prototype.setBurstCycles = function(nCycles)
|
||||
CPU8080.prototype.setBurstCycles = function(nCycles)
|
||||
{
|
||||
if (this.flags.fRunning) {
|
||||
var nDelta = this.nStepCycles - nCycles;
|
||||
|
|
@ -571,11 +571,11 @@ CPU.prototype.setBurstCycles = function(nCycles)
|
|||
/**
|
||||
* addCycles(nCycles, fEndStep)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nCycles
|
||||
* @param {boolean} [fEndStep]
|
||||
*/
|
||||
CPU.prototype.addCycles = function(nCycles, fEndStep)
|
||||
CPU8080.prototype.addCycles = function(nCycles, fEndStep)
|
||||
{
|
||||
this.nTotalCycles += nCycles;
|
||||
if (fEndStep) {
|
||||
|
|
@ -589,9 +589,9 @@ CPU.prototype.addCycles = function(nCycles, fEndStep)
|
|||
* Calculate the number of cycles to process for each "burst" of CPU activity. The size of a burst
|
||||
* is driven by the following values:
|
||||
*
|
||||
* CPU.YIELDS_PER_SECOND (eg, 30)
|
||||
* CPU.VIDEO_UPDATES_PER_SECOND (eg, 60)
|
||||
* CPU.STATUS_UPDATES_PER_SECOND (eg, 5)
|
||||
* CPU8080.YIELDS_PER_SECOND (eg, 30)
|
||||
* CPU8080.VIDEO_UPDATES_PER_SECOND (eg, 60)
|
||||
* CPU8080.STATUS_UPDATES_PER_SECOND (eg, 5)
|
||||
*
|
||||
* The largest of the above values forces the size of the burst to its smallest value. Let's say that
|
||||
* largest value is 30. Assuming nCyclesPerSecond is 1,000,000, that results in bursts of 33,333 cycles.
|
||||
|
|
@ -604,18 +604,18 @@ CPU.prototype.addCycles = function(nCycles, fEndStep)
|
|||
* Similarly, whenever the "next video update" cycle counter goes to (or below) zero, we call updateVideo(),
|
||||
* and whenever the "next status update" cycle counter goes to (or below) zero, we call updateStatus().
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent
|
||||
* speed calculation (see calcSpeed).
|
||||
*/
|
||||
CPU.prototype.calcCycles = function(fRecalc)
|
||||
CPU8080.prototype.calcCycles = function(fRecalc)
|
||||
{
|
||||
/*
|
||||
* Calculate the most cycles we're allowed to execute in a single "burst"
|
||||
*/
|
||||
var nMostUpdatesPerSecond = CPU.YIELDS_PER_SECOND;
|
||||
var nMostUpdatesPerSecond = CPU8080.YIELDS_PER_SECOND;
|
||||
if (nMostUpdatesPerSecond < this.refreshRate) nMostUpdatesPerSecond = this.refreshRate;
|
||||
if (nMostUpdatesPerSecond < CPU.STATUS_UPDATES_PER_SECOND) nMostUpdatesPerSecond = CPU.STATUS_UPDATES_PER_SECOND;
|
||||
if (nMostUpdatesPerSecond < CPU8080.STATUS_UPDATES_PER_SECOND) nMostUpdatesPerSecond = CPU8080.STATUS_UPDATES_PER_SECOND;
|
||||
|
||||
/*
|
||||
* Calculate cycle "per" values for the yield, video update, and status update cycle counters
|
||||
|
|
@ -627,11 +627,11 @@ CPU.prototype.calcCycles = function(fRecalc)
|
|||
}
|
||||
}
|
||||
|
||||
this.aCounts.msPerYield = Math.round(1000 / CPU.YIELDS_PER_SECOND);
|
||||
this.aCounts.msPerYield = Math.round(1000 / CPU8080.YIELDS_PER_SECOND);
|
||||
this.aCounts.nCyclesPerBurst = Math.floor(this.aCounts.nCyclesPerSecond / nMostUpdatesPerSecond * vMultiplier);
|
||||
this.aCounts.nCyclesPerYield = Math.floor(this.aCounts.nCyclesPerSecond / CPU.YIELDS_PER_SECOND * vMultiplier);
|
||||
this.aCounts.nCyclesPerYield = Math.floor(this.aCounts.nCyclesPerSecond / CPU8080.YIELDS_PER_SECOND * vMultiplier);
|
||||
this.aCounts.nCyclesPerVideoUpdate = Math.floor(this.aCounts.nCyclesPerSecond / this.refreshRate * vMultiplier);
|
||||
this.aCounts.nCyclesPerStatusUpdate = Math.floor(this.aCounts.nCyclesPerSecond / CPU.STATUS_UPDATES_PER_SECOND * vMultiplier);
|
||||
this.aCounts.nCyclesPerStatusUpdate = Math.floor(this.aCounts.nCyclesPerSecond / CPU8080.STATUS_UPDATES_PER_SECOND * vMultiplier);
|
||||
|
||||
/*
|
||||
* And initialize "next" yield, video update, and status update cycle "threshold" counters to those "per" values
|
||||
|
|
@ -657,11 +657,11 @@ CPU.prototype.calcCycles = function(fRecalc)
|
|||
* nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on
|
||||
* getCycles() returning steadily increasing values should also be prepared for a reset at any time.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1
|
||||
* @return {number}
|
||||
*/
|
||||
CPU.prototype.getCycles = function(fScaled)
|
||||
CPU8080.prototype.getCycles = function(fScaled)
|
||||
{
|
||||
var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;
|
||||
if (fScaled && this.aCounts.nCyclesMultiplier > 1 && this.aCounts.mhz > this.aCounts.mhzDefault) {
|
||||
|
|
@ -693,10 +693,10 @@ CPU.prototype.getCycles = function(fScaled)
|
|||
*
|
||||
* This returns the CPU's "base" speed (ie, the original cycles per second defined for the machine)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {number}
|
||||
*/
|
||||
CPU.prototype.getCyclesPerSecond = function()
|
||||
CPU8080.prototype.getCyclesPerSecond = function()
|
||||
{
|
||||
return this.aCounts.nCyclesPerSecond;
|
||||
};
|
||||
|
|
@ -708,9 +708,9 @@ CPU.prototype.getCyclesPerSecond = function()
|
|||
* It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),
|
||||
* which in turn assumes that all the cycle counts have been initialized to sensible values.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
*/
|
||||
CPU.prototype.resetCycles = function()
|
||||
CPU8080.prototype.resetCycles = function()
|
||||
{
|
||||
this.aCounts.mhz = 0;
|
||||
this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;
|
||||
|
|
@ -721,10 +721,10 @@ CPU.prototype.resetCycles = function()
|
|||
/**
|
||||
* getSpeed()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {number} the current speed multiplier
|
||||
*/
|
||||
CPU.prototype.getSpeed = function()
|
||||
CPU8080.prototype.getSpeed = function()
|
||||
{
|
||||
return this.aCounts.nCyclesMultiplier;
|
||||
};
|
||||
|
|
@ -732,10 +732,10 @@ CPU.prototype.getSpeed = function()
|
|||
/**
|
||||
* getSpeedCurrent()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {string} the current speed, in mhz, as a string formatted to two decimal places
|
||||
*/
|
||||
CPU.prototype.getSpeedCurrent = function()
|
||||
CPU8080.prototype.getSpeedCurrent = function()
|
||||
{
|
||||
/*
|
||||
* TODO: Has toFixed() been "fixed" in all browsers (eg, IE) to return a rounded value now?
|
||||
|
|
@ -746,10 +746,10 @@ CPU.prototype.getSpeedCurrent = function()
|
|||
/**
|
||||
* getSpeedTarget()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {string} the target speed, in mhz, as a string formatted to two decimal places
|
||||
*/
|
||||
CPU.prototype.getSpeedTarget = function()
|
||||
CPU8080.prototype.getSpeedTarget = function()
|
||||
{
|
||||
/*
|
||||
* TODO: Has toFixed() been "fixed" in all browsers (eg, IE) to return a rounded value now?
|
||||
|
|
@ -766,12 +766,12 @@ CPU.prototype.getSpeedTarget = function()
|
|||
* so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls
|
||||
* setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)
|
||||
* @param {boolean} [fUpdateFocus] is true to update Computer focus
|
||||
* @return {boolean} true if successful, false if not
|
||||
*/
|
||||
CPU.prototype.setSpeed = function(nMultiplier, fUpdateFocus)
|
||||
CPU8080.prototype.setSpeed = function(nMultiplier, fUpdateFocus)
|
||||
{
|
||||
var fSuccess = false;
|
||||
if (nMultiplier !== undefined) {
|
||||
|
|
@ -805,11 +805,11 @@ CPU.prototype.setSpeed = function(nMultiplier, fUpdateFocus)
|
|||
/**
|
||||
* calcSpeed(nCycles, msElapsed)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nCycles
|
||||
* @param {number} msElapsed
|
||||
*/
|
||||
CPU.prototype.calcSpeed = function(nCycles, msElapsed)
|
||||
CPU8080.prototype.calcSpeed = function(nCycles, msElapsed)
|
||||
{
|
||||
if (msElapsed) {
|
||||
this.aCounts.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;
|
||||
|
|
@ -823,9 +823,9 @@ CPU.prototype.calcSpeed = function(nCycles, msElapsed)
|
|||
/**
|
||||
* calcStartTime()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
*/
|
||||
CPU.prototype.calcStartTime = function()
|
||||
CPU8080.prototype.calcStartTime = function()
|
||||
{
|
||||
if (this.aCounts.nCyclesRecalc >= this.aCounts.nCyclesPerSecond) {
|
||||
this.calcCycles(true);
|
||||
|
|
@ -879,10 +879,10 @@ CPU.prototype.calcStartTime = function()
|
|||
/**
|
||||
* calcRemainingTime()
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @return {number}
|
||||
*/
|
||||
CPU.prototype.calcRemainingTime = function()
|
||||
CPU8080.prototype.calcRemainingTime = function()
|
||||
{
|
||||
this.aCounts.msEndThisRun = usr.getTime();
|
||||
|
||||
|
|
@ -939,7 +939,7 @@ CPU.prototype.calcRemainingTime = function()
|
|||
*/
|
||||
this.aCounts.nCyclesRecalc += this.aCounts.nCyclesThisRun;
|
||||
|
||||
if (DEBUG && this.messageEnabled(Messages.LOG) && msRemainsThisRun) {
|
||||
if (DEBUG && this.messageEnabled(Messages8080.LOG) && msRemainsThisRun) {
|
||||
this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.aCounts.msEndThisRun + "ms");
|
||||
}
|
||||
|
||||
|
|
@ -960,11 +960,11 @@ CPU.prototype.calcRemainingTime = function()
|
|||
*
|
||||
* Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {function()} callBack
|
||||
* @return {number} timer index
|
||||
*/
|
||||
CPU.prototype.addTimer = function(callBack)
|
||||
CPU8080.prototype.addTimer = function(callBack)
|
||||
{
|
||||
var iTimer = this.aTimers.length;
|
||||
this.aTimers.push([-1, callBack]);
|
||||
|
|
@ -986,12 +986,12 @@ CPU.prototype.addTimer = function(callBack)
|
|||
* use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,
|
||||
* that's currently not the case. TODO: Fix.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} iTimer
|
||||
* @param {number} ms (converted into a cycle countdown internally)
|
||||
* @return {number} (number of cycles used to arm timer, or -1 if error)
|
||||
*/
|
||||
CPU.prototype.setTimer = function(iTimer, ms)
|
||||
CPU8080.prototype.setTimer = function(iTimer, ms)
|
||||
{
|
||||
var nCycles = -1;
|
||||
if (iTimer >= 0 && iTimer < this.aTimers.length) {
|
||||
|
|
@ -1006,11 +1006,11 @@ CPU.prototype.setTimer = function(iTimer, ms)
|
|||
*
|
||||
* Used by runCPU() to either accept or shorten the current burst if any timers need to fire soon.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nCycles (number of cycles about to execute)
|
||||
* @return {number} (either nCycles or less if a timer needs to fire)
|
||||
*/
|
||||
CPU.prototype.getTimerBurst = function(nCycles)
|
||||
CPU8080.prototype.getTimerBurst = function(nCycles)
|
||||
{
|
||||
for (var i = 0; i < this.aTimers.length; i++) {
|
||||
var timer = this.aTimers[i];
|
||||
|
|
@ -1029,10 +1029,10 @@ CPU.prototype.getTimerBurst = function(nCycles)
|
|||
* this is the function that actually "fires" any timer(s) whose countdown has reached (or dropped below)
|
||||
* zero, invoking their callback function.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nCycles (number of cycles actually executed)
|
||||
*/
|
||||
CPU.prototype.updateTimers = function(nCycles)
|
||||
CPU8080.prototype.updateTimers = function(nCycles)
|
||||
{
|
||||
for (var i = 0; i < this.aTimers.length; i++) {
|
||||
var timer = this.aTimers[i];
|
||||
|
|
@ -1048,10 +1048,10 @@ CPU.prototype.updateTimers = function(nCycles)
|
|||
/**
|
||||
* runCPU(fUpdateFocus)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {boolean} [fUpdateFocus] is true to update Computer focus
|
||||
*/
|
||||
CPU.prototype.runCPU = function(fUpdateFocus)
|
||||
CPU8080.prototype.runCPU = function(fUpdateFocus)
|
||||
{
|
||||
if (!this.setBusy(true)) {
|
||||
this.updateCPU();
|
||||
|
|
@ -1140,7 +1140,7 @@ CPU.prototype.runCPU = function(fUpdateFocus)
|
|||
*
|
||||
* @param {boolean} [fUpdateFocus]
|
||||
*/
|
||||
CPU.prototype.startCPU = function(fUpdateFocus)
|
||||
CPU8080.prototype.startCPU = function(fUpdateFocus)
|
||||
{
|
||||
if (!this.flags.fRunning) {
|
||||
/*
|
||||
|
|
@ -1168,11 +1168,11 @@ CPU.prototype.startCPU = function(fUpdateFocus)
|
|||
*
|
||||
* This will be implemented by the CPUState component.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)
|
||||
* @return {number} of cycles executed; 0 indicates that the last instruction was not executed
|
||||
*/
|
||||
CPU.prototype.stepCPU = function(nMinCycles)
|
||||
CPU8080.prototype.stepCPU = function(nMinCycles)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
|
@ -1185,10 +1185,10 @@ CPU.prototype.stepCPU = function(nMinCycles)
|
|||
* This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();
|
||||
* it simply needs to clear fRunning (well, "simply" may be oversimplifying a bit....)
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {boolean} [fComplete]
|
||||
*/
|
||||
CPU.prototype.stopCPU = function(fComplete)
|
||||
CPU8080.prototype.stopCPU = function(fComplete)
|
||||
{
|
||||
this.isBusy(true);
|
||||
this.nBurstCycles -= this.nStepCycles;
|
||||
|
|
@ -1212,10 +1212,10 @@ CPU.prototype.stopCPU = function(fComplete)
|
|||
* other callers of stepCPU(), such as the Debugger, the combination of stepCPU() + updateCPU()
|
||||
* provides the old behavior.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
* @param {boolean} [fForce] (true to force a video update; used by the Debugger)
|
||||
*/
|
||||
CPU.prototype.updateCPU = function(fForce)
|
||||
CPU8080.prototype.updateCPU = function(fForce)
|
||||
{
|
||||
if (this.cmp) {
|
||||
this.cmp.updateVideo(-1);
|
||||
|
|
@ -1229,9 +1229,9 @@ CPU.prototype.updateCPU = function(fForce)
|
|||
* Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU
|
||||
* remains in a "running" state.
|
||||
*
|
||||
* @this {CPU}
|
||||
* @this {CPU8080}
|
||||
*/
|
||||
CPU.prototype.yieldCPU = function()
|
||||
CPU8080.prototype.yieldCPU = function()
|
||||
{
|
||||
this.aCounts.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()
|
||||
this.nBurstCycles -= this.nStepCycles;
|
||||
|
|
@ -1245,4 +1245,4 @@ CPU.prototype.yieldCPU = function()
|
|||
this.updateCPU();
|
||||
};
|
||||
|
||||
if (NODE) module.exports = CPU;
|
||||
if (NODE) module.exports = CPU8080;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var CPUDef = {
|
||||
var CPUDef8080 = {
|
||||
/*
|
||||
* CPU model numbers (supported)
|
||||
*/
|
||||
|
|
@ -114,17 +114,17 @@ var CPUDef = {
|
|||
* These are the internal PS bits (outside of PS.MASK) that getPS() and setPS() can get and set,
|
||||
* but which cannot be seen with any of the documented instructions.
|
||||
*/
|
||||
CPUDef.PS.INTERNAL = (CPUDef.PS.IF);
|
||||
CPUDef8080.PS.INTERNAL = (CPUDef8080.PS.IF);
|
||||
|
||||
/*
|
||||
* PS "arithmetic" flags are NOT stored in regPS; they are maintained across separate result registers,
|
||||
* hence the RESULT designation.
|
||||
*/
|
||||
CPUDef.PS.RESULT = (CPUDef.PS.CF | CPUDef.PS.PF | CPUDef.PS.AF | CPUDef.PS.ZF | CPUDef.PS.SF);
|
||||
CPUDef8080.PS.RESULT = (CPUDef8080.PS.CF | CPUDef8080.PS.PF | CPUDef8080.PS.AF | CPUDef8080.PS.ZF | CPUDef8080.PS.SF);
|
||||
|
||||
/*
|
||||
* These are the "always set" PS bits for the 8080.
|
||||
*/
|
||||
CPUDef.PS.SET = (CPUDef.PS.BIT1);
|
||||
CPUDef8080.PS.SET = (CPUDef8080.PS.BIT1);
|
||||
|
||||
if (NODE) module.exports = CPUDef;
|
||||
if (NODE) module.exports = CPUDef8080;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -68,7 +68,7 @@ var BYTEARRAYS = false;
|
|||
|
||||
/**
|
||||
* TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've
|
||||
* added Memory access functions for typed arrays (see Memory.afnTypedArray), so support can be enabled dynamically now.
|
||||
* added Memory access functions for typed arrays (see Memory8080.afnTypedArray), so support can be enabled dynamically now.
|
||||
*
|
||||
* See the Memory component for details.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -35,39 +35,39 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var ChipSet8080 = require("./chipset");
|
||||
var Messages8080= require("./messages");
|
||||
}
|
||||
|
||||
/**
|
||||
* Keyboard(parmsKbd)
|
||||
* Keyboard8080(parmsKbd)
|
||||
*
|
||||
* The Keyboard component has the following component-specific (parmsKbd) properties:
|
||||
* The Keyboard8080 component has the following component-specific (parmsKbd) properties:
|
||||
*
|
||||
* model: eg, "VT100" (should be a member of Keyboard.MODELS)
|
||||
* model: eg, "VT100" (should be a member of Keyboard8080.MODELS)
|
||||
*
|
||||
* @constructor
|
||||
* @extends Component
|
||||
* @param {Object} parmsKbd
|
||||
*/
|
||||
function Keyboard(parmsKbd)
|
||||
function Keyboard8080(parmsKbd)
|
||||
{
|
||||
Component.call(this, "Keyboard", parmsKbd, Keyboard, Messages.KEYBOARD);
|
||||
Component.call(this, "Keyboard", parmsKbd, Keyboard8080, Messages8080.KEYBOARD);
|
||||
|
||||
var model = parmsKbd['model'];
|
||||
|
||||
if (model && !Keyboard.MODELS[model]) {
|
||||
Component.notice("Unrecognized Keyboard model: " + model);
|
||||
if (model && !Keyboard8080.MODELS[model]) {
|
||||
Component.notice("Unrecognized Keyboard8080 model: " + model);
|
||||
}
|
||||
|
||||
this.config = Keyboard.MODELS[model] || {};
|
||||
this.config = Keyboard8080.MODELS[model] || {};
|
||||
|
||||
this.reset();
|
||||
|
||||
this.setReady();
|
||||
}
|
||||
|
||||
Component.subclass(Keyboard);
|
||||
Component.subclass(Keyboard8080);
|
||||
|
||||
/**
|
||||
* Alphanumeric and other common (printable) ASCII codes.
|
||||
|
|
@ -78,7 +78,7 @@ Component.subclass(Keyboard);
|
|||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
Keyboard.ASCII = {
|
||||
Keyboard8080.ASCII = {
|
||||
CTRL_A: 1, CTRL_C: 3, CTRL_Z: 26,
|
||||
' ': 32, '!': 33, '"': 34, '#': 35, '$': 36, '%': 37, '&': 38, "'": 39,
|
||||
'(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,
|
||||
|
|
@ -106,7 +106,7 @@ Keyboard.ASCII = {
|
|||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
Keyboard.KEYCODE = {
|
||||
Keyboard8080.KEYCODE = {
|
||||
/* 0x08 */ BS: 8,
|
||||
/* 0x09 */ TAB: 9,
|
||||
/* 0x0A */ LF: 10, // TODO: Determine if any key actually generates this (I suspect there is none)
|
||||
|
|
@ -227,26 +227,26 @@ Keyboard.KEYCODE = {
|
|||
/*
|
||||
* Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.
|
||||
*/
|
||||
Keyboard.KEYCODE.NUM_CR = Keyboard.KEYCODE.CR + Keyboard.KEYCODE.ONRIGHT;
|
||||
Keyboard8080.KEYCODE.NUM_CR = Keyboard8080.KEYCODE.CR + Keyboard8080.KEYCODE.ONRIGHT;
|
||||
|
||||
/*
|
||||
* Maps "stupid" keyCodes to their "non-stupid" counterparts
|
||||
*/
|
||||
Keyboard.STUPID_KEYCODES = {};
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.SEMI] = Keyboard.ASCII[';']; // 186 -> 59
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.EQUALS] = Keyboard.ASCII['=']; // 187 -> 61
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.COMMA] = Keyboard.ASCII[',']; // 188 -> 44
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.DASH] = Keyboard.ASCII['-']; // 189 -> 45
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.PERIOD] = Keyboard.ASCII['.']; // 190 -> 46
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.SLASH] = Keyboard.ASCII['/']; // 191 -> 47
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.BQUOTE] = Keyboard.ASCII['`']; // 192 -> 96
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.LBRACK] = Keyboard.ASCII['[']; // 219 -> 91
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.BSLASH] = Keyboard.ASCII['\\']; // 220 -> 92
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.RBRACK] = Keyboard.ASCII[']']; // 221 -> 93
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.QUOTE] = Keyboard.ASCII["'"]; // 222 -> 39
|
||||
Keyboard.STUPID_KEYCODES[Keyboard.KEYCODE.FF_DASH] = Keyboard.ASCII['-'];
|
||||
Keyboard8080.STUPID_KEYCODES = {};
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.SEMI] = Keyboard8080.ASCII[';']; // 186 -> 59
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.EQUALS] = Keyboard8080.ASCII['=']; // 187 -> 61
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.COMMA] = Keyboard8080.ASCII[',']; // 188 -> 44
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.DASH] = Keyboard8080.ASCII['-']; // 189 -> 45
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.PERIOD] = Keyboard8080.ASCII['.']; // 190 -> 46
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.SLASH] = Keyboard8080.ASCII['/']; // 191 -> 47
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.BQUOTE] = Keyboard8080.ASCII['`']; // 192 -> 96
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.LBRACK] = Keyboard8080.ASCII['[']; // 219 -> 91
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.BSLASH] = Keyboard8080.ASCII['\\']; // 220 -> 92
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.RBRACK] = Keyboard8080.ASCII[']']; // 221 -> 93
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.QUOTE] = Keyboard8080.ASCII["'"]; // 222 -> 39
|
||||
Keyboard8080.STUPID_KEYCODES[Keyboard8080.KEYCODE.FF_DASH] = Keyboard8080.ASCII['-'];
|
||||
|
||||
Keyboard.MINPRESSTIME = 100; // 100ms
|
||||
Keyboard8080.MINPRESSTIME = 100; // 100ms
|
||||
|
||||
/**
|
||||
* Alternate keyCode mappings to support popular "WASD"-style directional-key mappings.
|
||||
|
|
@ -254,36 +254,36 @@ Keyboard.MINPRESSTIME = 100; // 100ms
|
|||
* TODO: ES6 computed property name support may now be in all mainstream browsers, allowing us to use
|
||||
* a simple object literal for this and all other object initializations.
|
||||
*/
|
||||
Keyboard.WASDCODES = {};
|
||||
Keyboard.WASDCODES[Keyboard.ASCII.A] = Keyboard.KEYCODE.LEFT;
|
||||
Keyboard.WASDCODES[Keyboard.ASCII.D] = Keyboard.KEYCODE.RIGHT;
|
||||
Keyboard.WASDCODES[Keyboard.ASCII.L] = Keyboard.KEYCODE.SPACE;
|
||||
Keyboard8080.WASDCODES = {};
|
||||
Keyboard8080.WASDCODES[Keyboard8080.ASCII.A] = Keyboard8080.KEYCODE.LEFT;
|
||||
Keyboard8080.WASDCODES[Keyboard8080.ASCII.D] = Keyboard8080.KEYCODE.RIGHT;
|
||||
Keyboard8080.WASDCODES[Keyboard8080.ASCII.L] = Keyboard8080.KEYCODE.SPACE;
|
||||
|
||||
/*
|
||||
* Supported configurations
|
||||
*/
|
||||
Keyboard.SI1978 = {
|
||||
Keyboard8080.SI1978 = {
|
||||
MODEL: 1978.1,
|
||||
KEYMAP: {},
|
||||
ALTCODES: Keyboard.WASDCODES,
|
||||
ALTCODES: Keyboard8080.WASDCODES,
|
||||
LEDCODES: {},
|
||||
SOFTCODES: {
|
||||
'1p': Keyboard.KEYCODE.ONE,
|
||||
'2p': Keyboard.KEYCODE.TWO,
|
||||
'coin': Keyboard.KEYCODE.THREE,
|
||||
'left': Keyboard.KEYCODE.LEFT,
|
||||
'right': Keyboard.KEYCODE.RIGHT,
|
||||
'fire': Keyboard.KEYCODE.SPACE
|
||||
'1p': Keyboard8080.KEYCODE.ONE,
|
||||
'2p': Keyboard8080.KEYCODE.TWO,
|
||||
'coin': Keyboard8080.KEYCODE.THREE,
|
||||
'left': Keyboard8080.KEYCODE.LEFT,
|
||||
'right': Keyboard8080.KEYCODE.RIGHT,
|
||||
'fire': Keyboard8080.KEYCODE.SPACE
|
||||
}
|
||||
};
|
||||
|
||||
Keyboard.VT100 = {
|
||||
Keyboard8080.VT100 = {
|
||||
MODEL: 100.0,
|
||||
KEYMAP: {},
|
||||
ALTCODES: {},
|
||||
LEDCODES: {},
|
||||
SOFTCODES: {
|
||||
'setup': Keyboard.KEYCODE.F9
|
||||
'setup': Keyboard8080.KEYCODE.F9
|
||||
},
|
||||
/*
|
||||
* Reading port 0x82 returns a key address from the VT100 keyboard's UART data output.
|
||||
|
|
@ -328,119 +328,119 @@ Keyboard.VT100 = {
|
|||
/*
|
||||
* Table to map host key codes to VT100 key addresses (ie, unique 7-bit values representing key positions on the VT100)
|
||||
*/
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.DEL] = 0x03;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.P] = 0x05;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.O] = 0x06;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.Y] = 0x07;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.T] = 0x08;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.W] = 0x09;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.Q] = 0x0A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.RIGHT] = 0x10;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.RBRACK] = 0x14;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.LBRACK] = 0x15;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.I] = 0x16;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.U] = 0x17;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.R] = 0x18;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.E] = 0x19;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.ONE] = 0x1A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.LEFT] = 0x20;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.DOWN] = 0x22;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F6] = 0x23; // aka BREAK
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.PAUSE] = 0x23; // aka BREAK
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.BQUOTE] = 0x24;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.DASH] = 0x25;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NINE] = 0x26;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.SEVEN] = 0x27;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.FOUR] = 0x28;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.THREE] = 0x29;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.ESC] = 0x2A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.UP] = 0x30;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F3] = 0x31; // aka PF3
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F1] = 0x32; // aka PF1
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.BS] = 0x33;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.EQUALS] = 0x34;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.ZERO] = 0x35;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.EIGHT] = 0x36;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.SIX] = 0x37;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.FIVE] = 0x38;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.TWO] = 0x39;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.TAB] = 0x3A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_7] = 0x40;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F4] = 0x41; // aka PF4
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F2] = 0x42; // aka PF2
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_0] = 0x43;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F7] = 0x44; // aka LINE FEED
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.BSLASH] = 0x45;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.L] = 0x46;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.K] = 0x47;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.G] = 0x48;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.F] = 0x49;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.A] = 0x4A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_8] = 0x50;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_CR] = 0x51;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_2] = 0x52;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_1] = 0x53;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.QUOTE] = 0x55;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.SEMI] = 0x56;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.J] = 0x57;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.H] = 0x58;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.D] = 0x59;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.S] = 0x5A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_DEL] = 0x60; // keypad period
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F5] = 0x61; // aka KEYPAD COMMA
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_5] = 0x62;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_4] = 0x63;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.CR] = 0x64; // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.PERIOD] = 0x65;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.COMMA] = 0x66;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.N] = 0x67;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.B] = 0x68;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.X] = 0x69;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F8] = 0x6A; // aka NO SCROLL
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_9] = 0x70;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_3] = 0x71;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_6] = 0x72;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.NUM_SUB] = 0x73; // aka KEYPAD MINUS
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.SLASH] = 0x75;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.M] = 0x76;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII[' ']] = 0x77;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.V] = 0x78;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.C] = 0x79;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.Z] = 0x7A;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.F9] = 0x7B; // aka SET-UP
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.CTRL] = 0x7C;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.SHIFT] = 0x7D; // either shift key (doesn't matter)
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.CAPSLOCK]= 0x7E;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.DEL] = 0x03;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.P] = 0x05;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.O] = 0x06;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.Y] = 0x07;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.T] = 0x08;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.W] = 0x09;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.Q] = 0x0A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.RIGHT] = 0x10;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.RBRACK] = 0x14;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.LBRACK] = 0x15;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.I] = 0x16;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.U] = 0x17;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.R] = 0x18;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.E] = 0x19;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.ONE] = 0x1A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.LEFT] = 0x20;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.DOWN] = 0x22;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F6] = 0x23; // aka BREAK
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.PAUSE] = 0x23; // aka BREAK
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.BQUOTE] = 0x24;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.DASH] = 0x25;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NINE] = 0x26;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.SEVEN] = 0x27;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.FOUR] = 0x28;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.THREE] = 0x29;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.ESC] = 0x2A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.UP] = 0x30;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F3] = 0x31; // aka PF3
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F1] = 0x32; // aka PF1
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.BS] = 0x33;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.EQUALS] = 0x34;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.ZERO] = 0x35;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.EIGHT] = 0x36;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.SIX] = 0x37;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.FIVE] = 0x38;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.TWO] = 0x39;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.TAB] = 0x3A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_7] = 0x40;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F4] = 0x41; // aka PF4
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F2] = 0x42; // aka PF2
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_0] = 0x43;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F7] = 0x44; // aka LINE FEED
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.BSLASH] = 0x45;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.L] = 0x46;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.K] = 0x47;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.G] = 0x48;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.F] = 0x49;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.A] = 0x4A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_8] = 0x50;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_CR] = 0x51;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_2] = 0x52;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_1] = 0x53;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.QUOTE] = 0x55;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.SEMI] = 0x56;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.J] = 0x57;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.H] = 0x58;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.D] = 0x59;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.S] = 0x5A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_DEL] = 0x60; // keypad period
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F5] = 0x61; // aka KEYPAD COMMA
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_5] = 0x62;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_4] = 0x63;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.CR] = 0x64; // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.PERIOD] = 0x65;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.COMMA] = 0x66;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.N] = 0x67;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.B] = 0x68;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.X] = 0x69;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F8] = 0x6A; // aka NO SCROLL
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_9] = 0x70;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_3] = 0x71;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_6] = 0x72;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.NUM_SUB] = 0x73; // aka KEYPAD MINUS
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.SLASH] = 0x75;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.M] = 0x76;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII[' ']] = 0x77;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.V] = 0x78;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.C] = 0x79;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.ASCII.Z] = 0x7A;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.F9] = 0x7B; // aka SET-UP
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.CTRL] = 0x7C;
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.SHIFT] = 0x7D; // either shift key (doesn't matter)
|
||||
Keyboard8080.VT100.KEYMAP[Keyboard8080.KEYCODE.CAPSLOCK]= 0x7E;
|
||||
|
||||
Keyboard.VT100.LEDCODES = {
|
||||
'l4': Keyboard.VT100.STATUS.LED4,
|
||||
'l3': Keyboard.VT100.STATUS.LED3,
|
||||
'l2': Keyboard.VT100.STATUS.LED2,
|
||||
'l1': Keyboard.VT100.STATUS.LED1,
|
||||
'locked': Keyboard.VT100.STATUS.LOCKED,
|
||||
'local': Keyboard.VT100.STATUS.LOCAL,
|
||||
'online': ~Keyboard.VT100.STATUS.LOCAL
|
||||
Keyboard8080.VT100.LEDCODES = {
|
||||
'l4': Keyboard8080.VT100.STATUS.LED4,
|
||||
'l3': Keyboard8080.VT100.STATUS.LED3,
|
||||
'l2': Keyboard8080.VT100.STATUS.LED2,
|
||||
'l1': Keyboard8080.VT100.STATUS.LED1,
|
||||
'locked': Keyboard8080.VT100.STATUS.LOCKED,
|
||||
'local': Keyboard8080.VT100.STATUS.LOCAL,
|
||||
'online': ~Keyboard8080.VT100.STATUS.LOCAL
|
||||
};
|
||||
|
||||
/*
|
||||
* Supported models and their configurations
|
||||
*/
|
||||
Keyboard.MODELS = {
|
||||
"SI1978": Keyboard.SI1978,
|
||||
"VT100": Keyboard.VT100
|
||||
Keyboard8080.MODELS = {
|
||||
"SI1978": Keyboard8080.SI1978,
|
||||
"VT100": Keyboard8080.VT100
|
||||
};
|
||||
|
||||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "esc")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
Keyboard8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
/*
|
||||
* There's a special binding that the Video component uses ("kbd") to effectively bind its
|
||||
|
|
@ -528,18 +528,18 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {Keyboard8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
Keyboard.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
Keyboard8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg; // NOTE: The "dbg" property must be set for the message functions to work
|
||||
this.chipset = /** @type {ChipSet} */ (cmp.getMachineComponent("ChipSet"));
|
||||
this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent("ChipSet"));
|
||||
bus.addPortInputTable(this, this.config.portsInput);
|
||||
bus.addPortOutputTable(this, this.config.portsOutput);
|
||||
};
|
||||
|
|
@ -547,12 +547,12 @@ Keyboard.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
Keyboard.prototype.powerUp = function(data, fRepower)
|
||||
Keyboard8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) {
|
||||
if (!data) {
|
||||
|
|
@ -567,20 +567,20 @@ Keyboard.prototype.powerUp = function(data, fRepower)
|
|||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
Keyboard.prototype.powerDown = function(fSave, fShutdown)
|
||||
Keyboard8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
return fSave? this.save() : true;
|
||||
};
|
||||
|
||||
Keyboard.VT100.INIT = [
|
||||
Keyboard8080.VT100.INIT = [
|
||||
[
|
||||
Keyboard.VT100.STATUS.INIT, // bVT100Status
|
||||
Keyboard.VT100.ADDRESS.INIT, // bVT100Address
|
||||
Keyboard8080.VT100.STATUS.INIT, // bVT100Status
|
||||
Keyboard8080.VT100.ADDRESS.INIT, // bVT100Address
|
||||
-1 // iKeyNext
|
||||
]
|
||||
];
|
||||
|
|
@ -588,9 +588,9 @@ Keyboard.VT100.INIT = [
|
|||
/**
|
||||
* reset()
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
*/
|
||||
Keyboard.prototype.reset = function()
|
||||
Keyboard8080.prototype.reset = function()
|
||||
{
|
||||
/*
|
||||
* As keyDown events are encountered, a corresponding "softCode" is looked up. If one is found,
|
||||
|
|
@ -614,16 +614,16 @@ Keyboard.prototype.reset = function()
|
|||
*
|
||||
* This implements save support for the Keyboard component.
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @return {Object}
|
||||
*/
|
||||
Keyboard.prototype.save = function()
|
||||
Keyboard8080.prototype.save = function()
|
||||
{
|
||||
var state = new State(this);
|
||||
switch(this.config.MODEL) {
|
||||
case Keyboard.SI1978.MODEL:
|
||||
case Keyboard8080.SI1978.MODEL:
|
||||
break;
|
||||
case Keyboard.VT100.MODEL:
|
||||
case Keyboard8080.VT100.MODEL:
|
||||
state.set(0, [this.bVT100Status, this.bVT100Address, -1]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -635,21 +635,21 @@ Keyboard.prototype.save = function()
|
|||
*
|
||||
* This implements restore support for the Keyboard component.
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
Keyboard.prototype.restore = function(data)
|
||||
Keyboard8080.prototype.restore = function(data)
|
||||
{
|
||||
var a;
|
||||
if (data && (a = data[0]) && a.length) {
|
||||
switch(this.config.MODEL) {
|
||||
case Keyboard.SI1978.MODEL:
|
||||
case Keyboard8080.SI1978.MODEL:
|
||||
return true;
|
||||
|
||||
case Keyboard.VT100.MODEL:
|
||||
case Keyboard8080.VT100.MODEL:
|
||||
this.bVT100Status = a[0];
|
||||
this.updateLEDs(this.bVT100Status & Keyboard.VT100.STATUS.LEDS);
|
||||
this.updateLEDs(this.bVT100Status & Keyboard8080.VT100.STATUS.LEDS);
|
||||
this.bVT100Address = a[1];
|
||||
this.iKeyNext = a[2];
|
||||
return true;
|
||||
|
|
@ -661,11 +661,11 @@ Keyboard.prototype.restore = function(data)
|
|||
/**
|
||||
* setLED(control, f)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} control is an HTML control DOM object
|
||||
* @param {boolean} f is true if the LED represented by control should be "on", false if "off"
|
||||
*/
|
||||
Keyboard.prototype.setLED = function(control, f)
|
||||
Keyboard8080.prototype.setLED = function(control, f)
|
||||
{
|
||||
/*
|
||||
* TODO: Add support for user-definable LED colors
|
||||
|
|
@ -676,10 +676,10 @@ Keyboard.prototype.setLED = function(control, f)
|
|||
/**
|
||||
* updateLEDs(bLEDs)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {number} bLEDs
|
||||
*/
|
||||
Keyboard.prototype.updateLEDs = function(bLEDs)
|
||||
Keyboard8080.prototype.updateLEDs = function(bLEDs)
|
||||
{
|
||||
this.bLEDs = bLEDs;
|
||||
for (var sBinding in this.config.LEDCODES) {
|
||||
|
|
@ -701,10 +701,10 @@ Keyboard.prototype.updateLEDs = function(bLEDs)
|
|||
*
|
||||
* Returns a number if the keyCode exists in the KEYMAP, or a string if the keyCode has a soft-code string.
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @return {string|number|null}
|
||||
*/
|
||||
Keyboard.prototype.getSoftCode = function(keyCode)
|
||||
Keyboard8080.prototype.getSoftCode = function(keyCode)
|
||||
{
|
||||
keyCode = this.config.ALTCODES[keyCode] || keyCode;
|
||||
if (this.config.KEYMAP[keyCode]) {
|
||||
|
|
@ -721,12 +721,12 @@ Keyboard.prototype.getSoftCode = function(keyCode)
|
|||
/**
|
||||
* onKeyDown(event, fDown)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} event
|
||||
* @param {boolean} fDown is true for a keyDown event, false for up
|
||||
* @return {boolean} true to pass the event along, false to consume it
|
||||
*/
|
||||
Keyboard.prototype.onKeyDown = function(event, fDown)
|
||||
Keyboard8080.prototype.onKeyDown = function(event, fDown)
|
||||
{
|
||||
var fPass = true;
|
||||
var keyCode = event.keyCode;
|
||||
|
|
@ -737,7 +737,7 @@ Keyboard.prototype.onKeyDown = function(event, fDown)
|
|||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||
if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {
|
||||
this.printMessage("onKey" + (fDown? "Down" : "Up") + "(" + keyCode + "): softCode=" + softCode + ", pass=" + (fPass? "true" : "false"), true);
|
||||
}
|
||||
|
||||
|
|
@ -747,11 +747,11 @@ Keyboard.prototype.onKeyDown = function(event, fDown)
|
|||
/**
|
||||
* indexOfSoftKey(softCode)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {number|string} softCode
|
||||
* @return {number} index of softCode in aKeysActive, or -1 if not found
|
||||
*/
|
||||
Keyboard.prototype.indexOfSoftKey = function(softCode)
|
||||
Keyboard8080.prototype.indexOfSoftKey = function(softCode)
|
||||
{
|
||||
var i;
|
||||
for (i = 0; i < this.aKeysActive.length; i++) {
|
||||
|
|
@ -763,12 +763,12 @@ Keyboard.prototype.indexOfSoftKey = function(softCode)
|
|||
/**
|
||||
* onSoftKeyDown(softCode, fDown)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {number|string} softCode
|
||||
* @param {boolean} fDown is true for a down event, false for up
|
||||
* @return {boolean} true to pass the event along, false to consume it
|
||||
*/
|
||||
Keyboard.prototype.onSoftKeyDown = function(softCode, fDown)
|
||||
Keyboard8080.prototype.onSoftKeyDown = function(softCode, fDown)
|
||||
{
|
||||
var i = this.indexOfSoftKey(softCode);
|
||||
if (fDown) {
|
||||
|
|
@ -789,7 +789,7 @@ Keyboard.prototype.onSoftKeyDown = function(softCode, fDown)
|
|||
var msDown = this.aKeysActive[i].msDown;
|
||||
if (msDown) {
|
||||
var msElapsed = Date.now() - msDown;
|
||||
if (msElapsed < Keyboard.MINPRESSTIME) {
|
||||
if (msElapsed < Keyboard8080.MINPRESSTIME) {
|
||||
// this.println(softCode + " released after only " + msElapsed + "ms");
|
||||
this.aKeysActive[i].fAutoRelease = true;
|
||||
this.checkSoftKeysToRelease();
|
||||
|
|
@ -806,22 +806,22 @@ Keyboard.prototype.onSoftKeyDown = function(softCode, fDown)
|
|||
var bit = 0;
|
||||
switch(softCode) {
|
||||
case '1p':
|
||||
bit = ChipSet.SI1978.STATUS1.P1;
|
||||
bit = ChipSet8080.SI1978.STATUS1.P1;
|
||||
break;
|
||||
case '2p':
|
||||
bit = ChipSet.SI1978.STATUS1.P2;
|
||||
bit = ChipSet8080.SI1978.STATUS1.P2;
|
||||
break;
|
||||
case 'coin':
|
||||
bit = ChipSet.SI1978.STATUS1.CREDIT;
|
||||
bit = ChipSet8080.SI1978.STATUS1.CREDIT;
|
||||
break;
|
||||
case 'left':
|
||||
bit = ChipSet.SI1978.STATUS1.P1_LEFT;
|
||||
bit = ChipSet8080.SI1978.STATUS1.P1_LEFT;
|
||||
break;
|
||||
case 'right':
|
||||
bit = ChipSet.SI1978.STATUS1.P1_RIGHT;
|
||||
bit = ChipSet8080.SI1978.STATUS1.P1_RIGHT;
|
||||
break;
|
||||
case 'fire':
|
||||
bit = ChipSet.SI1978.STATUS1.P1_FIRE;
|
||||
bit = ChipSet8080.SI1978.STATUS1.P1_FIRE;
|
||||
break;
|
||||
}
|
||||
if (bit) {
|
||||
|
|
@ -834,9 +834,9 @@ Keyboard.prototype.onSoftKeyDown = function(softCode, fDown)
|
|||
/**
|
||||
* checkSoftKeysToRelease()
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
*/
|
||||
Keyboard.prototype.checkSoftKeysToRelease = function()
|
||||
Keyboard8080.prototype.checkSoftKeysToRelease = function()
|
||||
{
|
||||
var i = 0;
|
||||
var msDelayMin = -1;
|
||||
|
|
@ -845,7 +845,7 @@ Keyboard.prototype.checkSoftKeysToRelease = function()
|
|||
var softCode = this.aKeysActive[i].softCode;
|
||||
var msDown = this.aKeysActive[i].msDown;
|
||||
var msElapsed = Date.now() - msDown;
|
||||
var msDelay = Keyboard.MINPRESSTIME - msElapsed;
|
||||
var msDelay = Keyboard8080.MINPRESSTIME - msElapsed;
|
||||
if (msDelay > 0) {
|
||||
if (msDelayMin < 0 || msDelayMin > msDelay) {
|
||||
msDelayMin = msDelay;
|
||||
|
|
@ -875,10 +875,10 @@ Keyboard.prototype.checkSoftKeysToRelease = function()
|
|||
* Called whenever a ChipSet circuit needs the Keyboard UART's transmitter status.
|
||||
* Currently, we have no busy conditions (our virtual keyboard transmitter is infinitely fast).
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @return {boolean} (true if ready, false if not)
|
||||
*/
|
||||
Keyboard.prototype.isTransmitterReady = function()
|
||||
Keyboard8080.prototype.isTransmitterReady = function()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
|
@ -888,15 +888,15 @@ Keyboard.prototype.isTransmitterReady = function()
|
|||
*
|
||||
* We take our cue from iKeyNext. If it's -1 (default), we simply return the last value latched
|
||||
* in bVT100Address. Otherwise, if iKeyNext is a valid index into aKeysActive, we look up the key
|
||||
* in the VT100.KEYMAP, latch it, and increment iKeyNext. Failing that, we latch Keyboard.VT100.KEYLAST
|
||||
* in the VT100.KEYMAP, latch it, and increment iKeyNext. Failing that, we latch Keyboard8080.VT100.KEYLAST
|
||||
* and reset iKeyNext to -1.
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {number} port (0x82)
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
Keyboard.prototype.inVT100UARTAddress = function(port, addrFrom)
|
||||
Keyboard8080.prototype.inVT100UARTAddress = function(port, addrFrom)
|
||||
{
|
||||
var b = this.bVT100Address;
|
||||
if (this.iKeyNext >= 0) {
|
||||
|
|
@ -913,7 +913,7 @@ Keyboard.prototype.inVT100UARTAddress = function(port, addrFrom)
|
|||
*/
|
||||
this.aKeysActive.splice(this.iKeyNext, 1);
|
||||
}
|
||||
b = Keyboard.VT100.KEYMAP[key.softCode];
|
||||
b = Keyboard8080.VT100.KEYMAP[key.softCode];
|
||||
if (b & 0x80) {
|
||||
/*
|
||||
* TODO: This code is supposed to be accompanied by a SHIFT key; make sure that it is.
|
||||
|
|
@ -922,7 +922,7 @@ Keyboard.prototype.inVT100UARTAddress = function(port, addrFrom)
|
|||
}
|
||||
} else {
|
||||
this.iKeyNext = -1;
|
||||
b = Keyboard.VT100.KEYLAST;
|
||||
b = Keyboard8080.VT100.KEYLAST;
|
||||
}
|
||||
this.bVT100Address = b;
|
||||
this.cpu.requestINTR(1);
|
||||
|
|
@ -934,17 +934,17 @@ Keyboard.prototype.inVT100UARTAddress = function(port, addrFrom)
|
|||
/**
|
||||
* outVT100UARTStatus(port, b, addrFrom)
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @this {Keyboard8080}
|
||||
* @param {number} port (0x82)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
Keyboard.prototype.outVT100UARTStatus = function(port, b, addrFrom)
|
||||
Keyboard8080.prototype.outVT100UARTStatus = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "KBDUART.STATUS");
|
||||
this.bVT100Status = b;
|
||||
this.updateLEDs(b & Keyboard.VT100.STATUS.LEDS);
|
||||
if (b & Keyboard.VT100.STATUS.START) {
|
||||
this.updateLEDs(b & Keyboard8080.VT100.STATUS.LEDS);
|
||||
if (b & Keyboard8080.VT100.STATUS.START) {
|
||||
this.iKeyNext = 0;
|
||||
this.cpu.requestINTR(1);
|
||||
}
|
||||
|
|
@ -953,29 +953,29 @@ Keyboard.prototype.outVT100UARTStatus = function(port, b, addrFrom)
|
|||
/*
|
||||
* Port notification tables
|
||||
*/
|
||||
Keyboard.VT100.portsInput = {
|
||||
0x82: Keyboard.prototype.inVT100UARTAddress
|
||||
Keyboard8080.VT100.portsInput = {
|
||||
0x82: Keyboard8080.prototype.inVT100UARTAddress
|
||||
};
|
||||
|
||||
Keyboard.VT100.portsOutput = {
|
||||
0x82: Keyboard.prototype.outVT100UARTStatus
|
||||
Keyboard8080.VT100.portsOutput = {
|
||||
0x82: Keyboard8080.prototype.outVT100UARTStatus
|
||||
};
|
||||
|
||||
/**
|
||||
* Keyboard.init()
|
||||
* Keyboard8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "keyboard", extracting the
|
||||
* JSON-encoded parameters for the Keyboard constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a Keyboard component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*/
|
||||
Keyboard.init = function()
|
||||
Keyboard8080.init = function()
|
||||
{
|
||||
var aeKbd = Component.getElementsByClass(document, PC8080.APPCLASS, "keyboard");
|
||||
for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {
|
||||
var eKbd = aeKbd[iKbd];
|
||||
var parmsKbd = Component.getComponentParms(eKbd);
|
||||
var kbd = new Keyboard(parmsKbd);
|
||||
var kbd = new Keyboard8080(parmsKbd);
|
||||
Component.bindComponentControls(kbd, eKbd, PC8080.APPCLASS);
|
||||
}
|
||||
};
|
||||
|
|
@ -983,6 +983,6 @@ Keyboard.init = function()
|
|||
/*
|
||||
* Initialize every Keyboard module on the page.
|
||||
*/
|
||||
web.onInit(Keyboard.init);
|
||||
web.onInit(Keyboard8080.init);
|
||||
|
||||
if (NODE) module.exports = Keyboard;
|
||||
if (NODE) module.exports = Keyboard8080;
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@
|
|||
if (NODE) {
|
||||
var str = require("../../shared/lib/strlib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
var CPUDef = require("./cpudef");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var Messages8080= require("./messages");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -55,20 +55,20 @@ var littleEndian = (TYPEDARRAYS? (function() {
|
|||
})() : false);
|
||||
|
||||
/**
|
||||
* Memory(addr, used, size, type)
|
||||
* Memory8080(addr, used, size, type)
|
||||
*
|
||||
* The Bus component allocates Memory objects so that each has a memory buffer with a
|
||||
* The Bus component allocates Memory8080 objects so that each has a memory buffer with a
|
||||
* block-granular starting address and an address range equal to bus.nBlockSize; however,
|
||||
* the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;
|
||||
* the size of any given Memory8080 object's underlying buffer can be either zero or bus.nBlockSize;
|
||||
* memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.
|
||||
*
|
||||
* The Bus allocates empty blocks for the entire address space during initialization, so that
|
||||
* any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM
|
||||
* components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate
|
||||
* as many new blockSize Memory objects as the ranges require. Partial Memory blocks could
|
||||
* as many new blockSize Memory8080 objects as the ranges require. Partial Memory8080 blocks could
|
||||
* also be supported in theory, but in practice, they're not.
|
||||
*
|
||||
* Because Memory blocks now allow us to have a "sparse" address space, we could choose to
|
||||
* Because Memory8080 blocks now allow us to have a "sparse" address space, we could choose to
|
||||
* take the memory hit of allocating 4K arrays per block, where each element stores only one byte,
|
||||
* instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords
|
||||
* (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would
|
||||
|
|
@ -82,7 +82,7 @@ var littleEndian = (TYPEDARRAYS? (function() {
|
|||
* size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably
|
||||
* the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).
|
||||
*
|
||||
* WARNING: Since Memory blocks are low-level objects that have no UI requirements, they
|
||||
* WARNING: Since Memory8080 blocks are low-level objects that have no UI requirements, they
|
||||
* do not inherit from the Component class, so if you want to use any Component class methods,
|
||||
* such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger
|
||||
* is available).
|
||||
|
|
@ -91,19 +91,19 @@ var littleEndian = (TYPEDARRAYS? (function() {
|
|||
* @param {number|null} [addr] of lowest used address in block
|
||||
* @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4
|
||||
* @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4
|
||||
* @param {number} [type] is one of the Memory.TYPE constants (default is Memory.TYPE.NONE)
|
||||
* @param {number} [type] is one of the Memory8080.TYPE constants (default is Memory8080.TYPE.NONE)
|
||||
*/
|
||||
function Memory(addr, used, size, type)
|
||||
function Memory8080(addr, used, size, type)
|
||||
{
|
||||
var i;
|
||||
this.id = (Memory.idBlock += 2);
|
||||
this.id = (Memory8080.idBlock += 2);
|
||||
this.adw = null;
|
||||
this.offset = 0;
|
||||
this.addr = addr;
|
||||
this.used = used;
|
||||
this.size = size || 0;
|
||||
this.type = type || Memory.TYPE.NONE;
|
||||
this.fReadOnly = (type == Memory.TYPE.ROM);
|
||||
this.type = type || Memory8080.TYPE.NONE;
|
||||
this.fReadOnly = (type == Memory8080.TYPE.ROM);
|
||||
this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize
|
||||
|
||||
/*
|
||||
|
|
@ -146,7 +146,7 @@ function Memory(addr, used, size, type)
|
|||
this.ab = new Uint8Array(this.buffer, 0, size);
|
||||
this.aw = new Uint16Array(this.buffer, 0, size >> 1);
|
||||
this.adw = new Int32Array(this.buffer, 0, size >> 2);
|
||||
this.setAccess(littleEndian? Memory.afnArrayLE : Memory.afnArrayBE);
|
||||
this.setAccess(littleEndian? Memory8080.afnArrayLE : Memory8080.afnArrayBE);
|
||||
} else {
|
||||
if (BYTEARRAYS) {
|
||||
this.ab = new Array(size);
|
||||
|
|
@ -160,7 +160,7 @@ function Memory(addr, used, size, type)
|
|||
this.adw = new Array(size >> 2);
|
||||
for (i = 0; i < this.adw.length; i++) this.adw[i] = 0;
|
||||
}
|
||||
this.setAccess(Memory.afnMemory);
|
||||
this.setAccess(Memory8080.afnMemory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ function Memory(addr, used, size, type)
|
|||
* 'little endian") storage. ROM is equally conventional, except that the fReadOnly property is set,
|
||||
* disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and
|
||||
* VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()
|
||||
* interface (which in turn uses the Memory writeByteDirect() interface), allowing the ROM component to
|
||||
* interface (which in turn uses the Memory8080 writeByteDirect() interface), allowing the ROM component to
|
||||
* initialize its own memory. The CTRL type is used to identify memory-mapped devices that do not need
|
||||
* any default storage and always provide their own controller.
|
||||
*
|
||||
|
|
@ -186,7 +186,7 @@ function Memory(addr, used, size, type)
|
|||
* read-only memory), but the larger purpose of these types is to help document the caller's intent and to
|
||||
* provide the Control Panel with the ability to highlight memory regions accordingly.
|
||||
*/
|
||||
Memory.TYPE = {
|
||||
Memory8080.TYPE = {
|
||||
NONE: 0,
|
||||
RAM: 1,
|
||||
ROM: 2,
|
||||
|
|
@ -199,7 +199,7 @@ Memory.TYPE = {
|
|||
/*
|
||||
* Last used block ID (used for debugging only)
|
||||
*/
|
||||
Memory.idBlock = 0;
|
||||
Memory8080.idBlock = 0;
|
||||
|
||||
/**
|
||||
* adjustEndian(dw)
|
||||
|
|
@ -207,22 +207,22 @@ Memory.idBlock = 0;
|
|||
* @param {number} dw
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.adjustEndian = function(dw) {
|
||||
Memory8080.adjustEndian = function(dw) {
|
||||
if (TYPEDARRAYS && !littleEndian) {
|
||||
dw = (dw << 24) | ((dw << 8) & 0x00ff0000) | ((dw >> 8) & 0x0000ff00) | (dw >>> 24);
|
||||
}
|
||||
return dw;
|
||||
};
|
||||
|
||||
Memory.prototype = {
|
||||
constructor: Memory,
|
||||
Memory8080.prototype = {
|
||||
constructor: Memory8080,
|
||||
parent: null,
|
||||
/**
|
||||
* init(addr)
|
||||
*
|
||||
* Quick reinitializer when reusing a Memory block.
|
||||
* Quick reinitializer when reusing a Memory8080 block.
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} addr
|
||||
*/
|
||||
init: function(addr) {
|
||||
|
|
@ -231,13 +231,13 @@ Memory.prototype = {
|
|||
/**
|
||||
* clone(mem, type)
|
||||
*
|
||||
* Converts the current Memory block (this) into a clone of the given Memory block (mem),
|
||||
* Converts the current Memory8080 block (this) into a clone of the given Memory8080 block (mem),
|
||||
* and optionally overrides the current block's type with the specified type.
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {Memory} mem
|
||||
* @this {Memory8080}
|
||||
* @param {Memory8080} mem
|
||||
* @param {number} [type]
|
||||
* @param {Debugger} [dbg]
|
||||
* @param {Debugger8080} [dbg]
|
||||
*/
|
||||
clone: function(mem, type, dbg) {
|
||||
/*
|
||||
|
|
@ -250,7 +250,7 @@ Memory.prototype = {
|
|||
this.size = mem.size;
|
||||
if (type) {
|
||||
this.type = type;
|
||||
this.fReadOnly = (type == Memory.TYPE.ROM);
|
||||
this.fReadOnly = (type == Memory8080.TYPE.ROM);
|
||||
}
|
||||
if (TYPEDARRAYS) {
|
||||
this.buffer = mem.buffer;
|
||||
|
|
@ -258,27 +258,27 @@ Memory.prototype = {
|
|||
this.ab = mem.ab;
|
||||
this.aw = mem.aw;
|
||||
this.adw = mem.adw;
|
||||
this.setAccess(littleEndian? Memory.afnArrayLE : Memory.afnArrayBE);
|
||||
this.setAccess(littleEndian? Memory8080.afnArrayLE : Memory8080.afnArrayBE);
|
||||
} else {
|
||||
if (BYTEARRAYS) {
|
||||
this.ab = mem.ab;
|
||||
} else {
|
||||
this.adw = mem.adw;
|
||||
}
|
||||
this.setAccess(Memory.afnMemory);
|
||||
this.setAccess(Memory8080.afnMemory);
|
||||
}
|
||||
this.copyBreakpoints(dbg, mem);
|
||||
},
|
||||
/**
|
||||
* save()
|
||||
*
|
||||
* This gets the contents of a Memory block as an array of 32-bit values; used by Bus.saveMemory(),
|
||||
* This gets the contents of a Memory8080 block as an array of 32-bit values; used by Bus8080.saveMemory(),
|
||||
* which in turn is called by CPUState.save().
|
||||
*
|
||||
* Memory blocks with custom memory controllers do NOT save their contents; that's the responsibility
|
||||
* Memory8080 blocks with custom memory controllers do NOT save their contents; that's the responsibility
|
||||
* of the controller component.
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @return {Array|Int32Array|null}
|
||||
*/
|
||||
save: function() {
|
||||
|
|
@ -315,12 +315,12 @@ Memory.prototype = {
|
|||
/**
|
||||
* restore(adw)
|
||||
*
|
||||
* This restores the contents of a Memory block from an array of 32-bit values;
|
||||
* used by Bus.restoreMemory(), which is called by CPUState.restore(), after all other
|
||||
* components have been restored and thus all Memory blocks have been allocated
|
||||
* This restores the contents of a Memory8080 block from an array of 32-bit values;
|
||||
* used by Bus8080.restoreMemory(), which is called by CPUState.restore(), after all other
|
||||
* components have been restored and thus all Memory8080 blocks have been allocated
|
||||
* by their respective components.
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {Array|null} adw
|
||||
* @return {boolean} true if successful, false if block size mismatch
|
||||
*/
|
||||
|
|
@ -360,16 +360,16 @@ Memory.prototype = {
|
|||
/**
|
||||
* setAccess(afn, fDirect)
|
||||
*
|
||||
* If no function table is specified, a default is selected based on the Memory type.
|
||||
* If no function table is specified, a default is selected based on the Memory8080 type.
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {Array.<function()>} [afn] function table
|
||||
* @param {boolean} [fDirect] (true to update direct access functions as well; default is true)
|
||||
*/
|
||||
setAccess: function(afn, fDirect) {
|
||||
if (!afn) {
|
||||
Component.assert(this.type == Memory.TYPE.NONE);
|
||||
afn = Memory.afnNone;
|
||||
Component.assert(this.type == Memory8080.TYPE.NONE);
|
||||
afn = Memory8080.afnNone;
|
||||
}
|
||||
this.setReadAccess(afn, fDirect);
|
||||
this.setWriteAccess(afn, fDirect);
|
||||
|
|
@ -377,7 +377,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* setReadAccess(afn, fDirect)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {Array.<function()>} afn
|
||||
* @param {boolean} [fDirect]
|
||||
*/
|
||||
|
|
@ -394,7 +394,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* setWriteAccess(afn, fDirect)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {Array.<function()>} afn
|
||||
* @param {boolean} [fDirect]
|
||||
*/
|
||||
|
|
@ -411,7 +411,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* resetReadAccess()
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
*/
|
||||
resetReadAccess: function() {
|
||||
this.readByte = this.readByteDirect;
|
||||
|
|
@ -420,7 +420,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* resetWriteAccess()
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
*/
|
||||
resetWriteAccess: function() {
|
||||
this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;
|
||||
|
|
@ -429,31 +429,31 @@ Memory.prototype = {
|
|||
/**
|
||||
* printAddr(sMessage)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {string} sMessage
|
||||
*/
|
||||
printAddr: function(sMessage) {
|
||||
if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {
|
||||
if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages8080.MEM)) {
|
||||
this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('%' + str.toHex(this.addr)) : '#' + this.id), true);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* addBreakpoint(off, fWrite)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {boolean} fWrite
|
||||
*/
|
||||
addBreakpoint: function(off, fWrite) {
|
||||
if (!fWrite) {
|
||||
if (this.cReadBreakpoints++ === 0) {
|
||||
this.setReadAccess(Memory.afnChecked, false);
|
||||
this.setReadAccess(Memory8080.afnChecked, false);
|
||||
}
|
||||
if (DEBUG) this.printAddr("read breakpoint added to memory block");
|
||||
}
|
||||
else {
|
||||
if (this.cWriteBreakpoints++ === 0) {
|
||||
this.setWriteAccess(Memory.afnChecked, false);
|
||||
this.setWriteAccess(Memory8080.afnChecked, false);
|
||||
}
|
||||
if (DEBUG) this.printAddr("write breakpoint added to memory block");
|
||||
}
|
||||
|
|
@ -461,7 +461,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* removeBreakpoint(off, fWrite)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {boolean} fWrite
|
||||
*/
|
||||
|
|
@ -484,19 +484,19 @@ Memory.prototype = {
|
|||
/**
|
||||
* copyBreakpoints(dbg, mem)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {Debugger} [dbg]
|
||||
* @param {Memory} [mem] (outgoing Memory block to copy breakpoints from, if any)
|
||||
* @this {Memory8080}
|
||||
* @param {Debugger8080} [dbg]
|
||||
* @param {Memory8080} [mem] (outgoing Memory8080 block to copy breakpoints from, if any)
|
||||
*/
|
||||
copyBreakpoints: function(dbg, mem) {
|
||||
this.dbg = dbg;
|
||||
this.cReadBreakpoints = this.cWriteBreakpoints = 0;
|
||||
if (mem) {
|
||||
if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {
|
||||
this.setReadAccess(Memory.afnChecked, false);
|
||||
this.setReadAccess(Memory8080.afnChecked, false);
|
||||
}
|
||||
if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {
|
||||
this.setWriteAccess(Memory.afnChecked, false);
|
||||
this.setWriteAccess(Memory8080.afnChecked, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -513,15 +513,15 @@ Memory.prototype = {
|
|||
* that a system would require nonexistent memory locations to return ALL bits set.
|
||||
*
|
||||
* Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above
|
||||
* Memory interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.
|
||||
* Memory8080 interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
*/
|
||||
readNone: function readNone(off, addr) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages8080.CPU | Messages8080.MEM) /* && !off */) {
|
||||
this.dbg.message("attempt to read invalid block %" + str.toHex(this.addr), true);
|
||||
}
|
||||
return 0xff;
|
||||
|
|
@ -529,20 +529,20 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeNone(off, v, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)
|
||||
* @param {number} addr
|
||||
*/
|
||||
writeNone: function writeNone(off, v, addr) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages8080.CPU | Messages8080.MEM) /* && !off */) {
|
||||
this.dbg.message("attempt to write " + str.toHexWord(v) + " to invalid block %" + str.toHex(this.addr), true);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* readShortDefault(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -553,7 +553,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeShortDefault(off, w, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} w
|
||||
* @param {number} addr
|
||||
|
|
@ -565,7 +565,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readByteMemory(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -579,7 +579,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readShortMemory(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -602,7 +602,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeByteMemory(off, b, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} b
|
||||
* @param {number} addr
|
||||
|
|
@ -620,7 +620,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeShortMemory(off, w, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} w
|
||||
* @param {number} addr
|
||||
|
|
@ -645,7 +645,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readByteChecked(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -659,7 +659,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readShortChecked(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -673,7 +673,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeByteChecked(off, b, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @param {number} b
|
||||
|
|
@ -687,7 +687,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeShortChecked(off, w, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @param {number} w
|
||||
|
|
@ -701,7 +701,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readByteBE(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -712,7 +712,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readByteLE(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -723,7 +723,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readShortBE(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -734,7 +734,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* readShortLE(off, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @return {number}
|
||||
|
|
@ -749,7 +749,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeByteBE(off, b, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} b
|
||||
* @param {number} addr
|
||||
|
|
@ -761,7 +761,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeByteLE(off, b, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @param {number} b
|
||||
|
|
@ -773,7 +773,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeShortBE(off, w, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @param {number} w
|
||||
|
|
@ -785,7 +785,7 @@ Memory.prototype = {
|
|||
/**
|
||||
* writeShortLE(off, w, addr)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @this {Memory8080}
|
||||
* @param {number} off
|
||||
* @param {number} addr
|
||||
* @param {number} w
|
||||
|
|
@ -809,16 +809,16 @@ Memory.prototype = {
|
|||
* This is the effective definition of afnNone, but we need not fully define it, because setAccess()
|
||||
* uses these defaults when any of the 6 handlers (ie, 3 read handlers and 3 write handlers) are undefined.
|
||||
*
|
||||
Memory.afnNone = [Memory.prototype.readNone, Memory.prototype.readShortDefault, Memory.prototype.writeNone, Memory.prototype.writeShortDefault];
|
||||
Memory8080.afnNone = [Memory8080.prototype.readNone, Memory8080.prototype.readShortDefault, Memory8080.prototype.writeNone, Memory8080.prototype.writeShortDefault];
|
||||
*/
|
||||
|
||||
Memory.afnNone = [];
|
||||
Memory.afnMemory = [Memory.prototype.readByteMemory, Memory.prototype.readShortMemory, Memory.prototype.writeByteMemory, Memory.prototype.writeShortMemory];
|
||||
Memory.afnChecked = [Memory.prototype.readByteChecked, Memory.prototype.readShortChecked, Memory.prototype.writeByteChecked, Memory.prototype.writeShortChecked];
|
||||
Memory8080.afnNone = [];
|
||||
Memory8080.afnMemory = [Memory8080.prototype.readByteMemory, Memory8080.prototype.readShortMemory, Memory8080.prototype.writeByteMemory, Memory8080.prototype.writeShortMemory];
|
||||
Memory8080.afnChecked = [Memory8080.prototype.readByteChecked, Memory8080.prototype.readShortChecked, Memory8080.prototype.writeByteChecked, Memory8080.prototype.writeShortChecked];
|
||||
|
||||
if (TYPEDARRAYS) {
|
||||
Memory.afnArrayBE = [Memory.prototype.readByteBE, Memory.prototype.readShortBE, Memory.prototype.writeByteBE, Memory.prototype.writeShortBE];
|
||||
Memory.afnArrayLE = [Memory.prototype.readByteLE, Memory.prototype.readShortLE, Memory.prototype.writeByteLE, Memory.prototype.writeShortLE];
|
||||
Memory8080.afnArrayBE = [Memory8080.prototype.readByteBE, Memory8080.prototype.readShortBE, Memory8080.prototype.writeByteBE, Memory8080.prototype.writeShortBE];
|
||||
Memory8080.afnArrayLE = [Memory8080.prototype.readByteLE, Memory8080.prototype.readShortLE, Memory8080.prototype.writeByteLE, Memory8080.prototype.writeShortLE];
|
||||
}
|
||||
|
||||
if (NODE) module.exports = Memory;
|
||||
if (NODE) module.exports = Memory8080;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Messages = {
|
||||
var Messages8080 = {
|
||||
CPU: 0x00000001,
|
||||
BUS: 0x00000040,
|
||||
MEM: 0x00000080,
|
||||
|
|
@ -51,4 +51,4 @@ var Messages = {
|
|||
HALT: 0x80000000|0
|
||||
};
|
||||
|
||||
if (NODE) module.exports = Messages;
|
||||
if (NODE) module.exports = Messages8080;
|
||||
|
|
|
|||
|
|
@ -36,26 +36,26 @@ if (NODE) {
|
|||
var usr = require("../../shared/lib/usrlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Bus = require("./bus");
|
||||
var Memory = require("./memory");
|
||||
var CPUDef = require("./cpudef");
|
||||
var Bus8080 = require("./bus");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var Memory8080 = require("./memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Panel(parmsPanel)
|
||||
* Panel8080(parmsPanel)
|
||||
*
|
||||
* The Panel component has no required (parmsPanel) properties.
|
||||
* The Panel8080 component has no required (parmsPanel) properties.
|
||||
*
|
||||
* @constructor
|
||||
* @extends Component
|
||||
* @param {Object} parmsPanel
|
||||
*/
|
||||
function Panel(parmsPanel)
|
||||
function Panel8080(parmsPanel)
|
||||
{
|
||||
Component.call(this, "Panel", parmsPanel, Panel);
|
||||
Component.call(this, "Panel", parmsPanel, Panel8080);
|
||||
}
|
||||
|
||||
Component.subclass(Panel);
|
||||
Component.subclass(Panel8080);
|
||||
|
||||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
|
|
@ -64,14 +64,14 @@ Component.subclass(Panel);
|
|||
* Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any component
|
||||
* that doesn't recognize the specified binding should simply ignore it.
|
||||
*
|
||||
* @this {Panel}
|
||||
* @this {Panel8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
Panel.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
Panel8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;
|
||||
if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;
|
||||
|
|
@ -83,44 +83,44 @@ Panel.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {Panel8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
Panel.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
Panel8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
this.kbd = /** @type {Keyboard} */ (cmp.getMachineComponent("Keyboard"));
|
||||
this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent("Keyboard"));
|
||||
};
|
||||
|
||||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @this {Panel8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
Panel.prototype.powerUp = function(data, fRepower)
|
||||
Panel8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) Panel.init();
|
||||
if (!fRepower) Panel8080.init();
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @this {Panel8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
Panel.prototype.powerDown = function(fSave, fShutdown)
|
||||
Panel8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
|
@ -135,19 +135,19 @@ Panel.prototype.powerDown = function(fSave, fShutdown)
|
|||
*
|
||||
* The Computer's updateStatus() handler is currently responsible for calling both our handler and the CPU's handler.
|
||||
*
|
||||
* @this {Panel}
|
||||
* @this {Panel8080}
|
||||
* @param {boolean} [fForce] (true will display registers even if the CPU is running and "live" registers are not enabled)
|
||||
*/
|
||||
Panel.prototype.updateStatus = function(fForce)
|
||||
Panel8080.prototype.updateStatus = function(fForce)
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* Panel.init()
|
||||
* Panel8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "panel", extracting the
|
||||
* JSON-encoded parameters for the Panel constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a Panel component, and then binding
|
||||
* JSON-encoded parameters for the Panel8080 constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a Panel8080 component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*
|
||||
* NOTE: Unlike most other component init() functions, this one is designed to be
|
||||
|
|
@ -159,7 +159,7 @@ Panel.prototype.updateStatus = function(fForce)
|
|||
* that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they
|
||||
* might want to use.
|
||||
*/
|
||||
Panel.init = function()
|
||||
Panel8080.init = function()
|
||||
{
|
||||
var fReady = false;
|
||||
var aePanels = Component.getElementsByClass(document, PC8080.APPCLASS, "panel");
|
||||
|
|
@ -169,7 +169,7 @@ Panel.init = function()
|
|||
var panel = Component.getComponentByID(parmsPanel['id']);
|
||||
if (!panel) {
|
||||
fReady = true;
|
||||
panel = new Panel(parmsPanel);
|
||||
panel = new Panel8080(parmsPanel);
|
||||
}
|
||||
Component.bindComponentControls(panel, ePanel, PC8080.APPCLASS);
|
||||
if (fReady) panel.setReady();
|
||||
|
|
@ -179,6 +179,6 @@ Panel.init = function()
|
|||
/*
|
||||
* Initialize every Panel module on the page.
|
||||
*/
|
||||
web.onInit(Panel.init);
|
||||
web.onInit(Panel8080.init);
|
||||
|
||||
if (NODE) module.exports = Panel;
|
||||
if (NODE) module.exports = Panel8080;
|
||||
|
|
|
|||
|
|
@ -35,15 +35,15 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Memory = require("./memory");
|
||||
var ROM = require("./rom");
|
||||
var State = require("./state");
|
||||
var Memory8080 = require("./memory");
|
||||
var ROM8080 = require("./rom");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
* RAM(parmsRAM)
|
||||
* RAM8080(parmsRAM)
|
||||
*
|
||||
* The RAM component expects the following (parmsRAM) properties:
|
||||
* The RAM8080 component expects the following (parmsRAM) properties:
|
||||
*
|
||||
* addr: starting physical address of RAM (default is 0)
|
||||
* size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)
|
||||
|
|
@ -55,9 +55,9 @@ if (NODE) {
|
|||
* @extends Component
|
||||
* @param {Object} parmsRAM
|
||||
*/
|
||||
function RAM(parmsRAM)
|
||||
function RAM8080(parmsRAM)
|
||||
{
|
||||
Component.call(this, "RAM", parmsRAM, RAM);
|
||||
Component.call(this, "RAM", parmsRAM, RAM8080);
|
||||
|
||||
this.addrRAM = parmsRAM['addr'];
|
||||
this.sizeRAM = parmsRAM['size'];
|
||||
|
|
@ -65,18 +65,18 @@ function RAM(parmsRAM)
|
|||
this.fAllocated = false;
|
||||
}
|
||||
|
||||
Component.subclass(RAM);
|
||||
Component.subclass(RAM8080);
|
||||
|
||||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {RAM}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {RAM8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
RAM.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
RAM8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
|
|
@ -87,12 +87,12 @@ RAM.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {RAM}
|
||||
* @this {RAM8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
RAM.prototype.powerUp = function(data, fRepower)
|
||||
RAM8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) {
|
||||
/*
|
||||
|
|
@ -109,12 +109,12 @@ RAM.prototype.powerUp = function(data, fRepower)
|
|||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {RAM}
|
||||
* @this {RAM8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
RAM.prototype.powerDown = function(fSave, fShutdown)
|
||||
RAM8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
/*
|
||||
* The Computer powers down the CPU first, at which point CPUState state is saved,
|
||||
|
|
@ -128,12 +128,12 @@ RAM.prototype.powerDown = function(fSave, fShutdown)
|
|||
/**
|
||||
* reset()
|
||||
*
|
||||
* @this {RAM}
|
||||
* @this {RAM8080}
|
||||
*/
|
||||
RAM.prototype.reset = function()
|
||||
RAM8080.prototype.reset = function()
|
||||
{
|
||||
if (!this.fAllocated && this.sizeRAM) {
|
||||
if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory.TYPE.RAM)) {
|
||||
if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory8080.TYPE.RAM)) {
|
||||
this.fAllocated = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -145,12 +145,12 @@ RAM.prototype.reset = function()
|
|||
/**
|
||||
* save()
|
||||
*
|
||||
* This implements save support for the RAM component.
|
||||
* This implements save support for the RAM8080 component.
|
||||
*
|
||||
* @this {RAM}
|
||||
* @this {RAM8080}
|
||||
* @return {Object}
|
||||
*/
|
||||
RAM.prototype.save = function()
|
||||
RAM8080.prototype.save = function()
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
|
@ -158,39 +158,39 @@ RAM.prototype.save = function()
|
|||
/**
|
||||
* restore(data)
|
||||
*
|
||||
* This implements restore support for the RAM component.
|
||||
* This implements restore support for the RAM8080 component.
|
||||
*
|
||||
* @this {RAM}
|
||||
* @this {RAM8080}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
RAM.prototype.restore = function(data)
|
||||
RAM8080.prototype.restore = function(data)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* RAM.init()
|
||||
* RAM8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "ram", extracting the
|
||||
* JSON-encoded parameters for the RAM constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a RAM component, and then binding
|
||||
* JSON-encoded parameters for the RAM8080 constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a RAM8080 component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*/
|
||||
RAM.init = function()
|
||||
RAM8080.init = function()
|
||||
{
|
||||
var aeRAM = Component.getElementsByClass(document, PC8080.APPCLASS, "ram");
|
||||
for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {
|
||||
var eRAM = aeRAM[iRAM];
|
||||
var parmsRAM = Component.getComponentParms(eRAM);
|
||||
var ram = new RAM(parmsRAM);
|
||||
var ram = new RAM8080(parmsRAM);
|
||||
Component.bindComponentControls(ram, eRAM, PC8080.APPCLASS);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize all the RAM modules on the page.
|
||||
* Initialize all the RAM8080 modules on the page.
|
||||
*/
|
||||
web.onInit(RAM.init);
|
||||
web.onInit(RAM8080.init);
|
||||
|
||||
if (NODE) module.exports = RAM;
|
||||
if (NODE) module.exports = RAM8080;
|
||||
|
|
|
|||
|
|
@ -36,14 +36,14 @@ if (NODE) {
|
|||
var web = require("../../shared/lib/weblib");
|
||||
var DumpAPI = require("../../shared/lib/dumpapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Memory = require("./memory");
|
||||
var CPUDef = require("./cpudef");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var Memory8080 = require("./memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* ROM(parmsROM)
|
||||
* ROM8080(parmsROM)
|
||||
*
|
||||
* The ROM component expects the following (parmsROM) properties:
|
||||
* The ROM8080 component expects the following (parmsROM) properties:
|
||||
*
|
||||
* addr: physical address of ROM
|
||||
* size: amount of ROM, in bytes
|
||||
|
|
@ -68,9 +68,9 @@ if (NODE) {
|
|||
* @extends Component
|
||||
* @param {Object} parmsROM
|
||||
*/
|
||||
function ROM(parmsROM)
|
||||
function ROM8080(parmsROM)
|
||||
{
|
||||
Component.call(this, "ROM", parmsROM, ROM);
|
||||
Component.call(this, "ROM", parmsROM, ROM8080);
|
||||
|
||||
this.abROM = null;
|
||||
this.addrROM = parmsROM['addr'];
|
||||
|
|
@ -112,9 +112,9 @@ function ROM(parmsROM)
|
|||
}
|
||||
}
|
||||
|
||||
Component.subclass(ROM);
|
||||
Component.subclass(ROM8080);
|
||||
|
||||
ROM.CPM = {
|
||||
ROM8080.CPM = {
|
||||
BIOS: {
|
||||
VECTOR: 0x0000
|
||||
},
|
||||
|
|
@ -136,7 +136,7 @@ ROM.CPM = {
|
|||
}
|
||||
};
|
||||
|
||||
ROM.CPM.VECTORS = [ROM.CPM.BIOS.VECTOR, ROM.CPM.BDOS.VECTOR];
|
||||
ROM8080.CPM.VECTORS = [ROM8080.CPM.BIOS.VECTOR, ROM8080.CPM.BDOS.VECTOR];
|
||||
|
||||
/*
|
||||
* NOTE: There's currently no need for this component to have a reset() function, since
|
||||
|
|
@ -154,13 +154,13 @@ ROM.CPM.VECTORS = [ROM.CPM.BIOS.VECTOR, ROM.CPM.BDOS.VECTOR];
|
|||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {ROM8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
ROM.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
ROM8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
|
|
@ -171,12 +171,12 @@ ROM.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
ROM.prototype.powerUp = function(data, fRepower)
|
||||
ROM8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (this.aSymbols) {
|
||||
if (this.dbg) {
|
||||
|
|
@ -199,12 +199,12 @@ ROM.prototype.powerUp = function(data, fRepower)
|
|||
* useful down the road, like user-defined symbols (ie, symbols that the Debugger may have
|
||||
* created, above and beyond those symbols we automatically loaded, if any, along with the ROM).
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
ROM.prototype.powerDown = function(fSave, fShutdown)
|
||||
ROM8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
|
@ -212,12 +212,12 @@ ROM.prototype.powerDown = function(fSave, fShutdown)
|
|||
/**
|
||||
* doneLoad(sURL, sROMData, nErrorCode)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {string} sURL
|
||||
* @param {string} sROMData
|
||||
* @param {number} nErrorCode (response from server if anything other than 200)
|
||||
*/
|
||||
ROM.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
||||
ROM8080.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
||||
{
|
||||
if (nErrorCode) {
|
||||
this.notice("Unable to load system ROM (error " + nErrorCode + ": " + sURL + ")");
|
||||
|
|
@ -291,9 +291,9 @@ ROM.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
|||
* until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both
|
||||
* those criteria are satisfied, the component becomes "ready".
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
*/
|
||||
ROM.prototype.copyROM = function()
|
||||
ROM8080.prototype.copyROM = function()
|
||||
{
|
||||
if (!this.isReady()) {
|
||||
if (!this.sFilePath) {
|
||||
|
|
@ -346,13 +346,13 @@ ROM.prototype.copyROM = function()
|
|||
/**
|
||||
* addROM(addr)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {number} addr
|
||||
* @return {boolean}
|
||||
*/
|
||||
ROM.prototype.addROM = function(addr)
|
||||
ROM8080.prototype.addROM = function(addr)
|
||||
{
|
||||
if (this.bus.addMemory(addr, this.sizeROM, this.fWritable? Memory.TYPE.RAM : Memory.TYPE.ROM)) {
|
||||
if (this.bus.addMemory(addr, this.sizeROM, this.fWritable? Memory8080.TYPE.RAM : Memory8080.TYPE.ROM)) {
|
||||
if (DEBUG) this.log("addROM(): copying ROM to " + str.toHexLong(addr) + " (" + str.toHexLong(this.abROM.length) + " bytes)");
|
||||
var i;
|
||||
for (i = 0; i < this.abROM.length; i++) {
|
||||
|
|
@ -365,8 +365,8 @@ ROM.prototype.addROM = function(addr)
|
|||
* (namely, 0x0000, which is the CP/M reset vector, and 0x0005, which is the CP/M system call vector) and
|
||||
* then telling the CPU to call us whenever a HLT occurs, so we can check PC for one of these addresses.
|
||||
*/
|
||||
for (i = 0; i < ROM.CPM.VECTORS.length; i++) {
|
||||
this.bus.setByteDirect(ROM.CPM.VECTORS[i], CPUDef.OPCODE.HLT);
|
||||
for (i = 0; i < ROM8080.CPM.VECTORS.length; i++) {
|
||||
this.bus.setByteDirect(ROM8080.CPM.VECTORS[i], CPUDef8080.OPCODE.HLT);
|
||||
}
|
||||
|
||||
this.cpu.addHaltCheck(function(rom) {
|
||||
|
|
@ -388,24 +388,24 @@ ROM.prototype.addROM = function(addr)
|
|||
/**
|
||||
* checkCPMVector(addr)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {number} addr (of the HLT opcode)
|
||||
* @return {boolean} true if special processing performed, false if not
|
||||
*/
|
||||
ROM.prototype.checkCPMVector = function(addr)
|
||||
ROM8080.prototype.checkCPMVector = function(addr)
|
||||
{
|
||||
var i = ROM.CPM.VECTORS.indexOf(addr);
|
||||
var i = ROM8080.CPM.VECTORS.indexOf(addr);
|
||||
if (i >= 0) {
|
||||
var fCPM = false;
|
||||
var cpu = this.cpu;
|
||||
var dbg = this.dbg;
|
||||
if (addr == ROM.CPM.BDOS.VECTOR) {
|
||||
if (addr == ROM8080.CPM.BDOS.VECTOR) {
|
||||
fCPM = true;
|
||||
switch(cpu.regC) {
|
||||
case ROM.CPM.BDOS.FUNC.CON_WRITE:
|
||||
case ROM8080.CPM.BDOS.FUNC.CON_WRITE:
|
||||
this.writeCPMString(this.getCPMChar(cpu.regE));
|
||||
break;
|
||||
case ROM.CPM.BDOS.FUNC.STR_WRITE:
|
||||
case ROM8080.CPM.BDOS.FUNC.STR_WRITE:
|
||||
this.writeCPMString(this.getCPMString(cpu.getDE(), '$'));
|
||||
break;
|
||||
default:
|
||||
|
|
@ -414,7 +414,7 @@ ROM.prototype.checkCPMVector = function(addr)
|
|||
}
|
||||
}
|
||||
if (fCPM) {
|
||||
CPUDef.opRET.call(cpu); // for recognized calls, automatically return
|
||||
CPUDef8080.opRET.call(cpu); // for recognized calls, automatically return
|
||||
}
|
||||
else if (dbg) {
|
||||
this.println("\nCP/M vector " + str.toHexWord(addr));
|
||||
|
|
@ -430,11 +430,11 @@ ROM.prototype.checkCPMVector = function(addr)
|
|||
/**
|
||||
* getCPMChar(ch)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {number} ch
|
||||
* @return {string}
|
||||
*/
|
||||
ROM.prototype.getCPMChar = function(ch)
|
||||
ROM8080.prototype.getCPMChar = function(ch)
|
||||
{
|
||||
return String.fromCharCode(ch);
|
||||
};
|
||||
|
|
@ -442,12 +442,12 @@ ROM.prototype.getCPMChar = function(ch)
|
|||
/**
|
||||
* getCPMString(addr, chEnd)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {number} addr (of a string)
|
||||
* @param {string|number} [chEnd] (terminating character, default is 0)
|
||||
* @return {string}
|
||||
*/
|
||||
ROM.prototype.getCPMString = function(addr, chEnd)
|
||||
ROM8080.prototype.getCPMString = function(addr, chEnd)
|
||||
{
|
||||
var s = "";
|
||||
var cchMax = 255;
|
||||
|
|
@ -463,10 +463,10 @@ ROM.prototype.getCPMString = function(addr, chEnd)
|
|||
/**
|
||||
* writeCPMString(s)
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {string} s
|
||||
*/
|
||||
ROM.prototype.writeCPMString = function(s)
|
||||
ROM8080.prototype.writeCPMString = function(s)
|
||||
{
|
||||
s = s.replace(/\r/g, '');
|
||||
if (this.controlPrint) {
|
||||
|
|
@ -485,37 +485,37 @@ ROM.prototype.writeCPMString = function(s)
|
|||
* Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods
|
||||
* to manually get and set the blocks of any memory range, it is now possible to create true aliases.
|
||||
*
|
||||
* @this {ROM}
|
||||
* @this {ROM8080}
|
||||
* @param {number} addr
|
||||
*/
|
||||
ROM.prototype.cloneROM = function(addr)
|
||||
ROM8080.prototype.cloneROM = function(addr)
|
||||
{
|
||||
var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);
|
||||
this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);
|
||||
};
|
||||
|
||||
/**
|
||||
* ROM.init()
|
||||
* ROM8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "rom", extracting the
|
||||
* JSON-encoded parameters for the ROM constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a ROM component, and then binding
|
||||
* JSON-encoded parameters for the ROM8080 constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a ROM8080 component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*/
|
||||
ROM.init = function()
|
||||
ROM8080.init = function()
|
||||
{
|
||||
var aeROM = Component.getElementsByClass(document, PC8080.APPCLASS, "rom");
|
||||
for (var iROM = 0; iROM < aeROM.length; iROM++) {
|
||||
var eROM = aeROM[iROM];
|
||||
var parmsROM = Component.getComponentParms(eROM);
|
||||
var rom = new ROM(parmsROM);
|
||||
var rom = new ROM8080(parmsROM);
|
||||
Component.bindComponentControls(rom, eROM, PC8080.APPCLASS);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize all the ROM modules on the page.
|
||||
* Initialize all the ROM8080 modules on the page.
|
||||
*/
|
||||
web.onInit(ROM.init);
|
||||
web.onInit(ROM8080.init);
|
||||
|
||||
if (NODE) module.exports = ROM;
|
||||
if (NODE) module.exports = ROM8080;
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
var State = require("./state");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
* SerialPort(parmsSerial)
|
||||
* SerialPort8080(parmsSerial)
|
||||
*
|
||||
* The SerialPort component has the following component-specific (parmsSerial) properties:
|
||||
* The SerialPort8080 component has the following component-specific (parmsSerial) properties:
|
||||
*
|
||||
* adapter: 0 if not defined
|
||||
*
|
||||
|
|
@ -62,7 +62,7 @@ if (NODE) {
|
|||
* @extends Component
|
||||
* @param {Object} parmsSerial
|
||||
*/
|
||||
function SerialPort(parmsSerial) {
|
||||
function SerialPort8080(parmsSerial) {
|
||||
|
||||
this.iAdapter = +parmsSerial['adapter'];
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ function SerialPort(parmsSerial) {
|
|||
this.charBOL = parmsSerial['charBOL'];
|
||||
this.iLogicalCol = 0;
|
||||
|
||||
Component.call(this, "SerialPort", parmsSerial, SerialPort, Messages.SERIAL);
|
||||
Component.call(this, "SerialPort", parmsSerial, SerialPort8080, Messages8080.SERIAL);
|
||||
|
||||
var sBinding = parmsSerial['binding'];
|
||||
if (sBinding == "console") {
|
||||
|
|
@ -112,7 +112,7 @@ function SerialPort(parmsSerial) {
|
|||
/*
|
||||
* NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.
|
||||
*/
|
||||
Component.bindExternalControl(this, sBinding, SerialPort.sIOBuffer);
|
||||
Component.bindExternalControl(this, sBinding, SerialPort8080.sIOBuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -130,7 +130,7 @@ function SerialPort(parmsSerial) {
|
|||
}
|
||||
|
||||
/*
|
||||
* class SerialPort
|
||||
* class SerialPort8080
|
||||
* property {number} iAdapter
|
||||
* property {number} portBase
|
||||
* property {number} nIRQ
|
||||
|
|
@ -146,9 +146,9 @@ function SerialPort(parmsSerial) {
|
|||
* for third-party apps.
|
||||
*/
|
||||
|
||||
Component.subclass(SerialPort);
|
||||
Component.subclass(SerialPort8080);
|
||||
|
||||
SerialPort.UART8251 = {
|
||||
SerialPort8080.UART8251 = {
|
||||
/*
|
||||
* Format of MODE byte written to CONTROL port 0x1
|
||||
*/
|
||||
|
|
@ -212,6 +212,8 @@ SerialPort.UART8251 = {
|
|||
* 0xD 36 4800
|
||||
* 0xE 18 9600 (default)
|
||||
* 0xF 9 19200
|
||||
*
|
||||
* NOTE: This is a VT100-specific port and baud rate table.
|
||||
*/
|
||||
BAUDRATES: {
|
||||
RECV_RATE: 0x0F,
|
||||
|
|
@ -223,20 +225,20 @@ SerialPort.UART8251 = {
|
|||
]
|
||||
};
|
||||
|
||||
SerialPort.UART8251.INIT = [
|
||||
SerialPort8080.UART8251.INIT = [
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
SerialPort.UART8251.STATUS.INIT,
|
||||
SerialPort.UART8251.MODE.INIT,
|
||||
SerialPort.UART8251.COMMAND.INIT,
|
||||
SerialPort.UART8251.BAUDRATES.INIT
|
||||
SerialPort8080.UART8251.STATUS.INIT,
|
||||
SerialPort8080.UART8251.MODE.INIT,
|
||||
SerialPort8080.UART8251.COMMAND.INIT,
|
||||
SerialPort8080.UART8251.BAUDRATES.INIT
|
||||
];
|
||||
|
||||
/*
|
||||
* Internal name used for the I/O buffer control, if any, that we bind to the SerialPort.
|
||||
* Internal name used for the I/O buffer control, if any, that we bind to a SerialPort8080.
|
||||
*
|
||||
* Alternatively, if SerialPort wants to use another component's control (eg, the Panel's
|
||||
* Alternatively, if SerialPort8080 wants to use another component's control (eg, the Panel's
|
||||
* "print" control), it can specify the name of that control with the 'binding' property.
|
||||
*
|
||||
* For that binding to succeed, we also need to know the target component; for now, that's
|
||||
|
|
@ -244,24 +246,24 @@ SerialPort.UART8251.INIT = [
|
|||
* upon initializing before we do, but it would be a simple matter to include a component type
|
||||
* or ID as part of the 'binding' property as well, if we need more flexibility later.
|
||||
*/
|
||||
SerialPort.sIOBuffer = "buffer";
|
||||
SerialPort8080.sIOBuffer = "buffer";
|
||||
|
||||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "buffer")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
SerialPort8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
var serial = this;
|
||||
|
||||
switch (sBinding) {
|
||||
case SerialPort.sIOBuffer:
|
||||
case SerialPort8080.sIOBuffer:
|
||||
this.bindings[sBinding] = this.controlIOBuffer = control;
|
||||
|
||||
/*
|
||||
|
|
@ -368,13 +370,13 @@ SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {SerialPort8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
SerialPort.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
SerialPort8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.bus = bus;
|
||||
|
|
@ -389,10 +391,10 @@ SerialPort.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
serial.transmitData();
|
||||
});
|
||||
|
||||
this.chipset = /** @type {ChipSet} */ (cmp.getMachineComponent("ChipSet"));
|
||||
this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent("ChipSet"));
|
||||
|
||||
bus.addPortInputTable(this, SerialPort.aPortInput, this.portBase);
|
||||
bus.addPortOutputTable(this, SerialPort.aPortOutput, this.portBase);
|
||||
bus.addPortInputTable(this, SerialPort8080.aPortInput, this.portBase);
|
||||
bus.addPortOutputTable(this, SerialPort8080.aPortOutput, this.portBase);
|
||||
|
||||
this.initConnection();
|
||||
|
||||
|
|
@ -413,9 +415,9 @@ SerialPort.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
* performs its own initConnection(), it will find our receiveByte(b) function, at which point communication in both
|
||||
* directions should be established.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
*/
|
||||
SerialPort.prototype.initConnection = function()
|
||||
SerialPort8080.prototype.initConnection = function()
|
||||
{
|
||||
var sConnection = this.cmp.getMachineParm("connection");
|
||||
if (sConnection) {
|
||||
|
|
@ -439,12 +441,12 @@ SerialPort.prototype.initConnection = function()
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
SerialPort.prototype.powerUp = function(data, fRepower)
|
||||
SerialPort8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
if (!fRepower) {
|
||||
if (!data || !this.restore) {
|
||||
|
|
@ -459,12 +461,12 @@ SerialPort.prototype.powerUp = function(data, fRepower)
|
|||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
SerialPort.prototype.powerDown = function(fSave, fShutdown)
|
||||
SerialPort8080.prototype.powerDown = function(fSave, fShutdown)
|
||||
{
|
||||
return fSave? this.save() : true;
|
||||
};
|
||||
|
|
@ -472,9 +474,9 @@ SerialPort.prototype.powerDown = function(fSave, fShutdown)
|
|||
/**
|
||||
* reset()
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
*/
|
||||
SerialPort.prototype.reset = function()
|
||||
SerialPort8080.prototype.reset = function()
|
||||
{
|
||||
this.initState();
|
||||
};
|
||||
|
|
@ -482,12 +484,12 @@ SerialPort.prototype.reset = function()
|
|||
/**
|
||||
* save()
|
||||
*
|
||||
* This implements save support for the SerialPort component.
|
||||
* This implements save support for the SerialPort8080 component.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @return {Object}
|
||||
*/
|
||||
SerialPort.prototype.save = function()
|
||||
SerialPort8080.prototype.save = function()
|
||||
{
|
||||
var state = new State(this);
|
||||
state.set(0, this.saveRegisters());
|
||||
|
|
@ -497,13 +499,13 @@ SerialPort.prototype.save = function()
|
|||
/**
|
||||
* restore(data)
|
||||
*
|
||||
* This implements restore support for the SerialPort component.
|
||||
* This implements restore support for the SerialPort8080 component.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
SerialPort.prototype.restore = function(data)
|
||||
SerialPort8080.prototype.restore = function(data)
|
||||
{
|
||||
return this.initState(data[0]);
|
||||
};
|
||||
|
|
@ -511,15 +513,15 @@ SerialPort.prototype.restore = function(data)
|
|||
/**
|
||||
* initState(data)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {Array} [data]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
SerialPort.prototype.initState = function(data)
|
||||
SerialPort8080.prototype.initState = function(data)
|
||||
{
|
||||
var i = 0;
|
||||
if (data === undefined) {
|
||||
data = SerialPort.UART8251.INIT;
|
||||
data = SerialPort8080.UART8251.INIT;
|
||||
}
|
||||
this.fReady = data[i++];
|
||||
this.bDataIn = data[i++];
|
||||
|
|
@ -534,10 +536,10 @@ SerialPort.prototype.initState = function(data)
|
|||
/**
|
||||
* saveRegisters()
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @return {Array}
|
||||
*/
|
||||
SerialPort.prototype.saveRegisters = function()
|
||||
SerialPort8080.prototype.saveRegisters = function()
|
||||
{
|
||||
var i = 0;
|
||||
var data = [];
|
||||
|
|
@ -554,18 +556,18 @@ SerialPort.prototype.saveRegisters = function()
|
|||
/**
|
||||
* getBaudTimeout(maskRate)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @param {number} maskRate (either SerialPort.UART8251.BAUDRATES.RECV_RATE or SerialPort.UART8251.BAUDRATES.XMIT_RATE)
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} maskRate (either SerialPort8080.UART8251.BAUDRATES.RECV_RATE or SerialPort8080.UART8251.BAUDRATES.XMIT_RATE)
|
||||
* @return {number} (number of milliseconds per byte)
|
||||
*/
|
||||
SerialPort.prototype.getBaudTimeout = function(maskRate)
|
||||
SerialPort8080.prototype.getBaudTimeout = function(maskRate)
|
||||
{
|
||||
var indexRate = (this.bBaudRates & maskRate);
|
||||
if (!(maskRate & 0xf)) indexRate >>= 4;
|
||||
var nBaud = SerialPort.UART8251.BAUDTABLE[indexRate];
|
||||
var nBits = ((this.bMode & SerialPort.UART8251.MODE.DATA_BITS) >> 2) + 6; // includes an extra +1 for start bit
|
||||
if (this.bMode & SerialPort.UART8251.MODE.PARITY_ENABLE) nBits++;
|
||||
nBits += ((((this.bMode & SerialPort.UART8251.MODE.STOP_BITS) >> 6) + 1) >> 1);
|
||||
var nBaud = SerialPort8080.UART8251.BAUDTABLE[indexRate];
|
||||
var nBits = ((this.bMode & SerialPort8080.UART8251.MODE.DATA_BITS) >> 2) + 6; // includes an extra +1 for start bit
|
||||
if (this.bMode & SerialPort8080.UART8251.MODE.PARITY_ENABLE) nBits++;
|
||||
nBits += ((((this.bMode & SerialPort8080.UART8251.MODE.STOP_BITS) >> 6) + 1) >> 1);
|
||||
var nBytesPerSecond = Math.round(nBaud / nBits);
|
||||
return 1000 / nBytesPerSecond;
|
||||
};
|
||||
|
|
@ -573,16 +575,16 @@ SerialPort.prototype.getBaudTimeout = function(maskRate)
|
|||
/**
|
||||
* receiveByte(b)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
SerialPort.prototype.receiveByte = function(b)
|
||||
SerialPort8080.prototype.receiveByte = function(b)
|
||||
{
|
||||
this.printMessage("receiveByte(" + str.toHexByte(b) + "), status=" + str.toHexByte(this.bStatus));
|
||||
if (!(this.bStatus & SerialPort.UART8251.STATUS.RECV_FULL)) {
|
||||
if (!(this.bStatus & SerialPort8080.UART8251.STATUS.RECV_FULL)) {
|
||||
this.bDataIn = b;
|
||||
this.bStatus |= SerialPort.UART8251.STATUS.RECV_FULL;
|
||||
this.bStatus |= SerialPort8080.UART8251.STATUS.RECV_FULL;
|
||||
this.cpu.requestINTR(this.nIRQ);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -598,10 +600,10 @@ SerialPort.prototype.receiveByte = function(b)
|
|||
* of a string. When we're called by another component, data will typically be a number (ie, byte). If no
|
||||
* data is specified at all, then all we do is "clock" any remaining data into the receiver.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number|string|undefined} [data]
|
||||
*/
|
||||
SerialPort.prototype.receiveData = function(data)
|
||||
SerialPort8080.prototype.receiveData = function(data)
|
||||
{
|
||||
if (data != null) {
|
||||
if (typeof data != "number") {
|
||||
|
|
@ -615,7 +617,7 @@ SerialPort.prototype.receiveData = function(data)
|
|||
this.sDataReceived = this.sDataReceived.substr(1);
|
||||
}
|
||||
if (this.sDataReceived && this.cpu) {
|
||||
this.cpu.setTimer(this.timerReceiveNext, this.getBaudTimeout(SerialPort.UART8251.BAUDRATES.RECV_RATE));
|
||||
this.cpu.setTimer(this.timerReceiveNext, this.getBaudTimeout(SerialPort8080.UART8251.BAUDRATES.RECV_RATE));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -623,11 +625,11 @@ SerialPort.prototype.receiveData = function(data)
|
|||
/**
|
||||
* transmitByte(b)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} b
|
||||
* @return {boolean} true if transmitted, false if not
|
||||
*/
|
||||
SerialPort.prototype.transmitByte = function(b)
|
||||
SerialPort8080.prototype.transmitByte = function(b)
|
||||
{
|
||||
var fTransmitted = false;
|
||||
|
||||
|
|
@ -688,51 +690,51 @@ SerialPort.prototype.transmitByte = function(b)
|
|||
* When timerTransmitNext fires, we have honored the programmed XMIT_RATE period, so we can
|
||||
* set XMIT_READY (and XMIT_EMPTY), which signals the firmware that another byte can be transmitted.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
*/
|
||||
SerialPort.prototype.transmitData = function()
|
||||
SerialPort8080.prototype.transmitData = function()
|
||||
{
|
||||
this.bStatus |= (SerialPort.UART8251.STATUS.XMIT_READY | SerialPort.UART8251.STATUS.XMIT_EMPTY);
|
||||
this.bStatus |= (SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);
|
||||
};
|
||||
|
||||
/**
|
||||
* isTransmitterReady()
|
||||
*
|
||||
* Called whenever a ChipSet circuit needs the SerialPort UART's transmitter status.
|
||||
* Called whenever a ChipSet circuit needs the SerialPort8080 UART's transmitter status.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @return {boolean} (true if ready, false if not)
|
||||
*/
|
||||
SerialPort.prototype.isTransmitterReady = function()
|
||||
SerialPort8080.prototype.isTransmitterReady = function()
|
||||
{
|
||||
return !!(this.bStatus & SerialPort.UART8251.STATUS.XMIT_READY);
|
||||
return !!(this.bStatus & SerialPort8080.UART8251.STATUS.XMIT_READY);
|
||||
};
|
||||
|
||||
/**
|
||||
* inData(port, addrFrom)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} port (0x0)
|
||||
* @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
SerialPort.prototype.inData = function(port, addrFrom)
|
||||
SerialPort8080.prototype.inData = function(port, addrFrom)
|
||||
{
|
||||
var b = this.bDataIn;
|
||||
this.printMessageIO(port, null, addrFrom, "DATA", b);
|
||||
this.bStatus &= ~SerialPort.UART8251.STATUS.RECV_FULL;
|
||||
this.bStatus &= ~SerialPort8080.UART8251.STATUS.RECV_FULL;
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* inControl(port, addrFrom)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} port (0x1)
|
||||
* @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)
|
||||
* @return {number} simulated port value
|
||||
*/
|
||||
SerialPort.prototype.inControl = function(port, addrFrom)
|
||||
SerialPort8080.prototype.inControl = function(port, addrFrom)
|
||||
{
|
||||
var b = this.bStatus;
|
||||
this.printMessageIO(port, null, addrFrom, "STATUS", b);
|
||||
|
|
@ -742,22 +744,22 @@ SerialPort.prototype.inControl = function(port, addrFrom)
|
|||
/**
|
||||
* outData(port, bOut, addrFrom)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} port (0x0)
|
||||
* @param {number} bOut
|
||||
* @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)
|
||||
*/
|
||||
SerialPort.prototype.outData = function(port, bOut, addrFrom)
|
||||
SerialPort8080.prototype.outData = function(port, bOut, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, bOut, addrFrom, "DATA");
|
||||
this.bDataOut = bOut;
|
||||
this.bStatus &= ~(SerialPort.UART8251.STATUS.XMIT_READY | SerialPort.UART8251.STATUS.XMIT_EMPTY);
|
||||
this.bStatus &= ~(SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);
|
||||
/*
|
||||
* If we're transmitting to a virtual device that has no measurable delay, this code may clear XMIT_READY
|
||||
* too quickly.
|
||||
*
|
||||
* if (this.transmitByte(bOut)) {
|
||||
* this.bStatus |= (SerialPort.UART8251.STATUS.XMIT_READY | SerialPort.UART8251.STATUS.XMIT_EMPTY);
|
||||
* this.bStatus |= (SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);
|
||||
* }
|
||||
*
|
||||
* A better solution is to arm a timer based on the XMIT_RATE baud rate, and clear the above bits when that
|
||||
|
|
@ -765,7 +767,7 @@ SerialPort.prototype.outData = function(port, bOut, addrFrom)
|
|||
*/
|
||||
this.transmitByte(bOut);
|
||||
if (this.cpu) {
|
||||
this.cpu.setTimer(this.timerTransmitNext, this.getBaudTimeout(SerialPort.UART8251.BAUDRATES.XMIT_RATE));
|
||||
this.cpu.setTimer(this.timerTransmitNext, this.getBaudTimeout(SerialPort8080.UART8251.BAUDRATES.XMIT_RATE));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -777,12 +779,12 @@ SerialPort.prototype.outData = function(port, bOut, addrFrom)
|
|||
* has received that initial byte, the device is marked "ready", and all further bytes are
|
||||
* interpreted as COMMAND bytes (until/unless a COMMAND byte with the INTERNAL_RESET bit is set).
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} port (0x1)
|
||||
* @param {number} bOut
|
||||
* @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)
|
||||
*/
|
||||
SerialPort.prototype.outControl = function(port, bOut, addrFrom)
|
||||
SerialPort8080.prototype.outControl = function(port, bOut, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, bOut, addrFrom, "CONTROL");
|
||||
if (!this.fReady) {
|
||||
|
|
@ -790,7 +792,7 @@ SerialPort.prototype.outControl = function(port, bOut, addrFrom)
|
|||
this.fReady = true;
|
||||
} else {
|
||||
this.bCommand = bOut;
|
||||
if (this.bCommand & SerialPort.UART8251.COMMAND.INTERNAL_RESET) {
|
||||
if (this.bCommand & SerialPort8080.UART8251.COMMAND.INTERNAL_RESET) {
|
||||
this.fReady = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -799,12 +801,12 @@ SerialPort.prototype.outControl = function(port, bOut, addrFrom)
|
|||
/**
|
||||
* outBaudRates(port, bOut, addrFrom)
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @this {SerialPort8080}
|
||||
* @param {number} port (0x2)
|
||||
* @param {number} bOut
|
||||
* @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)
|
||||
*/
|
||||
SerialPort.prototype.outBaudRates = function(port, bOut, addrFrom)
|
||||
SerialPort8080.prototype.outBaudRates = function(port, bOut, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, bOut, addrFrom, "BAUDRATES");
|
||||
this.bBaudRates = bOut;
|
||||
|
|
@ -813,43 +815,43 @@ SerialPort.prototype.outBaudRates = function(port, bOut, addrFrom)
|
|||
/*
|
||||
* Port input notification table
|
||||
*/
|
||||
SerialPort.aPortInput = {
|
||||
0x0: SerialPort.prototype.inData,
|
||||
0x1: SerialPort.prototype.inControl
|
||||
SerialPort8080.aPortInput = {
|
||||
0x0: SerialPort8080.prototype.inData,
|
||||
0x1: SerialPort8080.prototype.inControl
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Port output notification table
|
||||
*/
|
||||
SerialPort.aPortOutput = {
|
||||
0x0: SerialPort.prototype.outData,
|
||||
0x1: SerialPort.prototype.outControl,
|
||||
0x2: SerialPort.prototype.outBaudRates
|
||||
SerialPort8080.aPortOutput = {
|
||||
0x0: SerialPort8080.prototype.outData,
|
||||
0x1: SerialPort8080.prototype.outControl,
|
||||
0x2: SerialPort8080.prototype.outBaudRates
|
||||
};
|
||||
|
||||
/**
|
||||
* SerialPort.init()
|
||||
* SerialPort8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "serial", extracting the
|
||||
* JSON-encoded parameters for the SerialPort constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a SerialPort component, and then binding
|
||||
* JSON-encoded parameters for the SerialPort8080 constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a SerialPort8080 component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*/
|
||||
SerialPort.init = function()
|
||||
SerialPort8080.init = function()
|
||||
{
|
||||
var aeSerial = Component.getElementsByClass(document, PC8080.APPCLASS, "serial");
|
||||
for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {
|
||||
var eSerial = aeSerial[iSerial];
|
||||
var parmsSerial = Component.getComponentParms(eSerial);
|
||||
var serial = new SerialPort(parmsSerial);
|
||||
var serial = new SerialPort8080(parmsSerial);
|
||||
Component.bindComponentControls(serial, eSerial, PC8080.APPCLASS);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize every SerialPort module on the page.
|
||||
* Initialize every SerialPort8080 module on the page.
|
||||
*/
|
||||
web.onInit(SerialPort.init);
|
||||
web.onInit(SerialPort8080.init);
|
||||
|
||||
if (NODE) module.exports = SerialPort;
|
||||
if (NODE) module.exports = SerialPort8080;
|
||||
|
|
|
|||
|
|
@ -1,396 +0,0 @@
|
|||
/**
|
||||
* @fileoverview The State class used by PCjs machines.
|
||||
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
|
||||
* @version 1.0
|
||||
* Created 2016-Apr-19
|
||||
*
|
||||
* Copyright © 2012-2016 Jeff Parsons <Jeff@pcjs.org>
|
||||
*
|
||||
* This file is part of PCjs, a computer emulation software project at <http://pcjs.org/>.
|
||||
*
|
||||
* PCjs is free software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation, either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCjs. If not,
|
||||
* see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*
|
||||
* You are required to include the above copyright notice in every source code file of every
|
||||
* copy or modified version of this work, and to display that copyright notice on every screen
|
||||
* that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js).
|
||||
*
|
||||
* Some PCjs files also attempt to load external resource files, such as character-image files,
|
||||
* ROM files, and disk image files. Those external resource files are not considered part of PCjs
|
||||
* for purposes of the GNU General Public License, and the author does not claim any copyright
|
||||
* as to their contents.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (NODE) {
|
||||
var web = require("./../../shared/lib/weblib");
|
||||
var Component = require("./../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
}
|
||||
|
||||
/**
|
||||
* State(component, sVersion, sSuffix)
|
||||
*
|
||||
* State objects are used by components to save/restore their state.
|
||||
*
|
||||
* During a save operation, components add data to a State object via set(),
|
||||
* and then return the resulting data using data().
|
||||
*
|
||||
* During a restore operation, the Computer component passes the results of each
|
||||
* data() call back to the originating component.
|
||||
*
|
||||
* WARNING: Since State objects are low-level objects that have no UI requirements,
|
||||
* they do not inherit from the Component class, so you should only use class methods
|
||||
* of Component, such as Component.assert(), or Debugger methods if the Debugger
|
||||
* is available.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Component} component
|
||||
* @param {string} [sVersion] is used to append a major version number to the key
|
||||
* @param {string} [sSuffix] is used to append any additional suffixes to the key
|
||||
*/
|
||||
function State(component, sVersion, sSuffix) {
|
||||
this.id = component.id;
|
||||
this.key = State.key(component, sVersion, sSuffix);
|
||||
this.dbg = component.dbg;
|
||||
this.unload(component.parms);
|
||||
}
|
||||
|
||||
/**
|
||||
* State.key(component, sVersion, sSuffix)
|
||||
*
|
||||
* This encapsulates the key generation code.
|
||||
*
|
||||
* @param {Component} component
|
||||
* @param {string} [sVersion] is used to append a major version number to the key
|
||||
* @param {string} [sSuffix] is used to append any additional suffixes to the key
|
||||
* @return {string} key
|
||||
*/
|
||||
State.key = function(component, sVersion, sSuffix) {
|
||||
var key = component.id;
|
||||
if (sVersion) {
|
||||
var i = sVersion.indexOf('.');
|
||||
if (i > 0) key += ".v" + sVersion.substr(0, i);
|
||||
}
|
||||
if (sSuffix) {
|
||||
key += "." + sSuffix;
|
||||
}
|
||||
return key;
|
||||
};
|
||||
|
||||
/**
|
||||
* State.compress(aSrc)
|
||||
*
|
||||
* @param {Array.<number>|null} aSrc
|
||||
* @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of "count, value" pairs (aComp)
|
||||
*/
|
||||
State.compress = function(aSrc) {
|
||||
if (aSrc) {
|
||||
var iSrc = 0;
|
||||
var iComp = 0;
|
||||
var aComp = [];
|
||||
while (iSrc < aSrc.length) {
|
||||
var n = aSrc[iSrc];
|
||||
Component.assert(n !== undefined);
|
||||
var iCompare = iSrc + 1;
|
||||
while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;
|
||||
aComp[iComp++] = iCompare - iSrc;
|
||||
aComp[iComp++] = n;
|
||||
iSrc = iCompare;
|
||||
}
|
||||
if (aComp.length < aSrc.length) return aComp;
|
||||
}
|
||||
return aSrc;
|
||||
};
|
||||
|
||||
/**
|
||||
* State.decompress(aComp)
|
||||
*
|
||||
* @param {Array.<number>} aComp
|
||||
* @param {number} nLength is expected length of decompressed data
|
||||
* @return {Array.<number>}
|
||||
*/
|
||||
State.decompress = function(aComp, nLength) {
|
||||
var iDst = 0;
|
||||
var aDst = new Array(nLength);
|
||||
var iComp = 0;
|
||||
while (iComp < aComp.length - 1) {
|
||||
var c = aComp[iComp++];
|
||||
var n = aComp[iComp++];
|
||||
while (c--) {
|
||||
aDst[iDst++] = n;
|
||||
}
|
||||
}
|
||||
Component.assert(aDst.length == nLength);
|
||||
return aDst;
|
||||
};
|
||||
|
||||
/**
|
||||
* State.compressEvenOdd(aSrc)
|
||||
*
|
||||
* This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,
|
||||
* followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even
|
||||
* addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case
|
||||
* for compress(), but the best case for compressEvenOdd().
|
||||
*
|
||||
* One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,
|
||||
* and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array
|
||||
* and return an uninitialized array.
|
||||
*
|
||||
* @param {Array.<number>|null} aSrc
|
||||
* @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of "count, value" pairs (aComp)
|
||||
*/
|
||||
State.compressEvenOdd = function(aSrc) {
|
||||
if (aSrc) {
|
||||
var iComp = 0, aComp = [];
|
||||
if (aSrc[0] !== undefined) {
|
||||
for (var off = 0; off < 2; off++) {
|
||||
var iSrc = off;
|
||||
while (iSrc < aSrc.length) {
|
||||
var n = aSrc[iSrc];
|
||||
var iCompare = iSrc + 2;
|
||||
while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;
|
||||
aComp[iComp++] = (iCompare - iSrc) >> 1;
|
||||
aComp[iComp++] = n;
|
||||
iSrc = iCompare;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aComp.length < aSrc.length) return aComp;
|
||||
}
|
||||
return aSrc;
|
||||
};
|
||||
|
||||
/**
|
||||
* State.decompressEvenOdd(aComp, nLength)
|
||||
*
|
||||
* This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence
|
||||
* that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:
|
||||
* if you used even/odd compression, then you must use even/odd decompression.
|
||||
*
|
||||
* @param {Array.<number>} aComp
|
||||
* @param {number} nLength is expected length of decompressed data
|
||||
* @return {Array.<number>}
|
||||
*/
|
||||
State.decompressEvenOdd = function(aComp, nLength) {
|
||||
var iDst = 0;
|
||||
var aDst = new Array(nLength);
|
||||
var iComp = 0;
|
||||
while (iComp < aComp.length - 1) {
|
||||
var c = aComp[iComp++];
|
||||
var n = aComp[iComp++];
|
||||
while (c--) {
|
||||
aDst[iDst] = n;
|
||||
iDst += 2;
|
||||
}
|
||||
/*
|
||||
* The output of a "count,value" pair will never exceed the end of the output array, so as soon as we reach it
|
||||
* the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be
|
||||
* done.
|
||||
*/
|
||||
Component.assert(iDst <= nLength || iComp == aComp.length);
|
||||
if (iDst == nLength) iDst = 1;
|
||||
}
|
||||
Component.assert(aDst.length == nLength);
|
||||
return aDst;
|
||||
};
|
||||
|
||||
State.prototype = {
|
||||
constructor: State,
|
||||
/**
|
||||
* set(id, data)
|
||||
*
|
||||
* @this {State}
|
||||
* @param {number|string} id
|
||||
* @param {Object|string} data
|
||||
*/
|
||||
set: function(id, data) {
|
||||
try {
|
||||
this[this.id][id] = data;
|
||||
} catch(e) {
|
||||
Component.log(e.message);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* get(id)
|
||||
*
|
||||
* @this {State}
|
||||
* @param {number|string} id
|
||||
* @return {Object|string|null}
|
||||
*/
|
||||
get: function(id) {
|
||||
return this[this.id][id] || null;
|
||||
},
|
||||
/**
|
||||
* value()
|
||||
*
|
||||
* Use this instead of data() if you haven't called parse() yet.
|
||||
*
|
||||
* @this {State}
|
||||
* @return {string}
|
||||
*/
|
||||
value: function() {
|
||||
return this[this.id];
|
||||
},
|
||||
/**
|
||||
* data()
|
||||
*
|
||||
* @this {State}
|
||||
* @return {Object}
|
||||
*/
|
||||
data: function() {
|
||||
return this[this.id];
|
||||
},
|
||||
/**
|
||||
* load(s)
|
||||
*
|
||||
* WARNING: Make sure you follow this call with either a call to parse() or unload(),
|
||||
* because any stringified data that we've loaded isn't usable until it's been parsed.
|
||||
*
|
||||
* @this {State}
|
||||
* @param {Object|string|null} [s]
|
||||
* @return {boolean} true if state exists in localStorage, false if not
|
||||
*/
|
||||
load: function(s) {
|
||||
if (s) {
|
||||
this[this.id] = s;
|
||||
this.fLoaded = true;
|
||||
return true;
|
||||
}
|
||||
if (this.fLoaded) {
|
||||
/*
|
||||
* This is assumed to be a redundant load().
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
if (web.hasLocalStorage()) {
|
||||
s = web.getLocalStorageItem(this.key);
|
||||
if (s) {
|
||||
this[this.id] = s;
|
||||
this.fLoaded = true;
|
||||
if (DEBUG) this.printString("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* parse()
|
||||
*
|
||||
* This completes the load() operation, by parsing what was loaded, on the assumption there
|
||||
* might be some benefit to deferring parsing until we've given the user a chance to confirm.
|
||||
* Otherwise, load() could have just as easily done this, too.
|
||||
*
|
||||
* @this {State}
|
||||
* @return {boolean} true if successful, false if error
|
||||
*/
|
||||
parse: function() {
|
||||
var fSuccess = true;
|
||||
try {
|
||||
this[this.id] = JSON.parse(this[this.id]);
|
||||
} catch (e) {
|
||||
Component.error(e.message || e);
|
||||
fSuccess = false;
|
||||
}
|
||||
return fSuccess;
|
||||
},
|
||||
/**
|
||||
* store()
|
||||
*
|
||||
* @this {State}
|
||||
* @return {boolean} true if successful, false if error
|
||||
*/
|
||||
store: function() {
|
||||
var fSuccess = true;
|
||||
if (web.hasLocalStorage()) {
|
||||
var s = JSON.stringify(this[this.id]);
|
||||
if (web.setLocalStorageItem(this.key, s)) {
|
||||
if (DEBUG) this.printString("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
} else {
|
||||
/*
|
||||
* WARNING: Because browsers tend to disable all alerts() during an "unload" operation,
|
||||
* it's unlikely anyone will ever see the "quota" errors that occur at this point. Need to
|
||||
* think of some way to notify the user that there's a problem, and offer a way of cleaning
|
||||
* up old states.
|
||||
*/
|
||||
Component.error("Unable to store " + s.length + " bytes in browser local storage");
|
||||
fSuccess = false;
|
||||
}
|
||||
}
|
||||
return fSuccess;
|
||||
},
|
||||
/**
|
||||
* toString()
|
||||
*
|
||||
* We can't know whether this might be called before parse() or after parse(), so we check.
|
||||
* If before, then this[this.id] will still be in string form; if after, it will be an Object.
|
||||
*
|
||||
* @this {State}
|
||||
* @return {string} JSON-encoded state
|
||||
*/
|
||||
toString: function() {
|
||||
var value = this[this.id];
|
||||
return (typeof value == "string"? value : JSON.stringify(value));
|
||||
},
|
||||
/**
|
||||
* unload(parms)
|
||||
*
|
||||
* This discards any data saved via set() or loaded via load(), creating an empty State object.
|
||||
* Note that you have to follow this call with an explicit call to store() if you want to remove
|
||||
* the state from localStorage as well.
|
||||
*
|
||||
* @this {State}
|
||||
* @param {Object} [parms]
|
||||
*/
|
||||
unload: function(parms) {
|
||||
this[this.id] = {};
|
||||
if (parms) this.set("parms", parms);
|
||||
this.fLoaded = false;
|
||||
},
|
||||
/**
|
||||
* clear(fAll)
|
||||
*
|
||||
* This unloads the current state, and then clears ALL localStorage for the current machine,
|
||||
* independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.
|
||||
*
|
||||
* @this {State}
|
||||
* @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain
|
||||
*/
|
||||
clear: function(fAll) {
|
||||
this.unload();
|
||||
var aKeys = web.getLocalStorageKeys();
|
||||
for (var i = 0; i < aKeys.length; i++) {
|
||||
var sKey = aKeys[i];
|
||||
if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {
|
||||
web.removeLocalStorageItem(sKey);
|
||||
if (DEBUG) this.printString("localStorage(" + sKey + ") removed");
|
||||
aKeys.splice(i, 1);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* printString(s)
|
||||
*
|
||||
* @this {State}
|
||||
* @param {string} s is any caller-defined string
|
||||
*/
|
||||
printString: function(s) {
|
||||
if (DEBUG && DEBUGGER && this.dbg) {
|
||||
if (this.dbg.messageEnabled(Messages.LOG)) {
|
||||
this.dbg.message(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (NODE) module.exports = State;
|
||||
|
|
@ -36,16 +36,16 @@ if (NODE) {
|
|||
var web = require("../../shared/lib/weblib");
|
||||
var DumpAPI = require("../../shared/lib/dumpapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var ChipSet = require("./chipset");
|
||||
var Memory = require("./memory");
|
||||
var Messages = require("./messages");
|
||||
var State = require("./state");
|
||||
var ChipSet8080 = require("./chipset");
|
||||
var Memory8080 = require("./memory");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
* Video(parmsVideo, canvas, context, textarea, container)
|
||||
* Video8080(parmsVideo, canvas, context, textarea, container)
|
||||
*
|
||||
* The Video component can be configured with the following (parmsVideo) properties:
|
||||
* The Video8080 component can be configured with the following (parmsVideo) properties:
|
||||
*
|
||||
* screenWidth: width of the screen canvas, in pixels
|
||||
* screenHeight: height of the screen canvas, in pixels
|
||||
|
|
@ -54,7 +54,7 @@ if (NODE) {
|
|||
* aspectRatio (eg, 1.33)
|
||||
* bufferAddr: the starting address of the frame buffer (eg, 0x2400)
|
||||
* bufferRAM: true to use existing RAM (default is false)
|
||||
* bufferFormat: if defined, one of the recognized formats in Video.FORMATS (eg, "vt100")
|
||||
* bufferFormat: if defined, one of the recognized formats in Video8080.FORMATS (eg, "vt100")
|
||||
* bufferCols: the width of a single frame buffer row, in pixels (eg, 256)
|
||||
* bufferRows: the number of frame buffer rows (eg, 224)
|
||||
* bufferBits: the number of bits per column (default is 1)
|
||||
|
|
@ -94,13 +94,13 @@ if (NODE) {
|
|||
* @param {Object} [textarea]
|
||||
* @param {Object} [container]
|
||||
*/
|
||||
function Video(parmsVideo, canvas, context, textarea, container)
|
||||
function Video8080(parmsVideo, canvas, context, textarea, container)
|
||||
{
|
||||
var video = this;
|
||||
this.fGecko = web.isUserAgent("Gecko/");
|
||||
var i, sEvent, asWebPrefixes = ['', 'moz', 'ms', 'webkit'];
|
||||
|
||||
Component.call(this, "Video", parmsVideo, Video, Messages.VIDEO);
|
||||
Component.call(this, "Video", parmsVideo, Video8080, Messages8080.VIDEO);
|
||||
|
||||
this.cxScreen = parmsVideo['screenWidth'];
|
||||
this.cyScreen = parmsVideo['screenHeight'];
|
||||
|
|
@ -109,7 +109,7 @@ function Video(parmsVideo, canvas, context, textarea, container)
|
|||
this.fUseRAM = parmsVideo['bufferRAM'];
|
||||
|
||||
var sFormat = parmsVideo['bufferFormat'];
|
||||
this.nFormat = sFormat && Video.FORMATS[sFormat.toUpperCase()] || Video.FORMAT.UNKNOWN;
|
||||
this.nFormat = sFormat && Video8080.FORMATS[sFormat.toUpperCase()] || Video8080.FORMAT.UNKNOWN;
|
||||
|
||||
this.nColsBuffer = parmsVideo['bufferCols'];
|
||||
this.nRowsBuffer = parmsVideo['bufferRows'];
|
||||
|
|
@ -252,27 +252,27 @@ function Video(parmsVideo, canvas, context, textarea, container)
|
|||
if (DEBUG) this.nCyclesPrev = 0;
|
||||
}
|
||||
|
||||
Component.subclass(Video);
|
||||
Component.subclass(Video8080);
|
||||
|
||||
Video.COLORS = {
|
||||
Video8080.COLORS = {
|
||||
OVERLAY_TOP: 0,
|
||||
OVERLAY_BOTTOM: 1,
|
||||
OVERLAY_TOTAL: 2
|
||||
};
|
||||
|
||||
Video.FORMAT = {
|
||||
Video8080.FORMAT = {
|
||||
UNKNOWN: 0,
|
||||
SI1978: 1,
|
||||
VT100: 2
|
||||
};
|
||||
|
||||
Video.FORMATS = {
|
||||
"SI1978": Video.FORMAT.SI1978,
|
||||
"VT100": Video.FORMAT.VT100
|
||||
Video8080.FORMATS = {
|
||||
"SI1978": Video8080.FORMAT.SI1978,
|
||||
"VT100": Video8080.FORMAT.VT100
|
||||
};
|
||||
|
||||
|
||||
Video.VT100 = {
|
||||
Video8080.VT100 = {
|
||||
/*
|
||||
* The following font IDs are nothing more than all the possible LINEATTR values masked with FONTMASK;
|
||||
* also, note that double-high implies double-wide; the VT100 doesn't support a double-high single-wide font.
|
||||
|
|
@ -297,10 +297,10 @@ Video.VT100 = {
|
|||
/**
|
||||
* initBuffers()
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @return {boolean}
|
||||
*/
|
||||
Video.prototype.initBuffers = function()
|
||||
Video8080.prototype.initBuffers = function()
|
||||
{
|
||||
/*
|
||||
* Allocate off-screen buffers now
|
||||
|
|
@ -318,7 +318,7 @@ Video.prototype.initBuffers = function()
|
|||
this.sizeBuffer = 0;
|
||||
if (!this.fUseRAM) {
|
||||
this.sizeBuffer = ((this.cxBuffer * this.nBitsPerPixel) >> 3) * this.cyBuffer;
|
||||
if (!this.bus.addMemory(this.addrBuffer, this.sizeBuffer, Memory.TYPE.VIDEO)) {
|
||||
if (!this.bus.addMemory(this.addrBuffer, this.sizeBuffer, Memory8080.TYPE.VIDEO)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ Video.prototype.initBuffers = function()
|
|||
this.aFonts = {};
|
||||
this.initColors();
|
||||
|
||||
if (this.nFormat == Video.FORMAT.VT100) {
|
||||
if (this.nFormat == Video8080.FORMAT.VT100) {
|
||||
/*
|
||||
* Beyond fonts, VT100 support requires that we maintain a number of additional properties:
|
||||
*
|
||||
|
|
@ -397,13 +397,13 @@ Video.prototype.initBuffers = function()
|
|||
/**
|
||||
* initBus(cmp, bus, cpu, dbg)
|
||||
*
|
||||
* @this {Video}
|
||||
* @param {Computer} cmp
|
||||
* @param {Bus} bus
|
||||
* @param {CPUState} cpu
|
||||
* @param {Debugger} dbg
|
||||
* @this {Video8080}
|
||||
* @param {Computer8080} cmp
|
||||
* @param {Bus8080} bus
|
||||
* @param {CPUState8080} cpu
|
||||
* @param {Debugger8080} dbg
|
||||
*/
|
||||
Video.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
Video8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.bus = bus;
|
||||
|
|
@ -419,7 +419,7 @@ Video.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
* If we have an associated keyboard, then ensure that the keyboard will be notified
|
||||
* whenever the canvas gets focus and receives input.
|
||||
*/
|
||||
this.kbd = /** @type {Keyboard} */ (cmp.getMachineComponent("Keyboard"));
|
||||
this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent("Keyboard"));
|
||||
if (this.kbd) {
|
||||
for (var s in this.ledBindings) {
|
||||
this.kbd.setBinding("led", s, this.ledBindings[s]);
|
||||
|
|
@ -435,12 +435,12 @@ Video.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* doneLoad(sURL, sFontData, nErrorCode)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {string} sURL
|
||||
* @param {string} sFontData
|
||||
* @param {number} nErrorCode (response from server if anything other than 200)
|
||||
*/
|
||||
Video.prototype.doneLoad = function(sURL, sFontData, nErrorCode)
|
||||
Video8080.prototype.doneLoad = function(sURL, sFontData, nErrorCode)
|
||||
{
|
||||
if (nErrorCode) {
|
||||
this.notice("Unable to load font ROM (error " + nErrorCode + ": " + sURL + ")");
|
||||
|
|
@ -496,25 +496,25 @@ Video.prototype.doneLoad = function(sURL, sFontData, nErrorCode)
|
|||
/**
|
||||
* createFonts()
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @return {boolean}
|
||||
*/
|
||||
Video.prototype.createFonts = function()
|
||||
Video8080.prototype.createFonts = function()
|
||||
{
|
||||
/*
|
||||
* We retain abFontData in case we have to rebuild the fonts (eg, when we switch from 80 to 132 columns)
|
||||
*/
|
||||
if (this.abFontData) {
|
||||
this.fDotStretcher = (this.nFormat == Video.FORMAT.VT100);
|
||||
this.aFonts[Video.VT100.FONT.NORML] = [
|
||||
this.fDotStretcher = (this.nFormat == Video8080.FORMAT.VT100);
|
||||
this.aFonts[Video8080.VT100.FONT.NORML] = [
|
||||
this.createFontVariation(this.cxCell, this.cyCell),
|
||||
this.createFontVariation(this.cxCell, this.cyCell, this.fUnderline)
|
||||
];
|
||||
this.aFonts[Video.VT100.FONT.DWIDE] = [
|
||||
this.aFonts[Video8080.VT100.FONT.DWIDE] = [
|
||||
this.createFontVariation(this.cxCell*2, this.cyCell),
|
||||
this.createFontVariation(this.cxCell*2, this.cyCell, this.fUnderline)
|
||||
];
|
||||
this.aFonts[Video.VT100.FONT.DHIGH] = this.aFonts[Video.VT100.FONT.DHIGH_BOT] = [
|
||||
this.aFonts[Video8080.VT100.FONT.DHIGH] = this.aFonts[Video8080.VT100.FONT.DHIGH_BOT] = [
|
||||
this.createFontVariation(this.cxCell*2, this.cyCell*2),
|
||||
this.createFontVariation(this.cxCell*2, this.cyCell*2, this.fUnderline)
|
||||
];
|
||||
|
|
@ -533,13 +533,13 @@ Video.prototype.createFonts = function()
|
|||
* 3) double-high double-wide characters (cell size is this.cxCell*2 x this.cyCell*2)
|
||||
* 4) any of the above with either reverse video or underline enabled (default is neither)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} cxCell is the target width of each character in the grid
|
||||
* @param {number} cyCell is the target height of each character in the grid
|
||||
* @param {boolean} [fUnderline] (null for unmodified font, false for reverse video, true for underline)
|
||||
* @return {Object}
|
||||
*/
|
||||
Video.prototype.createFontVariation = function(cxCell, cyCell, fUnderline)
|
||||
Video8080.prototype.createFontVariation = function(cxCell, cyCell, fUnderline)
|
||||
{
|
||||
/*
|
||||
* On a VT100, cxCell,cyCell is initially 10,10, but may change to 9,10 for 132-column mode.
|
||||
|
|
@ -606,12 +606,12 @@ Video.prototype.createFontVariation = function(cxCell, cyCell, fUnderline)
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
* @return {boolean} true if successful, false if failure
|
||||
*/
|
||||
Video.prototype.powerUp = function(data, fRepower)
|
||||
Video8080.prototype.powerUp = function(data, fRepower)
|
||||
{
|
||||
/*
|
||||
* Because the VT100 frame buffer can be located anywhere in RAM (above 0x2000), we must defer this
|
||||
|
|
@ -619,7 +619,7 @@ Video.prototype.powerUp = function(data, fRepower)
|
|||
*
|
||||
* TODO: Remove this display test code once the VT100 is fully operational.
|
||||
*/
|
||||
if (this.nFormat == Video.FORMAT.VT100) {
|
||||
if (this.nFormat == Video8080.FORMAT.VT100) {
|
||||
/*
|
||||
* Build a test screen in the VT100 frame buffer; we'll mimic the "SET-UP A" screen, since it uses
|
||||
* all the font variations. The process involves iterating over 0-based row numbers -2 (or -5 if 50Hz
|
||||
|
|
@ -629,10 +629,10 @@ Video.prototype.powerUp = function(data, fRepower)
|
|||
* default character attribute for subsequent strings. An empty array ends the screen build process.
|
||||
*/
|
||||
var aLineData = {
|
||||
0: [Video.VT100.FONT.DHIGH, 'SET-UP A'],
|
||||
2: [Video.VT100.FONT.DWIDE, 'TO EXIT PRESS "SET-UP"'],
|
||||
22: [Video.VT100.FONT.NORML, ' T T T T T T T T T'],
|
||||
23: [Video.VT100.FONT.NORML, '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890'],
|
||||
0: [Video8080.VT100.FONT.DHIGH, 'SET-UP A'],
|
||||
2: [Video8080.VT100.FONT.DWIDE, 'TO EXIT PRESS "SET-UP"'],
|
||||
22: [Video8080.VT100.FONT.NORML, ' T T T T T T T T T'],
|
||||
23: [Video8080.VT100.FONT.NORML, '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890'],
|
||||
24: []
|
||||
};
|
||||
var addr = this.addrBuffer;
|
||||
|
|
@ -644,9 +644,9 @@ Video.prototype.powerUp = function(data, fRepower)
|
|||
var fBreak = false;
|
||||
addrNext = addr + 2;
|
||||
if (!lineData) {
|
||||
if (font == Video.VT100.FONT.DHIGH) {
|
||||
if (font == Video8080.VT100.FONT.DHIGH) {
|
||||
lineData = aLineData[iRow-1];
|
||||
font = Video.VT100.FONT.DHIGH_BOT;
|
||||
font = Video8080.VT100.FONT.DHIGH_BOT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -657,7 +657,7 @@ Video.prototype.powerUp = function(data, fRepower)
|
|||
fBreak = true;
|
||||
}
|
||||
}
|
||||
b = (font & Video.VT100.LINEATTR.FONTMASK) | ((addrNext >> 8) & Video.VT100.LINEATTR.ADDRMASK) | Video.VT100.LINEATTR.ADDRBIAS;
|
||||
b = (font & Video8080.VT100.LINEATTR.FONTMASK) | ((addrNext >> 8) & Video8080.VT100.LINEATTR.ADDRMASK) | Video8080.VT100.LINEATTR.ADDRBIAS;
|
||||
this.bus.setByteDirect(addr++, b);
|
||||
this.bus.setByteDirect(addr++, addrNext & 0xff);
|
||||
if (fBreak) break;
|
||||
|
|
@ -672,7 +672,7 @@ Video.prototype.powerUp = function(data, fRepower)
|
|||
attr ^= 0x80;
|
||||
}
|
||||
}
|
||||
this.bus.setByteDirect(addr++, Video.VT100.LINETERM);
|
||||
this.bus.setByteDirect(addr++, Video8080.VT100.LINETERM);
|
||||
addrNext = addr;
|
||||
}
|
||||
/*
|
||||
|
|
@ -686,14 +686,14 @@ Video.prototype.powerUp = function(data, fRepower)
|
|||
/**
|
||||
* setBinding(sHTMLType, sBinding, control, sValue)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas")
|
||||
* @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "refresh")
|
||||
* @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement)
|
||||
* @param {string} [sValue] optional data value
|
||||
* @return {boolean} true if binding was successful, false if unrecognized binding request
|
||||
*/
|
||||
Video.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
Video8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||
{
|
||||
var video = this;
|
||||
|
||||
|
|
@ -730,11 +730,11 @@ Video.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
*
|
||||
* Called from the ChipSet component whenever the screen dimensions have been dynamically altered.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} nCols (should be either 80 or 132; 80 is the default)
|
||||
* @param {number} nRows (should be either 24 or 14; 24 is the default)
|
||||
*/
|
||||
Video.prototype.updateDimensions = function(nCols, nRows)
|
||||
Video8080.prototype.updateDimensions = function(nCols, nRows)
|
||||
{
|
||||
this.printMessage("updateDimensions(" + nCols + "," + nRows + ")");
|
||||
this.nColsBuffer = nCols;
|
||||
|
|
@ -757,10 +757,10 @@ Video.prototype.updateDimensions = function(nCols, nRows)
|
|||
*
|
||||
* Called from the ChipSet component whenever the monitor refresh rate has been dynamically altered.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} nRate (should be either 50 or 60; 60 is the default)
|
||||
*/
|
||||
Video.prototype.updateRate = function(nRate)
|
||||
Video8080.prototype.updateRate = function(nRate)
|
||||
{
|
||||
this.printMessage("updateRate(" + nRate + ")");
|
||||
this.rateMonitor = nRate;
|
||||
|
|
@ -771,10 +771,10 @@ Video.prototype.updateRate = function(nRate)
|
|||
*
|
||||
* Called from the ChipSet component whenever the screen scroll offset has been dynamically altered.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} bScroll
|
||||
*/
|
||||
Video.prototype.updateScrollOffset = function(bScroll)
|
||||
Video8080.prototype.updateScrollOffset = function(bScroll)
|
||||
{
|
||||
this.printMessage("updateScrollOffset(" + bScroll + ")");
|
||||
if (this.bScrollOffset !== bScroll) {
|
||||
|
|
@ -805,10 +805,10 @@ Video.prototype.updateScrollOffset = function(bScroll)
|
|||
/**
|
||||
* doFullScreen()
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @return {boolean} true if request successful, false if not (eg, failed OR not supported)
|
||||
*/
|
||||
Video.prototype.doFullScreen = function()
|
||||
Video8080.prototype.doFullScreen = function()
|
||||
{
|
||||
var fSuccess = false;
|
||||
if (this.container) {
|
||||
|
|
@ -874,10 +874,10 @@ Video.prototype.doFullScreen = function()
|
|||
/**
|
||||
* notifyFullScreen(fFullScreen)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {boolean|null} fFullScreen (null if there was a full-screen error)
|
||||
*/
|
||||
Video.prototype.notifyFullScreen = function(fFullScreen)
|
||||
Video8080.prototype.notifyFullScreen = function(fFullScreen)
|
||||
{
|
||||
if (!fFullScreen && this.container) {
|
||||
if (!this.fGecko) {
|
||||
|
|
@ -892,9 +892,9 @@ Video.prototype.notifyFullScreen = function(fFullScreen)
|
|||
/**
|
||||
* setFocus()
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
*/
|
||||
Video.prototype.setFocus = function()
|
||||
Video8080.prototype.setFocus = function()
|
||||
{
|
||||
if (this.inputScreen) this.inputScreen.focus();
|
||||
};
|
||||
|
|
@ -902,10 +902,10 @@ Video.prototype.setFocus = function()
|
|||
/**
|
||||
* getRefreshRate()
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @return {number}
|
||||
*/
|
||||
Video.prototype.getRefreshRate = function()
|
||||
Video8080.prototype.getRefreshRate = function()
|
||||
{
|
||||
return Math.max(this.rateRefresh, this.rateInterrupt);
|
||||
};
|
||||
|
|
@ -915,10 +915,10 @@ Video.prototype.getRefreshRate = function()
|
|||
*
|
||||
* Initializes the contents of our internal cell cache.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} nCells
|
||||
*/
|
||||
Video.prototype.initCellCache = function(nCells)
|
||||
Video8080.prototype.initCellCache = function(nCells)
|
||||
{
|
||||
this.nCellCache = nCells;
|
||||
this.fCellCacheValid = false;
|
||||
|
|
@ -932,35 +932,35 @@ Video.prototype.initCellCache = function(nCells)
|
|||
*
|
||||
* This creates an array of nColors, with additional OVERLAY_TOTAL colors tacked on to the end of the array.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
*/
|
||||
Video.prototype.initColors = function()
|
||||
Video8080.prototype.initColors = function()
|
||||
{
|
||||
var rgbBlack = [0x00, 0x00, 0x00, 0xff];
|
||||
var rgbWhite = [0xff, 0xff, 0xff, 0xff];
|
||||
this.nColors = (1 << this.nBitsPerPixel);
|
||||
this.aRGB = new Array(this.nColors + Video.COLORS.OVERLAY_TOTAL);
|
||||
this.aRGB = new Array(this.nColors + Video8080.COLORS.OVERLAY_TOTAL);
|
||||
this.aRGB[0] = rgbBlack;
|
||||
this.aRGB[1] = rgbWhite;
|
||||
if (this.nFormat == Video.FORMAT.SI1978) {
|
||||
if (this.nFormat == Video8080.FORMAT.SI1978) {
|
||||
var rgbGreen = [0x00, 0xff, 0x00, 0xff];
|
||||
//noinspection UnnecessaryLocalVariableJS
|
||||
var rgbYellow = [0xff, 0xff, 0x00, 0xff];
|
||||
this.aRGB[this.nColors + Video.COLORS.OVERLAY_TOP] = rgbYellow;
|
||||
this.aRGB[this.nColors + Video.COLORS.OVERLAY_BOTTOM] = rgbGreen;
|
||||
this.aRGB[this.nColors + Video8080.COLORS.OVERLAY_TOP] = rgbYellow;
|
||||
this.aRGB[this.nColors + Video8080.COLORS.OVERLAY_BOTTOM] = rgbGreen;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* setPixel(image, x, y, bPixel)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {Object} image
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} bPixel (ie, an index into aRGB)
|
||||
*/
|
||||
Video.prototype.setPixel = function(image, x, y, bPixel)
|
||||
Video8080.prototype.setPixel = function(image, x, y, bPixel)
|
||||
{
|
||||
var index;
|
||||
if (!this.rotateBuffer) {
|
||||
|
|
@ -968,12 +968,12 @@ Video.prototype.setPixel = function(image, x, y, bPixel)
|
|||
} else {
|
||||
index = (image.height - x - 1) * image.width + y;
|
||||
}
|
||||
if (bPixel && this.nFormat == Video.FORMAT.SI1978) {
|
||||
if (bPixel && this.nFormat == Video8080.FORMAT.SI1978) {
|
||||
if (x >= 208 && x < 236) {
|
||||
bPixel = this.nColors + Video.COLORS.OVERLAY_TOP;
|
||||
bPixel = this.nColors + Video8080.COLORS.OVERLAY_TOP;
|
||||
}
|
||||
else if (x >= 28 && x < 72) {
|
||||
bPixel = this.nColors + Video.COLORS.OVERLAY_BOTTOM;
|
||||
bPixel = this.nColors + Video8080.COLORS.OVERLAY_BOTTOM;
|
||||
}
|
||||
}
|
||||
var rgb = this.aRGB[bPixel];
|
||||
|
|
@ -989,14 +989,14 @@ Video.prototype.setPixel = function(image, x, y, bPixel)
|
|||
*
|
||||
* Updates a particular character cell (row,col) in the associated window.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} idFont
|
||||
* @param {number} col
|
||||
* @param {number} row
|
||||
* @param {number} data
|
||||
* @param {Object} [context]
|
||||
*/
|
||||
Video.prototype.updateChar = function(idFont, col, row, data, context)
|
||||
Video8080.prototype.updateChar = function(idFont, col, row, data, context)
|
||||
{
|
||||
var bChar = data & 0x7f;
|
||||
var font = this.aFonts[idFont][(data & 0x80)? 1 : 0];
|
||||
|
|
@ -1037,7 +1037,7 @@ Video.prototype.updateChar = function(idFont, col, row, data, context)
|
|||
* of the character should be drawn.
|
||||
*/
|
||||
if (font.cyCell > this.cyCell) {
|
||||
if (idFont == Video.VT100.FONT.DHIGH_BOT) ySrc += this.cyCell;
|
||||
if (idFont == Video8080.VT100.FONT.DHIGH_BOT) ySrc += this.cyCell;
|
||||
cySrc = this.cyCell;
|
||||
this.assert(font.cyCell == this.cyCell * 2);
|
||||
}
|
||||
|
|
@ -1054,10 +1054,10 @@ Video.prototype.updateChar = function(idFont, col, row, data, context)
|
|||
/**
|
||||
* updateVT100(fForced)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {boolean} [fForced]
|
||||
*/
|
||||
Video.prototype.updateVT100 = function(fForced)
|
||||
Video8080.prototype.updateVT100 = function(fForced)
|
||||
{
|
||||
var addrNext = this.addrBuffer, fontNext = -1;
|
||||
|
||||
|
|
@ -1075,14 +1075,14 @@ Video.prototype.updateVT100 = function(fForced)
|
|||
var addr = addrNext;
|
||||
var font = fontNext;
|
||||
var nColsVisible = this.nColsBuffer;
|
||||
if (font != Video.VT100.FONT.NORML) nColsVisible >>= 1;
|
||||
if (font != Video8080.VT100.FONT.NORML) nColsVisible >>= 1;
|
||||
while (true) {
|
||||
var data = this.bus.getByteDirect(addr++);
|
||||
if ((data & Video.VT100.LINETERM) == Video.VT100.LINETERM) {
|
||||
if ((data & Video8080.VT100.LINETERM) == Video8080.VT100.LINETERM) {
|
||||
var b = this.bus.getByteDirect(addr++);
|
||||
fontNext = b & Video.VT100.LINEATTR.FONTMASK;
|
||||
addrNext = ((b & Video.VT100.LINEATTR.ADDRMASK) << 8) | this.bus.getByteDirect(addr);
|
||||
addrNext += (b & Video.VT100.LINEATTR.ADDRBIAS)? Video.VT100.ADDRBIAS_LO : Video.VT100.ADDRBIAS_HI;
|
||||
fontNext = b & Video8080.VT100.LINEATTR.FONTMASK;
|
||||
addrNext = ((b & Video8080.VT100.LINEATTR.ADDRMASK) << 8) | this.bus.getByteDirect(addr);
|
||||
addrNext += (b & Video8080.VT100.LINEATTR.ADDRBIAS)? Video8080.VT100.ADDRBIAS_LO : Video8080.VT100.ADDRBIAS_HI;
|
||||
break;
|
||||
}
|
||||
if (nCols < nColsVisible) {
|
||||
|
|
@ -1192,10 +1192,10 @@ Video.prototype.updateVT100 = function(fForced)
|
|||
* and then update the cell cache to match. Since initCellCache() sets every cell in the cell cache to an
|
||||
* invalid value, we're assured that the next call to updateScreen() will redraw the entire (visible) video buffer.
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {number} n (where 0 <= n < getRefreshRate() for a normal update, or -1 for a forced update)
|
||||
*/
|
||||
Video.prototype.updateScreen = function(n)
|
||||
Video8080.prototype.updateScreen = function(n)
|
||||
{
|
||||
var fClean;
|
||||
var fUpdate = true;
|
||||
|
|
@ -1259,13 +1259,13 @@ Video.prototype.updateScreen = function(n)
|
|||
/**
|
||||
* updateScreenText(fForced)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {boolean} [fForced]
|
||||
*/
|
||||
Video.prototype.updateScreenText = function(fForced)
|
||||
Video8080.prototype.updateScreenText = function(fForced)
|
||||
{
|
||||
switch(this.nFormat) {
|
||||
case Video.FORMAT.VT100:
|
||||
case Video8080.FORMAT.VT100:
|
||||
this.updateVT100(fForced);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1274,10 +1274,10 @@ Video.prototype.updateScreenText = function(fForced)
|
|||
/**
|
||||
* updateScreenGraphics(fForced)
|
||||
*
|
||||
* @this {Video}
|
||||
* @this {Video8080}
|
||||
* @param {boolean} [fForced]
|
||||
*/
|
||||
Video.prototype.updateScreenGraphics = function(fForced)
|
||||
Video8080.prototype.updateScreenGraphics = function(fForced)
|
||||
{
|
||||
var addr = this.addrBuffer;
|
||||
var addrLimit = addr + this.sizeBuffer;
|
||||
|
|
@ -1359,14 +1359,14 @@ Video.prototype.updateScreenGraphics = function(fForced)
|
|||
};
|
||||
|
||||
/**
|
||||
* Video.init()
|
||||
* Video8080.init()
|
||||
*
|
||||
* This function operates on every HTML element of class "video", extracting the
|
||||
* JSON-encoded parameters for the Video constructor from the element's "data-value"
|
||||
* attribute, invoking the constructor to create a Video component, and then binding
|
||||
* any associated HTML controls to the new component.
|
||||
*/
|
||||
Video.init = function()
|
||||
Video8080.init = function()
|
||||
{
|
||||
var aeVideo = Component.getElementsByClass(document, PC8080.APPCLASS, "video");
|
||||
for (var iVideo = 0; iVideo < aeVideo.length; iVideo++) {
|
||||
|
|
@ -1486,7 +1486,7 @@ Video.init = function()
|
|||
* Now we can create the Video object, record it, and wire it up to the associated document elements.
|
||||
*/
|
||||
var eContext = eCanvas.getContext("2d");
|
||||
var video = new Video(parmsVideo, eCanvas, eContext, eTextArea /* || eInput */, eVideo);
|
||||
var video = new Video8080(parmsVideo, eCanvas, eContext, eTextArea /* || eInput */, eVideo);
|
||||
|
||||
/*
|
||||
* Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;
|
||||
|
|
@ -1499,6 +1499,6 @@ Video.init = function()
|
|||
/*
|
||||
* Initialize every Video module on the page.
|
||||
*/
|
||||
web.onInit(Video.init);
|
||||
web.onInit(Video8080.init);
|
||||
|
||||
if (NODE) module.exports = Video;
|
||||
if (NODE) module.exports = Video8080;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ At the time of this writing, the recommended order is:
|
|||
* [pcx86/fdc.js](lib/fdc.js)
|
||||
* [pcx86/hdc.js](lib/hdc.js)
|
||||
* [pcx86/debugger.js](lib/debugger.js)
|
||||
* [pcx86/state.js](lib/state.js)
|
||||
* [pcx86/computer.js](lib/computer.js)
|
||||
* [shared/state.js](../shared/lib/state.js)
|
||||
* [shared/embed.js](../shared/lib/embed.js)
|
||||
* [shared/save.js](../shared/lib/save.js)
|
||||
|
||||
|
|
|
|||
|
|
@ -85,18 +85,17 @@ function Component(type, parms, constructor, bitsMessage)
|
|||
|
||||
if (!parms) parms = {'id': "", 'name': ""};
|
||||
|
||||
this.id = parms['id'];
|
||||
this.id = parms['id'] || "";
|
||||
this.name = parms['name'];
|
||||
this.comment = parms['comment'];
|
||||
this.parms = parms;
|
||||
if (this.id === undefined) this.id = "";
|
||||
|
||||
var i = this.id.indexOf('.');
|
||||
if (i > 0) {
|
||||
if (i < 0) {
|
||||
this.idComponent = this.id;
|
||||
} else {
|
||||
this.idMachine = this.id.substr(0, i);
|
||||
this.idComponent = this.id.substr(i + 1);
|
||||
} else {
|
||||
this.idComponent = this.id;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -219,12 +218,35 @@ Component.subclass = function(subclass, superclass, methods, statics)
|
|||
};
|
||||
|
||||
/*
|
||||
* Every component created on the current page is recorded in this array (see Component.add()).
|
||||
*
|
||||
* This enables any component to locate another component by ID (see Component.getComponentByID())
|
||||
* Every component created on the current page is recorded in this array (see Component.add()),
|
||||
* enabling any component to locate another component by ID (see Component.getComponentByID())
|
||||
* or by type (see Component.getComponentByType()).
|
||||
*
|
||||
* Every machine on the page are now recorded as well, by their machine ID. We then record the
|
||||
* various resources used by that machine.
|
||||
*/
|
||||
Component.components = [];
|
||||
if (window) {
|
||||
if (!window['PCjs']) {
|
||||
window['PCjs'] = {
|
||||
'Machines': {},
|
||||
'Components': []
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Alias the new global objects above to their original property names, to minimize code changes.
|
||||
*/
|
||||
Component.machines = window['PCjs']['Machines'];
|
||||
Component.components = window['PCjs']['Components'];
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Fallback for non-browser-based environments (ie, Node). TODO: This will need to be
|
||||
* tailored to Node, probably using the global object instead of the window object, if we
|
||||
* ever want to support multi-machine configs in that environment.
|
||||
*/
|
||||
Component.machines = {};
|
||||
Component.components = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Component.add(component)
|
||||
|
|
@ -241,12 +263,6 @@ Component.add = function(component)
|
|||
Component.components.push(component);
|
||||
};
|
||||
|
||||
/*
|
||||
* Every machine on the page are now recorded as well, by their machine ID. We then record the various resources
|
||||
* used by that machine.
|
||||
*/
|
||||
Component.machines = {};
|
||||
|
||||
/**
|
||||
* Component.addMachine(idMachine)
|
||||
*
|
||||
|
|
@ -316,7 +332,6 @@ Component.log = function(s, type)
|
|||
* Verifies conditions that must be true (for DEBUG builds only).
|
||||
*
|
||||
* The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.
|
||||
*
|
||||
* TODO: Add a task to the build process that "asserts" there are no instances of "assertion failure" in RELEASE builds.
|
||||
*
|
||||
* @param {boolean} f is the expression we are asserting to be true
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @fileoverview The State class used by C1Pjs and PCx86.
|
||||
* @fileoverview The State class used by PCjs machines.
|
||||
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
|
||||
* @version 1.0
|
||||
* Created 2012-May-14
|
||||
|
|
@ -34,7 +34,6 @@
|
|||
if (NODE) {
|
||||
var web = require("./../../shared/lib/weblib");
|
||||
var Component = require("./../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,7 +49,7 @@ if (NODE) {
|
|||
*
|
||||
* WARNING: Since State objects are low-level objects that have no UI requirements, they do not
|
||||
* inherit from the Component class, so you should only use class methods of Component, such as
|
||||
* Component.assert(), or Debugger methods if the Debugger is available.
|
||||
* Component.assert() (or Debugger methods if the Debugger is available).
|
||||
*
|
||||
* NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.
|
||||
* From that point on, care must be taken to insure that any new version that's incompatible with
|
||||
|
|
@ -281,7 +280,7 @@ State.prototype = {
|
|||
if (s) {
|
||||
this[this.id] = s;
|
||||
this.fLoaded = true;
|
||||
if (DEBUG) this.printString("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
if (DEBUG) Component.log("localStorage(" + this.key + "): " + s.length + " bytes loaded");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -318,7 +317,7 @@ State.prototype = {
|
|||
if (web.hasLocalStorage()) {
|
||||
var s = JSON.stringify(this[this.id]);
|
||||
if (web.setLocalStorageItem(this.key, s)) {
|
||||
if (DEBUG) this.printString("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
if (DEBUG) Component.log("localStorage(" + this.key + "): " + s.length + " bytes stored");
|
||||
} else {
|
||||
/*
|
||||
* WARNING: Because browsers tend to disable all alerts() during an "unload" operation,
|
||||
|
|
@ -376,24 +375,11 @@ State.prototype = {
|
|||
var sKey = aKeys[i];
|
||||
if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {
|
||||
web.removeLocalStorageItem(sKey);
|
||||
if (DEBUG) this.printString("localStorage(" + sKey + ") removed");
|
||||
if (DEBUG) Component.log("localStorage(" + sKey + ") removed");
|
||||
aKeys.splice(i, 1);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* printString(s)
|
||||
*
|
||||
* @this {State}
|
||||
* @param {string} s is any caller-defined string
|
||||
*/
|
||||
printString: function(s) {
|
||||
if (DEBUG && DEBUGGER && this.dbg) {
|
||||
if (this.dbg.messageEnabled(Messages.LOG)) {
|
||||
this.dbg.message(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -126,8 +126,8 @@
|
|||
"./modules/pcx86/lib/fdc.js",
|
||||
"./modules/pcx86/lib/hdc.js",
|
||||
"./modules/pcx86/lib/debugger.js",
|
||||
"./modules/pcx86/lib/state.js",
|
||||
"./modules/pcx86/lib/computer.js",
|
||||
"./modules/shared/lib/state.js",
|
||||
"./modules/shared/lib/embed.js",
|
||||
"./modules/shared/lib/save.js"
|
||||
],
|
||||
|
|
@ -156,9 +156,8 @@
|
|||
"./modules/pc8080/lib/video.js",
|
||||
"./modules/pc8080/lib/serialport.js",
|
||||
"./modules/pc8080/lib/debugger.js",
|
||||
"./modules/pc8080/lib/state.js",
|
||||
"./modules/pc8080/lib/computer.js",
|
||||
"./modules/shared/lib/embed.js",
|
||||
"./modules/shared/lib/save.js"
|
||||
"./modules/shared/lib/state.js",
|
||||
"./modules/shared/lib/embed.js"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue