Fixed option to override 'state' property of a saved machine

This commit is contained in:
Jeff Parsons 2016-02-17 17:50:23 -08:00
commit 4bb7c65208
7 changed files with 132 additions and 10 deletions

View file

@ -0,0 +1,121 @@
---
layout: post
title: "Saving Disks and Machines"
date: 2016-02-17 14:00:00
permalink: /blog/2016/02/17/
---
PCjs (v1.20.9) now offers some new, *much* easier ways to save disks and machines, thanks to the new
[Save Disk](#saving-disks) and [Save Machine](#saving-machines) features. With one click, PCjs can now
generate a single download containing everything you need to embed any of our IBM PC demos on your own
web page.
Saving Disks
---
Floppy disk images can now be saved to your desktop computer by simply clicking the **Save** button next
to the floppy disk controls. Select the drive first, and then whatever diskette is shown as being "loaded"
in that drive will be saved in your local machine's Downloads folder when you click **Save**.
If you made any changes to that disk after it was loaded, those changes will be included, so if you want a pristine
copy of the disk, click the **Load** button first. PCjs will ask you to confirm that you really want to reload the
disk and discard any changes.
Note that the disk *should* be downloaded as an **.img** file, which is nothing more than a sector-by-sector binary
dump of the disk. For example, a 360Kb double-sided double-density (DSDD) disk contains 9 512-byte sectors on each
of the 40 tracks on each of its 2 sides, so when you **Save** a 360Kb disk, the downloaded file should be exactly
368,640 bytes large.
The Mac OS X operating system can automatically mount most **.img** files (from disks created by DOS 2.0 or later).
Older 1.x DOS disks, along with most non-DOS disks, do not have a BIOS Parameter Block (BPB) in the boot sector, so
most modern operating systems won't recognize the disk format. Other operating systems, like Windows, may require
third-party software in order to mount an **.img** file, and some third-party software may prefer a different extension,
such as **.ima** or **.bin**.
It's also recommended that make your **.img** files *read-only*, so that if you do mount them on your desktop
computer, neither you nor the operating system will inadvertently modify the contents of the disk. On OS X, this is
easily done with the **chmod** utility.
For example, if you saved the disk named "PC-DOS 2.00 (Disk 1)", it should have been downloaded as "PCDOS200-DISK2.img"
in your Downloads folder, so the OS X Terminal command `chmod -w PCDOS200-DISK2.img` will make it read-only, and
`chmod +w PCDOS200-DISK2.img` will make it writable again.
Saving Machines
---
Saving the entire state of any existing IBM PC machine is also possible with a single click. You can choose to save
a machine in its initial state, or make changes to any of the machine's disks and then save it. All your changes should
be preserved.
Under the bottom-left corner of any IBM PC on the PCjs [website](http://www.pcjs.org/), you should now see a
[**Save Machine**] link. When you click that link, PCjs will generate a large "blob" of JavaScript containing
everything that machine needs to run, including:
* The machine XML configuration file (eg, "machine.xml")
* The machine XSL transformation file (eg, "components.xsl")
* The machine CSS stylesheet file (eg, "components.css")
* The machine state file (eg, "state.json")
* The PCjs machine emulation script (eg, "pc.js")
* Copies of all the disk images mounted by the machine
Let's say you want to save the IBM PC on the PCjs [home page](http://www.pcjs.org/). When you click
**Save Machine**, two things should happen:
* A file will be downloaded ("pc.json")
* A popup will appear with some markup to copy-and-paste
The popup should provide the following information:
Check your Downloads folder for "pc.json", copy it to your web server as "pc.js",
and then add the following to your web page:
<div id="ibm5150"></div>
...
<script type="text/javascript" src="pc.js"></script>
<script type="text/javascript">embedPC("ibm5150","machine.xml","components.xsl");</script>
The machine should appear where the <div> is located.
Rename the downloaded file from **pc.json** to **pc.js**, copy it to your own web server, then create or edit
a web page and insert the above text. If **pc.js** and your web page are in different folders, then you'll also
need to change *src* to indicate the location of **pc.js**.
Some notes:
* PCjs asks the browser to name the downloaded file **pc.json** instead of **pc.js** because a file with a ".js"
extension may cause the Chrome web browser to block the download. And not all browsers support named downloads;
PCjs will attempt to open a new window/tab if that seems to be the case.
* Your version of Chrome may also impose size limitations on the download. If nothing downloads, the machine may
be too large for your browser, so try a different browser (eg, Firefox or Safari).
* If you have modified any floppy disks mounted by the machine *or* any of the machine's hard disks, those
modifications should be saved along with the machine.
* Any floppy disks mounted during the lifetime of the machine will be added to the machine's state. So, for example,
if you want your copy of the machine to include all the Windows 1.01 SDK disks, make sure you have loaded each disk
once before clicking **Save Machine**.
* Any floppy disks *not* mounted during the lifetime of the machine will be *removed* from the machine's list of
available disks; we don't want machines running on other websites to be consuming our bandwidth.
* The machine's current state, including memory and screen contents, are included as part of the saved
machine state. So, even if the original machine always powers on from scratch, the *copied* machine will always
resume at the point it was saved. This behavior, however, can be disabled by passing a *parms* object as the
4th parameter to the *embedPC()* call, overriding the 'state' property:
<script type="text/javascript">embedPC("ibm5150","machine.xml","components.xsl","{state:null}");</script>
While the [PCjs Documentation](/docs/pcjs/) explains how to create a *new* machine, by writing your own machine
XML file and manually copying all the other pieces, the new **Save Machine** feature is the best way to save
any *existing* IBM PC and embed it on any other website.
**WARNING**: While this feature is still "hot of the press," there will probably be some kinks to work out. Every
browser seems to have its own idiosyncrasies in terms of what can be downloaded and/or how large it can be. It's
also quite possible that certain machine features or modifications may not be properly preserved.
If you're having trouble with a particular browser or a particular machine, be sure to
[let me know](mailto:Jeff@pcjs.org), and then try another browser and/or machine.
*[@jeffpar](http://twitter.com/jeffpar)*
*February 17, 2016*

View file

@ -10,7 +10,8 @@
<disk path="/disks/pc/games/microsoft/adventure/adventure-1981.json">Microsoft Adventure</disk> <disk path="/disks/pc/games/microsoft/adventure/adventure-1981.json">Microsoft Adventure</disk>
<disk path="/apps/pc/1981/visicalc/disk.json">VisiCalc</disk> <disk path="/apps/pc/1981/visicalc/disk.json">VisiCalc</disk>
</control> </control>
<control type="button" binding="loadDrive" padright="8px">Load</control> <control type="button" binding="loadDrive">Load</control>
<control type="button" binding="saveDrive" padright="8px">Save</control>
<control type="description" binding="descDisk" padright="8px"/> <control type="description" binding="descDisk" padright="8px"/>
<control type="file" binding="mountDrive"/> <control type="file" binding="mountDrive"/>
</fdc> </fdc>

View file

@ -1206,7 +1206,7 @@ ef.prototype={constructor:ef,value:function(){return this[this.id]},data:functio
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function kr(a,b){a[a.id]={};b&&ff(a,"parms",b);a.A=!1}function lr(a){var b=!0;if(Ga()){var c=JSON.stringify(a[a.id]);Ia(a.key,c)||(Ca("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function mr(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){Ca(c.message||c),b=!1}return b}function nr(a,b){return a[a.id][b]||null}function ff(a,b,c){try{a[a.id][b]=c}catch(d){}} this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function kr(a,b){a[a.id]={};b&&ff(a,"parms",b);a.A=!1}function lr(a){var b=!0;if(Ga()){var c=JSON.stringify(a[a.id]);Ia(a.key,c)||(Ca("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function mr(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){Ca(c.message||c),b=!1}return b}function nr(a,b){return a[a.id][b]||null}function ff(a,b,c){try{a[a.id][b]=c}catch(d){}}
function or(a,b,c){Ya.call(this,"Computer",a,or,67108864);this.ra.hc=!1;pr(this,b);this.da=Qo(this,"autoPower",a);this.R=0;this.wa=a.busWidth||a.buswidth;this.A=qr;this.W=null;this.P=this.ta=!1;this.za=Qo(this,"url")||"";this.Ba=(Math.random()+.1).toString(36).substr(2,12);this.C=rr(this);if(this.M=mb("CPU",this.id)){this.ma=mb("Debugger",this.id);this.ja=new Rb({id:this.re+".bus",buswidth:this.wa},this.M,this.ma);var d,e=kb(this.id);if((this.Wd=mb("Panel",this.id))&&this.Wd.Af)for(b=0;b<e.length;b++)d= function or(a,b,c){Ya.call(this,"Computer",a,or,67108864);this.ra.hc=!1;pr(this,b);this.da=Qo(this,"autoPower",a);this.R=0;this.wa=a.busWidth||a.buswidth;this.A=qr;this.W=null;this.P=this.ta=!1;this.za=Qo(this,"url")||"";this.Ba=(Math.random()+.1).toString(36).substr(2,12);this.C=rr(this);if(this.M=mb("CPU",this.id)){this.ma=mb("Debugger",this.id);this.ja=new Rb({id:this.re+".bus",buswidth:this.wa},this.M,this.ma);var d,e=kb(this.id);if((this.Wd=mb("Panel",this.id))&&this.Wd.Af)for(b=0;b<e.length;b++)d=
e[b],d.Ua=this.Wd.Ua,d.U=this.Wd.U,d.Af=this.Wd.Af;for(b=0;b<e.length;b++)d=e[b],d.Jc&&d.Jc(this,this.ja,this.M,this.ma);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.Y=d:this.A=parseInt(d,10));var f;if(a=bb&&bb.state||Qo(this,"state")||(f=!0,a.state))b=this.ka=a,f||(this.P=!0,this.A=qr),this.A&&(this.X=new ef(this,sr),this.X.load()?b=null:delete this.X);!b&&this.A&&(f=null,this.C&&(f=Aa()+"/api/v1/user?req=load&user="+this.C+"&state="+jr(this,sr)),b=f)&&(this.P=!0);b?za(b,!0,null,this,this.vk): e[b],d.Ua=this.Wd.Ua,d.U=this.Wd.U,d.Af=this.Wd.Af;for(b=0;b<e.length;b++)d=e[b],d.Jc&&d.Jc(this,this.ja,this.M,this.ma);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.Y=d:this.A=parseInt(d,10));var f;if(a=bb&&bb.state||Qo(this,"state")||(f=!0,a.state))b=this.ka=a,f||(this.P=!0,this.A=qr),this.A&&(this.X=new ef(this,sr),this.X.load()?b=null:delete this.X);!b&&this.A&&(f=null,this.C&&(f=Aa()+"/api/v1/user?req=load&user="+this.C+"&state="+jr(this,sr)),b=f)&&(this.P=!0);b?za(b,!0,null,this,this.vk):
yb(this);this.xa.power||(this.da=!0);!c&&this.da&&tr(this,this.Xf)}else Ca("Unable to find CPU component")}hb(or);var sr="1.20.9",qr=0;h=or.prototype;h.df=function(){return this.Ba};function pr(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){Ca(d.message+" ("+c+")")}}a.ia=b}function Qo(a,b,c){var d=null;a.ia&&(d=a.ia[b]);null==d&&c&&(d=c[b]);null==d&&"object"==typeof resources&&resources[b]&&(d=b);return d}h.he=function(){return this.C||""}; yb(this);this.xa.power||(this.da=!0);!c&&this.da&&tr(this,this.Xf)}else Ca("Unable to find CPU component")}hb(or);var sr="1.20.9",qr=0;h=or.prototype;h.df=function(){return this.Ba};function pr(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){Ca(d.message+" ("+c+")")}}a.ia=b}function Qo(a,b,c){var d;a.ia&&(d=a.ia[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}h.he=function(){return this.C||""};
h.vk=function(a,b,c){c?(this.Y=null,this.P=!1,this.Ua("Unable to load machine state from server (error "+c+(b?": "+qa(b):"")+")")):(this.W=b,this.ta=!0);yb(this)};function tr(a,b,c){for(var d=kb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!zb(f)){zb(f,function(){tr(a,b,c)});return}}b.call(a,c)} h.vk=function(a,b,c){c?(this.Y=null,this.P=!1,this.Ua("Unable to load machine state from server (error "+c+(b?": "+qa(b):"")+")")):(this.W=b,this.ta=!0);yb(this)};function tr(a,b,c){for(var d=kb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!zb(f)){zb(f,function(){tr(a,b,c)});return}}b.call(a,c)}
function ur(a,b){var c=new ef(a,sr,"validate");if(c.load()&&mr(c)){var d=nr(c,"timestamp"),e=b?nr(b,"timestamp"):"unknown";d!=e&&(a.Ua("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}} function ur(a,b){var c=new ef(a,sr,"validate");if(c.load()&&mr(c)){var d=nr(c,"timestamp"),e=b?nr(b,"timestamp"):"unknown";d!=e&&(a.Ua("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
h.Xf=function(a){void 0===a&&(a=this.A||(this.W?1:qr));if(!this.R){this.R++;var b=!1,c=!1;this.qa=!1;var d=this.X||new ef(this,sr);if(-1==a)b=!0;else if(a>qr){if(d.load(this.W)){this.O=new ef(this,sr,"failsafe");this.O.load()&&(vr(this,d),a=2,kr(this.O));ff(this.O,"timestamp",ta());lr(this.O);var e=this.A&&!this.P;if(1==a||Ea("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=mr(d)){var f=nr(d,"code"),g=nr(d,"data");f&&("ok"==f?d.load(g):("error"==f&&"no machine state"!= h.Xf=function(a){void 0===a&&(a=this.A||(this.W?1:qr));if(!this.R){this.R++;var b=!1,c=!1;this.qa=!1;var d=this.X||new ef(this,sr);if(-1==a)b=!0;else if(a>qr){if(d.load(this.W)){this.O=new ef(this,sr,"failsafe");this.O.load()&&(vr(this,d),a=2,kr(this.O));ff(this.O,"timestamp",ta());lr(this.O);var e=this.A&&!this.P;if(1==a||Ea("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=mr(d)){var f=nr(d,"code"),g=nr(d,"data");f&&("ok"==f?d.load(g):("error"==f&&"no machine state"!=

View file

@ -1025,7 +1025,7 @@ Td.prototype={constructor:Td,value:function(){return this[this.id]},data:functio
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function Qm(a,b){a[a.id]={};b&&D(a,"parms",b);a.A=!1}function Rm(a){var b=!0;if(ta()){var c=JSON.stringify(a[a.id]);va(a.key,c)||(g("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function Sm(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){g(c.message||c),b=!1}return b}function Tm(a,b){return a[a.id][b]||null}function D(a,b,c){try{a[a.id][b]=c}catch(d){}} this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function Qm(a,b){a[a.id]={};b&&D(a,"parms",b);a.A=!1}function Rm(a){var b=!0;if(ta()){var c=JSON.stringify(a[a.id]);va(a.key,c)||(g("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function Sm(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){g(c.message||c),b=!1}return b}function Tm(a,b){return a[a.id][b]||null}function D(a,b,c){try{a[a.id][b]=c}catch(d){}}
function Um(a,b,c){Ha.call(this,"Computer",a,Um);this.ja.Qb=!1;Vm(this,b);this.S=Zl(this,"autoPower",a);this.F=0;this.ta=a.busWidth||a.buswidth;this.B=Wm;this.T=null;this.J=this.ha=!1;this.ka=Zl(this,"url")||"";this.na=(Math.random()+.1).toString(36).substr(2,12);this.D=Xm(this);if(this.A=Ua("CPU",this.id)){this.Ta=Ua("Debugger",this.id);this.oa=new qb({id:this.mf+".bus",buswidth:this.ta},this.A,this.Ta);var d,e=Sa(this.id);if((this.md=Ua("Panel",this.id))&&this.md.hg)for(b=0;b<e.length;b++)d=e[b], function Um(a,b,c){Ha.call(this,"Computer",a,Um);this.ja.Qb=!1;Vm(this,b);this.S=Zl(this,"autoPower",a);this.F=0;this.ta=a.busWidth||a.buswidth;this.B=Wm;this.T=null;this.J=this.ha=!1;this.ka=Zl(this,"url")||"";this.na=(Math.random()+.1).toString(36).substr(2,12);this.D=Xm(this);if(this.A=Ua("CPU",this.id)){this.Ta=Ua("Debugger",this.id);this.oa=new qb({id:this.mf+".bus",buswidth:this.ta},this.A,this.Ta);var d,e=Sa(this.id);if((this.md=Ua("Panel",this.id))&&this.md.hg)for(b=0;b<e.length;b++)d=e[b],
d.Ha=this.md.Ha,d.pc=this.md.pc,d.hg=this.md.hg;for(b=0;b<e.length;b++)d=e[b],d.nc&&d.nc(this,this.oa,this.A,this.Ta);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.N=d:this.B=parseInt(d,10));var k;if(a=Ka&&Ka.state||Zl(this,"state")||(k=!0,a.state))b=this.W=a,k||(this.J=!0,this.B=Wm),this.B&&(this.O=new Td(this,Ym),this.O.load()?b=null:delete this.O);!b&&this.B&&(k=null,this.D&&(k=qa()+"/api/v1/user?req=load&user="+this.D+"&state="+Pm(this,Ym)),b=k)&&(this.J=!0);b?pa(b,!0,null,this,this.qj):$a(this); d.Ha=this.md.Ha,d.pc=this.md.pc,d.hg=this.md.hg;for(b=0;b<e.length;b++)d=e[b],d.nc&&d.nc(this,this.oa,this.A,this.Ta);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.N=d:this.B=parseInt(d,10));var k;if(a=Ka&&Ka.state||Zl(this,"state")||(k=!0,a.state))b=this.W=a,k||(this.J=!0,this.B=Wm),this.B&&(this.O=new Td(this,Ym),this.O.load()?b=null:delete this.O);!b&&this.B&&(k=null,this.D&&(k=qa()+"/api/v1/user?req=load&user="+this.D+"&state="+Pm(this,Ym)),b=k)&&(this.J=!0);b?pa(b,!0,null,this,this.qj):$a(this);
this.pa.power||(this.S=!0);!c&&this.S&&Zm(this,this.bf)}else g("Unable to find CPU component")}Pa(Um);var Ym="1.20.9",Wm=0;f=Um.prototype;f.qe=function(){return this.na};function Vm(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){g(d.message+" ("+c+")")}}a.K=b}function Zl(a,b,c){var d=null;a.K&&(d=a.K[b]);null==d&&c&&(d=c[b]);null==d&&"object"==typeof resources&&resources[b]&&(d=b);return d}f.xd=function(){return this.D||""}; this.pa.power||(this.S=!0);!c&&this.S&&Zm(this,this.bf)}else g("Unable to find CPU component")}Pa(Um);var Ym="1.20.9",Wm=0;f=Um.prototype;f.qe=function(){return this.na};function Vm(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){g(d.message+" ("+c+")")}}a.K=b}function Zl(a,b,c){var d;a.K&&(d=a.K[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}f.xd=function(){return this.D||""};
f.qj=function(a,b,c){c?(this.N=null,this.J=!1,this.Ha("Unable to load machine state from server (error "+c+(b?": "+(String.prototype.trim?b.trim():b.replace(/^\s+|\s+$/g,"")):"")+")")):(this.T=b,this.ha=!0);$a(this)};function Zm(a,b,c){for(var d=Sa(a.id),e=0;e<=d.length;e++){var k=e<d.length?d[e]:a;if(!ab(k)){ab(k,function(){Zm(a,b,c)});return}}b.call(a,c)} f.qj=function(a,b,c){c?(this.N=null,this.J=!1,this.Ha("Unable to load machine state from server (error "+c+(b?": "+(String.prototype.trim?b.trim():b.replace(/^\s+|\s+$/g,"")):"")+")")):(this.T=b,this.ha=!0);$a(this)};function Zm(a,b,c){for(var d=Sa(a.id),e=0;e<=d.length;e++){var k=e<d.length?d[e]:a;if(!ab(k)){ab(k,function(){Zm(a,b,c)});return}}b.call(a,c)}
function $m(a,b){var c=new Td(a,Ym,"validate");if(c.load()&&Sm(c)){var d=Tm(c,"timestamp"),e=b?Tm(b,"timestamp"):"unknown";d!=e&&(a.Ha("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}} function $m(a,b){var c=new Td(a,Ym,"validate");if(c.load()&&Sm(c)){var d=Tm(c,"timestamp"),e=b?Tm(b,"timestamp"):"unknown";d!=e&&(a.Ha("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
f.bf=function(a){void 0===a&&(a=this.B||(this.T?1:Wm));if(!this.F){this.F++;var b=!1,c=!1;this.da=!1;var d=this.O||new Td(this,Ym);if(-1==a)b=!0;else if(a>Wm){if(d.load(this.T)){this.H=new Td(this,Ym,"failsafe");this.H.load()&&(an(this,d),a=2,Qm(this.H));D(this.H,"timestamp",la());Rm(this.H);var e=this.B&&!this.J;if(1==a||ra("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=Sm(d)){var k=Tm(d,"code"),l=Tm(d,"data");k&&("ok"==k?d.load(l):("error"==k&&"no machine state"!= f.bf=function(a){void 0===a&&(a=this.B||(this.T?1:Wm));if(!this.F){this.F++;var b=!1,c=!1;this.da=!1;var d=this.O||new Td(this,Ym);if(-1==a)b=!0;else if(a>Wm){if(d.load(this.T)){this.H=new Td(this,Ym,"failsafe");this.H.load()&&(an(this,d),a=2,Qm(this.H));D(this.H,"timestamp",la());Rm(this.H);var e=this.B&&!this.J;if(1==a||ra("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=Sm(d)){var k=Tm(d,"code"),l=Tm(d,"data");k&&("ok"==k?d.load(l):("error"==k&&"no machine state"!=

View file

@ -372,18 +372,18 @@ Computer.prototype.setMachineParms = function(parmsMachine)
* *
* @param {string} sParm * @param {string} sParm
* @param {Object} [parmsComponent] * @param {Object} [parmsComponent]
* @return {string|null} * @return {string|undefined}
*/ */
Computer.prototype.getMachineParm = function(sParm, parmsComponent) Computer.prototype.getMachineParm = function(sParm, parmsComponent)
{ {
var value = null; var value;
if (this.parmsMachine) { if (this.parmsMachine) {
value = this.parmsMachine[sParm]; value = this.parmsMachine[sParm];
} }
if (value == null && parmsComponent) { if (value === undefined && parmsComponent) {
value = parmsComponent[sParm]; value = parmsComponent[sParm];
} }
if (value == null && typeof resources == 'object' && resources[sParm]) { if (value === undefined && typeof resources == 'object' && resources[sParm]) {
value = sParm; value = sParm;
} }
return value; return value;

View file

@ -55,7 +55,7 @@ function savePC(idMachine, sPCJSFile)
var sState = cmp.powerOff(true); var sState = cmp.powerOff(true);
var sParms = cmp.saveMachineParms(); var sParms = cmp.saveMachineParms();
if (!sPCJSFile) { if (!sPCJSFile) {
if (MAXDEBUG) { if (DEBUG) {
sPCJSFile = "/tmp/pcjs/" + (XMLVERSION || APPVERSION) + "/pc.js" sPCJSFile = "/tmp/pcjs/" + (XMLVERSION || APPVERSION) + "/pc.js"
} else { } else {
sPCJSFile = "/versions/pcjs/" + (XMLVERSION || APPVERSION) + "/pc" + (dbg? "-dbg" : "") + ".js"; sPCJSFile = "/versions/pcjs/" + (XMLVERSION || APPVERSION) + "/pc" + (dbg? "-dbg" : "") + ".js";
@ -209,7 +209,7 @@ function downloadPC(sURL, sCSS, nErrorCode, aMachineInfo)
} }
var link = document.createElement('a'); var link = document.createElement('a');
if (typeof link.download == 'string') { if (!DEBUG && typeof link.download == 'string') {
link.href = uri; link.href = uri;
link.download = sScript + ".json"; link.download = sScript + ".json";
document.body.appendChild(link); // Firefox requires the link to be in the body (?) document.body.appendChild(link); // Firefox requires the link to be in the body (?)

View file

@ -1206,7 +1206,7 @@ ef.prototype={constructor:ef,value:function(){return this[this.id]},data:functio
this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function kr(a,b){a[a.id]={};b&&ff(a,"parms",b);a.A=!1}function lr(a){var b=!0;if(Ga()){var c=JSON.stringify(a[a.id]);Ia(a.key,c)||(Ca("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function mr(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){Ca(c.message||c),b=!1}return b}function nr(a,b){return a[a.id][b]||null}function ff(a,b,c){try{a[a.id][b]=c}catch(d){}} this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,1);c=0}}};function kr(a,b){a[a.id]={};b&&ff(a,"parms",b);a.A=!1}function lr(a){var b=!0;if(Ga()){var c=JSON.stringify(a[a.id]);Ia(a.key,c)||(Ca("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function mr(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){Ca(c.message||c),b=!1}return b}function nr(a,b){return a[a.id][b]||null}function ff(a,b,c){try{a[a.id][b]=c}catch(d){}}
function or(a,b,c){Ya.call(this,"Computer",a,or,67108864);this.ra.hc=!1;pr(this,b);this.da=Qo(this,"autoPower",a);this.R=0;this.wa=a.busWidth||a.buswidth;this.A=qr;this.W=null;this.P=this.ta=!1;this.za=Qo(this,"url")||"";this.Ba=(Math.random()+.1).toString(36).substr(2,12);this.C=rr(this);if(this.M=mb("CPU",this.id)){this.ma=mb("Debugger",this.id);this.ja=new Rb({id:this.re+".bus",buswidth:this.wa},this.M,this.ma);var d,e=kb(this.id);if((this.Wd=mb("Panel",this.id))&&this.Wd.Af)for(b=0;b<e.length;b++)d= function or(a,b,c){Ya.call(this,"Computer",a,or,67108864);this.ra.hc=!1;pr(this,b);this.da=Qo(this,"autoPower",a);this.R=0;this.wa=a.busWidth||a.buswidth;this.A=qr;this.W=null;this.P=this.ta=!1;this.za=Qo(this,"url")||"";this.Ba=(Math.random()+.1).toString(36).substr(2,12);this.C=rr(this);if(this.M=mb("CPU",this.id)){this.ma=mb("Debugger",this.id);this.ja=new Rb({id:this.re+".bus",buswidth:this.wa},this.M,this.ma);var d,e=kb(this.id);if((this.Wd=mb("Panel",this.id))&&this.Wd.Af)for(b=0;b<e.length;b++)d=
e[b],d.Ua=this.Wd.Ua,d.U=this.Wd.U,d.Af=this.Wd.Af;for(b=0;b<e.length;b++)d=e[b],d.Jc&&d.Jc(this,this.ja,this.M,this.ma);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.Y=d:this.A=parseInt(d,10));var f;if(a=bb&&bb.state||Qo(this,"state")||(f=!0,a.state))b=this.ka=a,f||(this.P=!0,this.A=qr),this.A&&(this.X=new ef(this,sr),this.X.load()?b=null:delete this.X);!b&&this.A&&(f=null,this.C&&(f=Aa()+"/api/v1/user?req=load&user="+this.C+"&state="+jr(this,sr)),b=f)&&(this.P=!0);b?za(b,!0,null,this,this.vk): e[b],d.Ua=this.Wd.Ua,d.U=this.Wd.U,d.Af=this.Wd.Af;for(b=0;b<e.length;b++)d=e[b],d.Jc&&d.Jc(this,this.ja,this.M,this.ma);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.Y=d:this.A=parseInt(d,10));var f;if(a=bb&&bb.state||Qo(this,"state")||(f=!0,a.state))b=this.ka=a,f||(this.P=!0,this.A=qr),this.A&&(this.X=new ef(this,sr),this.X.load()?b=null:delete this.X);!b&&this.A&&(f=null,this.C&&(f=Aa()+"/api/v1/user?req=load&user="+this.C+"&state="+jr(this,sr)),b=f)&&(this.P=!0);b?za(b,!0,null,this,this.vk):
yb(this);this.xa.power||(this.da=!0);!c&&this.da&&tr(this,this.Xf)}else Ca("Unable to find CPU component")}hb(or);var sr="1.20.9",qr=0;h=or.prototype;h.df=function(){return this.Ba};function pr(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){Ca(d.message+" ("+c+")")}}a.ia=b}function Qo(a,b,c){var d=null;a.ia&&(d=a.ia[b]);null==d&&c&&(d=c[b]);null==d&&"object"==typeof resources&&resources[b]&&(d=b);return d}h.he=function(){return this.C||""}; yb(this);this.xa.power||(this.da=!0);!c&&this.da&&tr(this,this.Xf)}else Ca("Unable to find CPU component")}hb(or);var sr="1.20.9",qr=0;h=or.prototype;h.df=function(){return this.Ba};function pr(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){Ca(d.message+" ("+c+")")}}a.ia=b}function Qo(a,b,c){var d;a.ia&&(d=a.ia[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}h.he=function(){return this.C||""};
h.vk=function(a,b,c){c?(this.Y=null,this.P=!1,this.Ua("Unable to load machine state from server (error "+c+(b?": "+qa(b):"")+")")):(this.W=b,this.ta=!0);yb(this)};function tr(a,b,c){for(var d=kb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!zb(f)){zb(f,function(){tr(a,b,c)});return}}b.call(a,c)} h.vk=function(a,b,c){c?(this.Y=null,this.P=!1,this.Ua("Unable to load machine state from server (error "+c+(b?": "+qa(b):"")+")")):(this.W=b,this.ta=!0);yb(this)};function tr(a,b,c){for(var d=kb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!zb(f)){zb(f,function(){tr(a,b,c)});return}}b.call(a,c)}
function ur(a,b){var c=new ef(a,sr,"validate");if(c.load()&&mr(c)){var d=nr(c,"timestamp"),e=b?nr(b,"timestamp"):"unknown";d!=e&&(a.Ua("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}} function ur(a,b){var c=new ef(a,sr,"validate");if(c.load()&&mr(c)){var d=nr(c,"timestamp"),e=b?nr(b,"timestamp"):"unknown";d!=e&&(a.Ua("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}
h.Xf=function(a){void 0===a&&(a=this.A||(this.W?1:qr));if(!this.R){this.R++;var b=!1,c=!1;this.qa=!1;var d=this.X||new ef(this,sr);if(-1==a)b=!0;else if(a>qr){if(d.load(this.W)){this.O=new ef(this,sr,"failsafe");this.O.load()&&(vr(this,d),a=2,kr(this.O));ff(this.O,"timestamp",ta());lr(this.O);var e=this.A&&!this.P;if(1==a||Ea("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=mr(d)){var f=nr(d,"code"),g=nr(d,"data");f&&("ok"==f?d.load(g):("error"==f&&"no machine state"!= h.Xf=function(a){void 0===a&&(a=this.A||(this.W?1:qr));if(!this.R){this.R++;var b=!1,c=!1;this.qa=!1;var d=this.X||new ef(this,sr);if(-1==a)b=!0;else if(a>qr){if(d.load(this.W)){this.O=new ef(this,sr,"failsafe");this.O.load()&&(vr(this,d),a=2,kr(this.O));ff(this.O,"timestamp",ta());lr(this.O);var e=this.A&&!this.P;if(1==a||Ea("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=mr(d)){var f=nr(d,"code"),g=nr(d,"data");f&&("ok"==f?d.load(g):("error"==f&&"no machine state"!=