diff --git a/_posts/2016-10-21-booting-pdp-11-basic.md b/_posts/2016-10-21-booting-pdp-11-basic.md index a9c4f7b80..e49f84432 100644 --- a/_posts/2016-10-21-booting-pdp-11-basic.md +++ b/_posts/2016-10-21-booting-pdp-11-basic.md @@ -21,12 +21,12 @@ component, including a new *loadImage()* interface that understands DEC's paper To provide a more "authentic" experience, there is also a new [PC11 Paper Tape](/devices/pdp11/pc11/) component, and machines can now be configured to include a virtual paper tape reader, with an [assortment of paper tapes](/apps/pdp11/tapes/) -ready to be attached. +ready to be loaded. In the real world, before you could load *any* paper tape, you had to first enter a [Bootstrap Loader](/apps/pdp11/boot/bootstrap/). PDPjs has simplified that process by including the Bootstrap Loader as -just another paper tape image that you can "Load" directly into memory. Once that has been loaded, you can then read any -other paper tape image, once you "Attach" it to the paper tape reader. +just another paper tape image that you can "Read" directly into memory. Once that has been done, you can then load any +other paper tape image using the Bootstrap Loader, once you "Load" it into the paper tape reader. {% include machine.html id="test1120" %} diff --git a/_posts/2016-11-13-curious-pdp-11-features.md b/_posts/2016-11-13-curious-pdp-11-features.md index 7bf72dad3..db1ce5ae2 100644 --- a/_posts/2016-11-13-curious-pdp-11-features.md +++ b/_posts/2016-11-13-curious-pdp-11-features.md @@ -80,7 +80,7 @@ but unlike tapes like [PDP-11 BASIC](/apps/pdp11/tapes/basic/), they don't inclu documentation for each test to learn the starting procedure, including any switches that should be set first. However, PDPjs makes life a bit simpler for you. As noted for other [DEC PDP-11 Tape Images](/apps/pdp11/tapes/), any -"Absolute Format" tape can be loaded directly into RAM using the machine's "Load" button instead of "Attach", allowing you +"Absolute Format" tape can be read directly into RAM using the machine's "Read" button instead of "Load", allowing you to bypass the usual three-step process of loading the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) in order to load the [Absolute Loader](/apps/pdp11/tapes/absloader/) in order to load the desired tape. diff --git a/apps/pdp11/tapes/README.md b/apps/pdp11/tapes/README.md index 0cb5e5034..32a353915 100644 --- a/apps/pdp11/tapes/README.md +++ b/apps/pdp11/tapes/README.md @@ -11,13 +11,13 @@ To load any of the DEC PDP-11 paper tapes listed below, you will need to use a [ with a [PC11 High-Speed Paper Tape Reader/Punch](/devices/pdp11/pc11/), such as this [PDP-11/20](/devices/pdp11/machine/1120/basic/debugger), and then follow this three-step process: -- Load the [DEC PDP-11 Bootstrap Loader](/apps/pdp11/boot/bootstrap/) -- Attach the [Absolute Loader](absloader/) tape image, and load it with the Bootstrap Loader -- Attach one of the "Absolute Format" tape images below, and load it with the Absolute Loader +- "Read" the [DEC PDP-11 Bootstrap Loader](/apps/pdp11/boot/bootstrap/) +- "Load" the [Absolute Loader](absloader/) tape image, and read it with the Bootstrap Loader +- "Load" one of the "Absolute Format" tape images below, and read it with the Absolute Loader This mirrors the three-step "real world" process of loading paper tape software. Moreover, any "Absolute Format" tape (which should include all the tapes listed below) can be loaded directly into RAM using the -machine's "Load" button instead of "Attach". In most cases, that eliminates the first two steps. +machine's "Read" button instead of "Load". In most cases, that eliminates the first two steps. Paper Tape Diagnostics ---------------------- diff --git a/apps/pdp11/tapes/diags/README.md b/apps/pdp11/tapes/diags/README.md index 8f903d4f7..4d1eb80c9 100644 --- a/apps/pdp11/tapes/diags/README.md +++ b/apps/pdp11/tapes/diags/README.md @@ -12,8 +12,8 @@ website, we have been able to archive the PDP-11 diagnostics shown below. The t [Default PC11 Configuration](/devices/pdp11/pc11/), so that you can easily load them into any machine with a [PC11](/modules/pdp11/lib/pc11.js), such as this [PDP-11/20 with Front Panel and Debugger](/devices/pdp11/machine/1120/panel/debugger/). -As noted for other [DEC PDP-11 Tape Images](/apps/pdp11/tapes/), these "Absolute Format" tapes can be loaded directly -into RAM using the machine's "Load" button instead of "Attach", allowing you to bypass the usual three-step process of +As noted for other [DEC PDP-11 Tape Images](/apps/pdp11/tapes/), these "Absolute Format" tapes can be read directly +into RAM using the machine's "Read" button instead of "Load", allowing you to bypass the usual three-step process of loading the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) in order to load the [Absolute Loader](/apps/pdp11/tapes/absloader/) in order to load the desired tape. @@ -255,7 +255,7 @@ From [bitsavers.org](http://bitsavers.trailing-edge.com/bits/DEC/pdp11/papertape MD-11 11/70 CPU EXERCISER ------------------------- -When started in a [PDP-11/70](/devices/pdp11/machine/1170/panel/debugger/cpuexer/) with no disk drives attached, +When started in a [PDP-11/70](/devices/pdp11/machine/1170/panel/debugger/cpuexer/) with no disk drives installed, this diagnostic displays the following startup information ("EXERCISOR" is DEC's typo, not mine): MAINDEC-11-DEQKC-B...PDP 11/70 CPU EXERCISOR diff --git a/devices/pcx86/machine/5160/mda/256kb/fake188/debugger/machine.xml b/devices/pcx86/machine/5160/mda/256kb/fake188/debugger/machine.xml index a850e2af4..3f32b2cd3 100644 --- a/devices/pcx86/machine/5160/mda/256kb/fake188/debugger/machine.xml +++ b/devices/pcx86/machine/5160/mda/256kb/fake188/debugger/machine.xml @@ -19,10 +19,10 @@ - Load - Save + Load + Save - + diff --git a/devices/pcx86/machine/5160/mda/256kb/fake188/machine.xml b/devices/pcx86/machine/5160/mda/256kb/fake188/machine.xml index 0ba34aaab..85def1992 100644 --- a/devices/pcx86/machine/5160/mda/256kb/fake188/machine.xml +++ b/devices/pcx86/machine/5160/mda/256kb/fake188/machine.xml @@ -18,10 +18,10 @@ - Load - Save + Load + Save - + Run diff --git a/devices/pdp11/machine/1120/basic/README.md b/devices/pdp11/machine/1120/basic/README.md index 9adfe2416..b9a37c6a8 100644 --- a/devices/pdp11/machine/1120/basic/README.md +++ b/devices/pdp11/machine/1120/basic/README.md @@ -13,7 +13,9 @@ PDP-11/20 BASIC Demo The machine below pre-loads the [DEC PDP-11 BASIC](/apps/pdp11/tapes/basic/) tape image into 16Kb of RAM: - +```xml + +``` You can also manually load it into memory using the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/). See the [Bootstrap Loader Demo](/devices/pdp11/machine/1120/bootstrap/) for details. diff --git a/devices/pdp11/machine/1120/basic/debugger/README.md b/devices/pdp11/machine/1120/basic/debugger/README.md index 6559cb5b7..7c8048777 100644 --- a/devices/pdp11/machine/1120/basic/debugger/README.md +++ b/devices/pdp11/machine/1120/basic/debugger/README.md @@ -14,7 +14,9 @@ PDP-11/20 BASIC Demo (with Debugger) The machine below pre-loads the [DEC PDP-11 BASIC](/apps/pdp11/tapes/basic/) tape image into 16Kb of RAM: - +```xml + +``` You can also manually load it into memory using the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/). See the [Bootstrap Loader Demo (with Debugger)](/devices/pdp11/machine/1120/bootstrap/debugger/) for details. diff --git a/devices/pdp11/machine/1120/bootstrap/README.md b/devices/pdp11/machine/1120/bootstrap/README.md index 01be48a64..9b1ba420c 100644 --- a/devices/pdp11/machine/1120/bootstrap/README.md +++ b/devices/pdp11/machine/1120/bootstrap/README.md @@ -5,6 +5,9 @@ permalink: /devices/pdp11/machine/1120/bootstrap/ machines: - id: test1120 type: pdp11 + autoMount: + PTR: + path: /apps/pdp11/tapes/absloader/DEC-11-L2PC-PO.json --- PDP-11/20 Bootstrap Loader Demo @@ -12,24 +15,28 @@ PDP-11/20 Bootstrap Loader Demo The machine below pre-loads the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) code into 16Kb of RAM: - +```xml + +``` -and then pre-attaches the [Absolute Loader](/apps/pdp11/tapes/absloader/) tape image to the PC11 Paper Tape Reader: +and then pre-loads the [Absolute Loader](/apps/pdp11/tapes/absloader/) tape image to the PC11 Paper Tape Reader: - ... +```xml +... +``` Click "Run" to load the [Absolute Loader](/apps/pdp11/tapes/absloader/). When the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) is finished, it will HALT, leaving the [Absolute Loader](/apps/pdp11/tapes/absloader/) ready to run immediately after the HALT. You can then select another tape image in the Absolute Loader format, such as [BASIC (Single User)](/apps/pdp11/tapes/basic/), -click "Attach" and then "Run". +click "Load" and then "Run". -If you need to start over, select "Bootstrap Loader (16Kb)" from the list of tapes and click "Load" instead of -"Attach", re-installing the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) directly into RAM. +If you need to start over, select "Bootstrap Loader (16Kb)" from the list of tapes and click "Read" instead of +"Load", re-installing the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) directly into RAM. Alternatively, just press the "Reset" button. The RAM component was recently updated to restore pre-loaded images whenever -the entire machine is reset. You'll still need to manually re-attach the [Absolute Loader](/apps/pdp11/tapes/absloader/) +the entire machine is reset. You'll still need to manually reload the [Absolute Loader](/apps/pdp11/tapes/absloader/) tape image, however. {% include machine.html id="test1120" %} diff --git a/devices/pdp11/machine/1120/bootstrap/debugger/README.md b/devices/pdp11/machine/1120/bootstrap/debugger/README.md index 5522d0a66..8447d998c 100644 --- a/devices/pdp11/machine/1120/bootstrap/debugger/README.md +++ b/devices/pdp11/machine/1120/bootstrap/debugger/README.md @@ -6,6 +6,9 @@ machines: - id: test1120 type: pdp11 debugger: true + autoMount: + PTR: + path: /apps/pdp11/tapes/absloader/DEC-11-L2PC-PO.json --- PDP-11/20 Bootstrap Loader Demo (with Debugger) @@ -13,24 +16,28 @@ PDP-11/20 Bootstrap Loader Demo (with Debugger) The machine below pre-loads the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) code into 16Kb of RAM: - +```xml + +``` -and then pre-attaches the [Absolute Loader](/apps/pdp11/tapes/absloader/) tape image to the PC11 Paper Tape Reader: +and then pre-loads the [Absolute Loader](/apps/pdp11/tapes/absloader/) tape image to the PC11 Paper Tape Reader: - ... +```xml +... +``` Click "Run" to load the [Absolute Loader](/apps/pdp11/tapes/absloader/). When the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) is finished, it will HALT, leaving the [Absolute Loader](/apps/pdp11/tapes/absloader/) ready to run immediately after the HALT. You can then select another tape image in the Absolute Loader format, such as [BASIC (Single User)](/apps/pdp11/tapes/basic/), -click "Attach" and then "Run". +click "Load" and then "Run". -If you need to start over, select "Bootstrap Loader (16Kb)" from the list of tapes and click "Load" instead of -"Attach", re-installing the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) directly into RAM. +If you need to start over, select "Bootstrap Loader (16Kb)" from the list of tapes and click "Read" instead of +"Load", re-installing the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) directly into RAM. Alternatively, just press the "Reset" button. The RAM component was recently updated to restore pre-loaded images whenever -the entire machine is reset. You'll still need to manually re-attach the [Absolute Loader](/apps/pdp11/tapes/absloader/) +the entire machine is reset. You'll still need to manually reload the [Absolute Loader](/apps/pdp11/tapes/absloader/) tape image, however. {% include machine.html id="test1120" %} diff --git a/devices/pdp11/machine/1120/monitor/README.md b/devices/pdp11/machine/1120/monitor/README.md index 78a875dde..066c21625 100644 --- a/devices/pdp11/machine/1120/monitor/README.md +++ b/devices/pdp11/machine/1120/monitor/README.md @@ -12,7 +12,9 @@ PDP-11/20 Boot Monitor The machine below pre-loads the [PDP-11 Boot Monitor](/apps/pdp11/boot/monitor/) into RAM: - +```xml + +``` {% include machine.html id="test1120" %} diff --git a/devices/pdp11/machine/1120/monitor/debugger/README.md b/devices/pdp11/machine/1120/monitor/debugger/README.md index 604c38242..6ef87aa3c 100644 --- a/devices/pdp11/machine/1120/monitor/debugger/README.md +++ b/devices/pdp11/machine/1120/monitor/debugger/README.md @@ -13,6 +13,8 @@ PDP-11/20 Boot Monitor (with Debugger) The machine below pre-loads the [PDP-11 Boot Monitor](/apps/pdp11/boot/monitor/) into RAM: - +```xml + +``` {% include machine.html id="test1120" %} diff --git a/devices/pdp11/machine/1170/panel/debugger/rt11/README.md b/devices/pdp11/machine/1170/panel/debugger/rt11/README.md index 7762c4f64..51cbbd271 100644 --- a/devices/pdp11/machine/1170/panel/debugger/rt11/README.md +++ b/devices/pdp11/machine/1170/panel/debugger/rt11/README.md @@ -13,6 +13,8 @@ machines: path: http://archive.pcjs.org/disks/dec/rk03/RK03-RT11-V40.json RL0: path: http://archive.pcjs.org/disks/dec/rl02k/RL02K-XXDP.json + PTR: + path: /apps/pdp11/tapes/absloader/DEC-11-L2PC-PO.json --- This machine is ready to boot [XXDP+ Diagnostics](/disks/dec/rl02k/xxdp/) ("BOOT RL0") and run diff --git a/devices/pdp11/pc11/README.md b/devices/pdp11/pc11/README.md index 55f8d246a..e1cf38f05 100644 --- a/devices/pdp11/pc11/README.md +++ b/devices/pdp11/pc11/README.md @@ -19,24 +19,28 @@ listed in the following PC11 Device XML file: which is typically referenced by a Machine XML file as: - +```xml + +``` Device XML files not only configure a device, but also list all the resource the device will use, and define UI elements -used to control the device, such as choosing which tape should be "attached" to the PC11 device. For example: +used to control the device, such as choosing which tape should be "loaded" into the PC11 device. For example: - - - Paper Tape Controls - - - - - - - Attach - Load - - - Tape Progress +```xml + + + Paper Tape Controls + + + + + - + Load + Read + + + Tape Progress + + +``` diff --git a/devices/pdp11/pc11/default.xml b/devices/pdp11/pc11/default.xml index 2cebc4365..c5ee62fbe 100644 --- a/devices/pdp11/pc11/default.xml +++ b/devices/pdp11/pc11/default.xml @@ -1,5 +1,5 @@ - + Paper Tape Controls @@ -49,8 +49,8 @@ - Attach Load + Read Tape Progress diff --git a/devices/pdp11/rk11/README.md b/devices/pdp11/rk11/README.md index e0352c4d9..9f32c5ce4 100644 --- a/devices/pdp11/rk11/README.md +++ b/devices/pdp11/rk11/README.md @@ -38,7 +38,8 @@ used to control the device, such as choosing which disks should be "auto-mounted - Load + Load + Boot diff --git a/devices/pdp11/rk11/default.xml b/devices/pdp11/rk11/default.xml index a71c22896..8a498fff7 100644 --- a/devices/pdp11/rk11/default.xml +++ b/devices/pdp11/rk11/default.xml @@ -1,5 +1,5 @@ - + Disk Drive Controls @@ -11,7 +11,8 @@ - Load + Load + Boot diff --git a/devices/pdp11/rl11/README.md b/devices/pdp11/rl11/README.md index 0c21f52fc..3b4876e78 100644 --- a/devices/pdp11/rl11/README.md +++ b/devices/pdp11/rl11/README.md @@ -39,7 +39,8 @@ used to control the device, such as choosing which disks should be "auto-mounted - Load + Load + Boot diff --git a/devices/pdp11/rl11/default.xml b/devices/pdp11/rl11/default.xml index e679acaae..76f09b814 100644 --- a/devices/pdp11/rl11/default.xml +++ b/devices/pdp11/rl11/default.xml @@ -6,7 +6,8 @@ - Load + Load + Boot diff --git a/disks/pcx86/compiled/library.xml b/disks/pcx86/compiled/library.xml index c6399a2a5..7d07a660a 100644 --- a/disks/pcx86/compiled/library.xml +++ b/disks/pcx86/compiled/library.xml @@ -517,8 +517,8 @@ Book: Undocumented Windows VGA Tests (Black Book) - Load - Save + Load + Save - + diff --git a/disks/pcx86/compiled/samples.xml b/disks/pcx86/compiled/samples.xml index 6b08e9d85..c45f1b62b 100644 --- a/disks/pcx86/compiled/samples.xml +++ b/disks/pcx86/compiled/samples.xml @@ -9,8 +9,8 @@ Microsoft Adventure VisiCalc (1981) - Load - Save + Load + Save - + diff --git a/disks/pcx86/cpm/1.1b/machine.xml b/disks/pcx86/cpm/1.1b/machine.xml index cdeaa2b3e..e9a0f72df 100644 --- a/disks/pcx86/cpm/1.1b/machine.xml +++ b/disks/pcx86/cpm/1.1b/machine.xml @@ -12,7 +12,7 @@ - Load + Load diff --git a/disks/pcx86/games/infocom/disks.xml b/disks/pcx86/games/infocom/disks.xml index 50717f284..a2fd8f4d7 100644 --- a/disks/pcx86/games/infocom/disks.xml +++ b/disks/pcx86/games/infocom/disks.xml @@ -8,6 +8,6 @@ - Load + Load diff --git a/disks/pcx86/library.xml b/disks/pcx86/library.xml index 11ac733b4..43c0b5d0f 100644 --- a/disks/pcx86/library.xml +++ b/disks/pcx86/library.xml @@ -107,8 +107,8 @@ VGA Tests (Black Book) - Load - Save + Load + Save - + diff --git a/disks/pcx86/samples.xml b/disks/pcx86/samples.xml index d1ebf5e1e..9eb68dbd0 100644 --- a/disks/pcx86/samples.xml +++ b/disks/pcx86/samples.xml @@ -8,8 +8,8 @@ - Load - Save + Load + Save - + diff --git a/disks/pcx86/windows/win10x.xml b/disks/pcx86/windows/win10x.xml index 6d2189877..955f68321 100644 --- a/disks/pcx86/windows/win10x.xml +++ b/disks/pcx86/windows/win10x.xml @@ -15,6 +15,6 @@ Windows 1.03 (APPS) Windows 1.03 (WRITE) - Load + Load diff --git a/docs/pcx86/README.md b/docs/pcx86/README.md index 446079451..ca68e7b30 100644 --- a/docs/pcx86/README.md +++ b/docs/pcx86/README.md @@ -100,7 +100,7 @@ disks at will, we'll include some UI controls. None PC-DOS 1.0 - Load + Load ... diff --git a/docs/pcx86/examples/example2.xml b/docs/pcx86/examples/example2.xml index 21019076e..a9fea6e1a 100644 --- a/docs/pcx86/examples/example2.xml +++ b/docs/pcx86/examples/example2.xml @@ -19,7 +19,7 @@ PC-DOS 1.00 - Load + Load diff --git a/docs/pcx86/examples/example3a.xml b/docs/pcx86/examples/example3a.xml index 6a5a50dfd..1b9782120 100644 --- a/docs/pcx86/examples/example3a.xml +++ b/docs/pcx86/examples/example3a.xml @@ -59,7 +59,7 @@ PC-DOS 1.00 VisiCalc - Load + Load diff --git a/docs/pcx86/examples/pcx86-dbg.js b/docs/pcx86/examples/pcx86-dbg.js index c4b4c945a..e00155291 100644 --- a/docs/pcx86/examples/pcx86-dbg.js +++ b/docs/pcx86/examples/pcx86-dbg.js @@ -650,8 +650,8 @@ l.toJSON=function(){var a;a=0;for(var b;b=ep(this,a++);)xp(b);a=JSON.stringify(t function xp(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function yp(a){bb.call(this,"FDC",a,yp,524288);this.dmaRead=this.el;this.dmaWrite=this.fl;this.dmaFormat=this.xl;this.U=a.autoMount||null;this.fa=a.sortBy||"name";"none"==this.fa&&(this.fa=null);this.B=[];this.ia=!La("Mobi")&&window&&"FileReader"in window}jb(yp);aa={}; var zp={3:{Ud:3,ge:0,name:aa.gp},4:{Ud:2,ge:1,name:aa.ep},5:{Ud:9,ge:7,name:aa.kp},6:{Ud:9,ge:7,name:aa.$o},7:{Ud:2,ge:0,name:aa.bp},8:{Ud:1,ge:2,name:aa.fp},10:{Ud:2,ge:7,name:aa.ap},13:{Ud:6,ge:7,name:aa.Xo},15:{Ud:3,ge:0,name:aa.cp}};l=yp.prototype; l.Pb=function(a,b,c){var d=this;switch(b){case "listDisks":this.qa[b]=c;if(this.fa){b=[];for(a=0;a'+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.qa[b]=c,c.onchange=function(){var a=ea(c.value,10);null!=a&&Ap(d,a)},!0;case "loadDrive":return this.qa[b]=c,c.onclick=function(){var a=d.qa.listDisks;a&&Bp(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=d.A[ea(a.value,10)||0])?(a=a.za)?(a=Na(wp(a),"octet-stream",!0,a.Ug.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)return 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;Bp(d,ja(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1}; +void 0===b&&(b="");g=g.href;void 0!==g&&(b=''+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.qa[b]=c,c.onchange=function(){var a=ea(c.value,10);null!=a&&Ap(d,a)},!0;case "loadDisk":return this.qa[b]=c,c.onclick=function(){var a=d.qa.listDisks;a&&Bp(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDisk":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= +d.A[ea(a.value,10)||0])?(a=a.za)?(a=Na(wp(a),"octet-stream",!0,a.Ug.replace(".json",".img")),w(a)):d.Na("No diskette loaded in drive."):d.Na("No diskette drive selected."))};return!0;case "mountDisk":if(this.ia)return 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;Bp(d,ja(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1}; l.Jc=function(a,b,c,d){this.ga=b;this.F=c;this.ha=d;this.X=a;this.N=Jb(a,"ChipSet");if((this.U=Yc(this.X,"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}Cp(this);qc(b,this,Dp);yc(b,this,Ep);Fp(this,"None","",!0);this.ia&&Fp(this,"Local Disk","?");Fp(this,"Remote Disk","??");Gp(this)||xb(this)}; l.hc=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.X.lh){this.B=[];for(a=0;a'+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.la[b]=c,c.onchange=function(){var a=ea(c.value,10);null!=a&&ym(d,a)},!0;case "loadDrive":return this.la[b]=c,c.onclick=function(){var a=d.la.listDisks;a&&zm(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.Y){c.parentNode.removeChild(c);break}this.la[b]=c;c.onclick=function(){var a=d.la.listDrives;a&&a.options&&d.B&&((a=d.B[ea(a.value, -10)||0])?(a=a.ua)?(a=Aa(um(a),"octet-stream",!0,a.th.replace(".json",".img")),r(a)):d.Ba("No diskette loaded in drive."):d.Ba("No diskette drive selected."))};return!0;case "mountDrive":if(this.Y)return this.la[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;zm(d,ga(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1}; +b&&(b="");g=g.href;void 0!==g&&(b=''+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.la[b]=c,c.onchange=function(){var a=ea(c.value,10);null!=a&&ym(d,a)},!0;case "loadDisk":return this.la[b]=c,c.onclick=function(){var a=d.la.listDisks;a&&zm(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDisk":if(!this.Y){c.parentNode.removeChild(c);break}this.la[b]=c;c.onclick=function(){var a=d.la.listDrives;a&&a.options&&d.B&&((a=d.B[ea(a.value, +10)||0])?(a=a.ua)?(a=Aa(um(a),"octet-stream",!0,a.th.replace(".json",".img")),r(a)):d.Ba("No diskette loaded in drive."):d.Ba("No diskette drive selected."))};return!0;case "mountDisk":if(this.Y)return this.la[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;zm(d,ga(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1}; l.pc=function(a,b,c,d){this.ia=b;this.A=c;this.Ia=d;this.ba=a;this.S=mb(a,"ChipSet");if((this.K=nc(this.ba,"autoMount")||this.K)&&"string"==typeof this.K)try{this.K=eval("("+this.K+")")}catch(e){r("FDC auto-mount error: "+e.message+" ("+this.K+")"),this.K=null}Am(this);Sb(b,this,Bm);Ub(b,this,Cm);Dm(this,"None","",!0);this.Y&&Dm(this,"Local Disk","?");Dm(this,"Remote Disk","??");Em(this)||t(this)}; l.Ub=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.ba.pg){this.C=[];for(a=0;a PC-DOS 1.0 - Load Drive + Load ``` @@ -74,7 +74,7 @@ Output ```html
-
+
diff --git a/modules/pcx86/lib/fdc.js b/modules/pcx86/lib/fdc.js index 88a200338..927eaf66a 100644 --- a/modules/pcx86/lib/fdc.js +++ b/modules/pcx86/lib/fdc.js @@ -517,7 +517,7 @@ FDC.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) }; return true; - case "loadDrive": + case "loadDisk": this.bindings[sBinding] = control; control.onclick = function onClickLoadDrive(event) { @@ -530,7 +530,7 @@ FDC.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) }; return true; - case "saveDrive": + case "saveDisk": /* * Yes, technically, this feature does not require "Local disk support" (which is really a reference * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there @@ -575,7 +575,7 @@ FDC.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) }; return true; - case "mountDrive": + case "mountDisk": if (!this.fLocalDisks) { if (DEBUG) this.log("Local disk support not available"); /* diff --git a/modules/pcx86/lib/hdc.js b/modules/pcx86/lib/hdc.js index 8740e8d19..12d15e299 100644 --- a/modules/pcx86/lib/hdc.js +++ b/modules/pcx86/lib/hdc.js @@ -568,7 +568,7 @@ HDC.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) var drive = hdc.aDrives && hdc.aDrives[iDrive]; if (drive && drive.disk) { /* - * Note the similarity (and hence factoring opportunity) between this code and the FDC's "saveDrive" binding. + * Note the similarity (and hence factoring opportunity) between this code and the FDC's "saveDisk" binding. */ var disk = drive.disk; if (DEBUG) hdc.println("saving disk " + disk.sDiskPath + "..."); diff --git a/modules/pdp11/lib/cpu.js b/modules/pdp11/lib/cpu.js index c611ba1a9..2954684b3 100644 --- a/modules/pdp11/lib/cpu.js +++ b/modules/pdp11/lib/cpu.js @@ -203,6 +203,13 @@ CPUPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) this.flags.autoStart = (sAutoStart == "true"? true : (sAutoStart == "false"? false : !!sAutoStart)); } + /* + * Start running automatically on power-up, assuming there's no Debugger and no "Run" button. + */ + if ((!DEBUGGER || !this.dbg) && this.bindings["run"] === undefined) { + this.flags.autoStart = true; + } + this.setReady(); }; @@ -328,10 +335,10 @@ CPUPDP11.prototype.powerDown = function(fSave, fShutdown) */ CPUPDP11.prototype.autoStart = function() { - /* - * Start running automatically on power-up, assuming there's no Debugger and no "Run" button - */ - if (this.flags.autoStart || (!DEBUGGER || !this.dbg) && this.bindings["run"] === undefined) { + if (this.flags.running) { + return true; + } + if (this.flags.autoStart) { /* * We used to also set fUpdateFocus when calling startCPU(), on the assumption that in the "auto-starting" * context, a machine without focus is like a day without sunshine, but in reality, focus should only be diff --git a/modules/pdp11/lib/cpustate.js b/modules/pdp11/lib/cpustate.js index 09808b041..719962c81 100644 --- a/modules/pdp11/lib/cpustate.js +++ b/modules/pdp11/lib/cpustate.js @@ -481,13 +481,13 @@ CPUStatePDP11.prototype.setMMR3 = function(newMMR3) }; /** - * setReset(addr, fReset) + * setReset(addr, fStart) * * @this {CPUStatePDP11} * @param {number} addr - * @param {boolean} [fReset] (true if called in the context of a complete reset, obviating the need to notify the Debugger) + * @param {boolean|undefined} fStart (true if a "startable" image was just loaded, false if not) */ -CPUStatePDP11.prototype.setReset = function(addr, fReset) +CPUStatePDP11.prototype.setReset = function(addr, fStart) { this.addrReset = addr; @@ -495,17 +495,25 @@ CPUStatePDP11.prototype.setReset = function(addr, fReset) this.setPC(addr); this.setPSW(0); - if (!fReset && this.dbg) { - /* - * TODO: Review the decision to always stop the CPU if the Debugger is loaded. Note that - * when stopCPU() stops a running CPU, the Debugger gets notified, so again, no need to notify it here. - * - * TODO: There are more serious problems to deal with if another component is slamming a new PC down - * the CPU's throat (presumably while also dropping some new code into RAM) while the CPU was still running; - * we should probably force a complete reset if the CPU is running, but for now, it's up to the user - * to hit the reset button themselves. - */ - if (!this.stopCPU()) this.dbg.updateStatus(); + if (fStart) { + this.autoStart(); + } + else { + if (this.dbg) { + /* + * TODO: Review the decision to always stop the CPU if the Debugger is loaded. Note that + * when stopCPU() stops a running CPU, the Debugger gets notified, so again, no need to notify it here. + * + * TODO: There are more serious problems to deal with if another component is slamming a new PC down + * the CPU's throat (presumably while also dropping some new code into RAM) while the CPU was still running; + * we should probably force a complete reset if the CPU is running, but for now, it's up to the user + * to hit the reset button themselves. + */ + if (!this.stopCPU()) this.dbg.updateStatus(); + } + else if (fStart === false) { + this.stopCPU(); + } } }; diff --git a/modules/pdp11/lib/pc11.js b/modules/pdp11/lib/pc11.js index 3596c25fe..1c09e380c 100644 --- a/modules/pdp11/lib/pc11.js +++ b/modules/pdp11/lib/pc11.js @@ -44,8 +44,8 @@ if (NODE) { * The PC11 component has the following component-specific (parms) properties: * * autoMount: a JSON-encoded object containing 'name' and 'path' properties, describing a - * tape resource to automatically attach at startup (only the "attach" operation is supported - * for autoMount; if you want to "load" a tape image directly into RAM at startup, you must + * tape resource to automatically load at startup (only the "load" operation is supported + * for autoMount; if you want to "read" a tape image directly into RAM at startup, you must * ask the RAM component to do that). * * baudReceive: the default number of bits/second that the device should receive data at; @@ -67,11 +67,13 @@ function PC11(parms) { Component.call(this, "PC11", parms, PC11); + this.sDevice = "PTR"; // TODO: Make the device name configurable + /* * We record any 'autoMount' object now, but we no longer parse it until initBus(), because the * Computer's getMachineParm() service may have an override for us. */ - this.configMount = parms['autoMount'] || null; + this.configMount = this.parseConfig(parms['autoMount']); this.cAutoMount = 0; this.nBaudReceive = parms['baudReceive'] || PDP11.PC11.PRS.BAUD; @@ -124,6 +126,30 @@ PC11.CSSCLASS = { PROGRESS_BAR: PDP11.CSSCLASS + "-progress-bar" }; +/** + * parseConfig(config) + * + * @this {PC11} + * @param {*} config + * @return {*} + */ +PC11.prototype.parseConfig = function(config) +{ + if (config && typeof config == "string") { + try { + /* + * The most likely source of any exception will be right here, where we're parsing + * this JSON-encoded data. + */ + config = eval("(" + config + ")"); + } catch (e) { + Component.error(this.type + " auto-mount error: " + e.message + " (" + config + ")"); + config = null; + } + } + return config || {}; +}; + /** * setBinding(sType, sBinding, control, sValue) * @@ -170,18 +196,18 @@ PC11.prototype.setBinding = function(sType, sBinding, control, sValue) return true; /* - * "loadTape" operation must do pretty much everything that the "attachTape" does, but whereas the attach - * operation records the bytes in aTapeData, the load operation stuffs them directly into the machine's memory; + * "readTape" operation must do pretty much everything that the "loadTape" does, but whereas the load + * operation records the bytes in aTapeData, the read operation stuffs them directly into the machine's memory; * the former sets nTapeTarget to TARGET.READER, while the latter sets it to TARGET.MEMORY. */ - case "loadTape": + case "readTape": nTapeTarget = PC11.TARGET.MEMORY; /* falls through */ - case "attachTape": + case "loadTape": if (!nTapeTarget) nTapeTarget = PC11.TARGET.READER; this.bindings[sBinding] = control; - control.onclick = function onClickLoadTape(event) { + control.onclick = function onClickReadTape(event) { var controlTapes = pc11.bindings["listTapes"]; if (controlTapes) { var sTapeName = controlTapes.options[controlTapes.selectedIndex].text; @@ -263,20 +289,15 @@ PC11.prototype.initBus = function(cmp, bus, cpu, dbg) var pc11 = this; - this.configMount = this.cmp.getMachineParm('autoMount') || this.configMount; + var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount')); - if (this.configMount) { - if (typeof this.configMount == "string") { - try { - /* - * The most likely source of any exception will be right here, where we're parsing - * this JSON-encoded data. - */ - this.configMount = eval("(" + this.configMount + ")"); - } catch (e) { - Component.error("PC11 auto-mount error: " + e.message + " (" + this.configMount + ")"); - this.configMount = null; - } + /* + * Add only devices from the machine-wide autoMount configuration that match devices managed by this component. + */ + if (configMount) { + for (var sDevice in configMount) { + if (sDevice != this.sDevice) continue; + this.configMount[sDevice] = configMount[sDevice]; } } @@ -332,7 +353,7 @@ PC11.prototype.powerDown = function(fSave, fShutdown) /** * reset() * - * TODO: Consider making our reset() handler ALSO restore the original attached tape, in much the same + * TODO: Consider making our reset() handler ALSO restore the original loaded tape, in much the same * way the RAM component now restores the original predefined memory or tape image after resetting the RAM. * * @this {PC11} @@ -353,9 +374,10 @@ PC11.prototype.reset = function() PC11.prototype.autoMount = function(fRemount) { if (!fRemount) this.cAutoMount = 0; - if (this.configMount) { - var sTapePath = this.configMount['path'] || ""; - var sTapeName = this.configMount['name'] || this.findTape(sTapePath); + var configMount = this.configMount[this.sDevice]; + if (configMount) { + var sTapePath = configMount['path'] || ""; + var sTapeName = configMount['name'] || this.findTape(sTapePath); if (sTapePath && sTapeName) { /* * TODO: Provide a way to autoMount tapes into MEMORY as well as READER. @@ -460,7 +482,7 @@ PC11.prototype.loadTape = function(sTapeName, sTapePath, nTapeTarget, fAutoMount * Now that we're calling parseTape() again (so that the current tape can either be restarted on * the reader or reloaded into RAM), we can also rely on it to display an appropriate status message, too. * - * this.status(this.nTapeTarget == PC11.TARGET.READER? "tape attached" : "tape loaded"); + * this.status(this.nTapeTarget == PC11.TARGET.READER? "tape loaded" : "tape read"); */ this.parseTape(this.sTapeName, this.sTapePath, this.nTapeTarget, this.aBytes, this.addrLoad, this.addrExec); } @@ -705,23 +727,28 @@ PC11.prototype.parseTape = function(sTapeName, sTapePath, nTapeTarget, aBytes, a * * For example, the "Absolute Loader" tape is NOT itself in the Absolute Loader format. You just have * to know that in order to load that tape, you must first load the appropriate "Bootstrap Loader" (which - * DOES include its own hard-coded load address), attach the "Absolute Loader" tape, and then run the + * DOES include its own hard-coded load address), load the "Absolute Loader" tape, and then run the * "Bootstrap Loader". */ - if (!this.ram || !this.ram.loadImage(aBytes, addrLoad, addrExec)) { - this.sTapeName = ""; - this.sTapePath = ""; - this.sTapeSource = PC11.SOURCE.NONE; - this.nTapeTarget = PC11.TARGET.NONE; - this.notice('No load address available for tape "' + sTapeName + '"'); + if (!this.ram || !this.ram.loadImage(aBytes, addrLoad, addrExec, null, false)) { + /* + * This doesn't seem to serve any purpose, other than to be annoying, because perhaps you accidentally + * clicked "Read" instead of "Load".... + * + * this.sTapeName = ""; + * this.sTapePath = ""; + * this.sTapeSource = PC11.SOURCE.NONE; + * this.nTapeTarget = PC11.TARGET.NONE; + */ + this.notice('No valid memory address for tape "' + sTapeName + '"'); return; } - this.status('Loaded tape "' + sTapeName + '"'); + this.status('Read tape "' + sTapeName + '"'); return; } this.iTapeData = 0; this.aTapeData = aBytes; - this.status('Attached tape "' + sTapeName + '"'); + this.status('Loaded tape "' + sTapeName + '"'); this.displayProgress(0); }; diff --git a/modules/pdp11/lib/ram.js b/modules/pdp11/lib/ram.js index 16a9d7b78..e9e937d02 100644 --- a/modules/pdp11/lib/ram.js +++ b/modules/pdp11/lib/ram.js @@ -260,7 +260,7 @@ RAMPDP11.prototype.reset = function() }; /** - * loadImage(aBytes, addrLoad, addrExec, addrInit, fReset) + * loadImage(aBytes, addrLoad, addrExec, addrInit, fStart) * * If the array contains a PAPER tape image in the "Absolute Format," load it as specified * by the format; otherwise, load it as-is using the address(es) supplied. @@ -270,11 +270,12 @@ RAMPDP11.prototype.reset = function() * @param {number|null} [addrLoad] * @param {number|null} [addrExec] (this CAN override any starting address INSIDE the image) * @param {number|null} [addrInit] - * @param {boolean} [fReset] + * @param {boolean} [fStart] * @return {boolean} (true if loaded, false if not) */ -RAMPDP11.prototype.loadImage = function(aBytes, addrLoad, addrExec, addrInit, fReset) +RAMPDP11.prototype.loadImage = function(aBytes, addrLoad, addrExec, addrInit, fStart) { + var fStop = false; var fLoaded = false; /* * Data on tapes in the "Absolute Format" is organized into blocks; each block begins with @@ -343,7 +344,7 @@ RAMPDP11.prototype.loadImage = function(aBytes, addrLoad, addrExec, addrInit, fR } if (!cbData) { if (addr & 0x1) { - this.cpu.stopCPU(); + fStop = true; } else { if (addrExec == null) addrExec = addr; } @@ -375,7 +376,13 @@ RAMPDP11.prototype.loadImage = function(aBytes, addrLoad, addrExec, addrInit, fR * image, but we know that the directions for that diagnostic say to "Start and Restart at 200", * so we have manually inserted an "exec":128 in the JSON containing the image. */ - if (addrExec != null) this.cpu.setReset(addrExec, fReset); + if (addrExec == null || fStop) { + this.cpu.stopCPU(); + fStart = false; + } + if (addrExec != null) { + this.cpu.setReset(addrExec, fStart); + } } return fLoaded; }; diff --git a/modules/pdp11/lib/rk11.js b/modules/pdp11/lib/rk11.js index aac69cb3f..34daa709f 100644 --- a/modules/pdp11/lib/rk11.js +++ b/modules/pdp11/lib/rk11.js @@ -65,7 +65,7 @@ function RK11(parms) * We record any 'autoMount' object now, but we no longer parse it until initBus(), * because the Computer's getMachineParm() service may have an override for us. */ - this.configMount = parms['autoMount'] || {}; + this.configMount = this.parseConfig(parms['autoMount']); this.cAutoMount = 0; /* @@ -88,6 +88,30 @@ RK11.SOURCE = { REMOTE: "??" }; +/** + * parseConfig(config) + * + * @this {RK11} + * @param {*} config + * @return {*} + */ +RK11.prototype.parseConfig = function(config) +{ + if (config && typeof config == "string") { + try { + /* + * The most likely source of any exception will be right here, where we're parsing + * this JSON-encoded data. + */ + config = eval("(" + config + ")"); + } catch (e) { + Component.error(this.type + " auto-mount error: " + e.message + " (" + config + ")"); + config = null; + } + } + return config || {}; +}; + /** * setBinding(sType, sBinding, control, sValue) * @@ -143,7 +167,7 @@ RK11.prototype.setBinding = function(sType, sBinding, control, sValue) }; return true; - case "loadDrive": + case "loadDisk": this.bindings[sBinding] = control; control.onclick = function onClickLoadDrive(event) { @@ -156,7 +180,15 @@ RK11.prototype.setBinding = function(sType, sBinding, control, sValue) }; return true; - case "saveDrive": + case "bootDisk": + this.bindings[sBinding] = control; + + control.onclick = function onClickBootDisk(event) { + rk11.bootSelectedDisk(); + }; + return true; + + case "saveDisk": /* * Yes, technically, this feature does not require "Local disk support" (which is really a reference * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there @@ -201,7 +233,7 @@ RK11.prototype.setBinding = function(sType, sBinding, control, sValue) }; return true; - case "mountDrive": + case "mountDisk": if (!this.fLocalDisks) { if (DEBUG) this.log("Local disk support not available"); /* @@ -263,21 +295,7 @@ RK11.prototype.initBus = function(cmp, bus, cpu, dbg) this.cpu = cpu; this.dbg = dbg; - var configMount = this.cmp.getMachineParm('autoMount'); - if (configMount) { - if (typeof configMount == "string") { - try { - /* - * The most likely source of any exception will be right here, where we're parsing - * this JSON-encoded data. - */ - configMount = eval("(" + configMount + ")"); - } catch (e) { - Component.error(this.type + " auto-mount error: " + e.message + " (" + configMount + ")"); - configMount = null; - } - } - } + var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount')); /* * Add only drives from the machine-wide autoMount configuration that match drives managed by this component. @@ -527,6 +545,33 @@ RK11.prototype.loadSelectedDrive = function(sDiskName, sDiskPath, file) this.loadDrive(iDrive, sDiskName, sDiskPath, false, file); }; +/** + * bootSelectedDisk() + * + * @this {RK11} + */ +RK11.prototype.bootSelectedDisk = function() +{ + var drive; + var controlDrives = this.bindings["listDrives"]; + var iDrive = controlDrives && str.parseInt(controlDrives.value, 10); + + if (iDrive == null || iDrive < 0 || iDrive >= this.aDrives.length || !(drive = this.aDrives[iDrive])) { + this.notice("Unable to boot the selected drive"); + return; + } + if (!drive.disk) { + this.notice("No disk loaded in the selected drive"); + return; + } + var err = this.readData(drive, 0, 0, 0, drive.cbSector >> 1, 0); + if (err) { + this.notice("Unable to read the boot sector (" + err + ")"); + return; + } + this.cpu.setReset(0, true); +}; + /** * loadDrive(iDrive, sDiskName, sDiskPath, fAutoMount, file) * @@ -639,7 +684,7 @@ RK11.prototype.finishLoadDrive = function onLoadDrive(drive, disk, sDiskName, sD * With the addition of notify(), users are now "alerted" whenever a disk has finished loading; * notify() is selective about its output, using print() if a print window is open, alert() otherwise. */ - this.notice("Mounted disk \"" + sDiskName + "\" in drive " + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount); + this.notice("Loaded disk \"" + sDiskName + "\" in drive " + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount); /* * Since you usually want the Computer to have focus again after loading a new disk, let's try automatically @@ -941,6 +986,7 @@ RK11.prototype.processCommand = function() case PDP11.RK11.FUNC.WRITE: if (!sFunc) sFunc = "WRITE"; + if (!fnReadWrite) fnReadWrite = this.writeData; iCylinder = (this.regRKDA & PDP11.RK11.RKDA.CA) >> PDP11.RK11.RKDA.SHIFT.CA; iHead = (this.regRKDA & PDP11.RK11.RKDA.HS) >> PDP11.RK11.RKDA.SHIFT.HS; @@ -950,8 +996,6 @@ RK11.prototype.processCommand = function() if (this.messageEnabled()) this.printMessage(this.type + ": " + sFunc + "(" + iCylinder + ":" + iHead + ":" + iSector + ") @" + str.toOct(addr) + "-" + str.toOct(addr + ((nWords - 1) << 1)), true); - if (!fnReadWrite) fnReadWrite = this.writeData; - if (iCylinder >= drive.nCylinders) { this.regRKER |= PDP11.RK11.RKER.DRE | PDP11.RK11.RKER.NXC; this.regRKCS |= PDP11.RK11.RKCS.HE | PDP11.RK11.RKCS.ERR; @@ -1023,9 +1067,9 @@ RK11.prototype.endReadWrite = function(err, iCylinder, iHead, iSector, nWords, a * @param {number} iSector * @param {number} nWords * @param {number} addr - * @param {boolean} fCheck - * @param {function(...)} done - * @return {boolean} true if complete, false if queued + * @param {boolean} [fCheck] + * @param {function(...)} [done] + * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any) */ RK11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, addr, fCheck, done) { @@ -1084,7 +1128,7 @@ RK11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, add } } } - return done(err, iCylinder, iHead, iSector, nWords, addr); + return done? done(err, iCylinder, iHead, iSector, nWords, addr) : err; }; /** @@ -1097,9 +1141,9 @@ RK11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, add * @param {number} iSector * @param {number} nWords * @param {number} addr - * @param {boolean} fCheck - * @param {function(...)} done - * @return {boolean} true if complete, false if queued + * @param {boolean} [fCheck] + * @param {function(...)} [done] + * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any) */ RK11.prototype.writeData = function(drive, iCylinder, iHead, iSector, nWords, addr, fCheck, done) { @@ -1157,7 +1201,7 @@ RK11.prototype.writeData = function(drive, iCylinder, iHead, iSector, nWords, ad } } } - return done(err, iCylinder, iHead, iSector, nWords, addr); + return done? done(err, iCylinder, iHead, iSector, nWords, addr) : err; }; /** diff --git a/modules/pdp11/lib/rl11.js b/modules/pdp11/lib/rl11.js index f7c60a5d5..1a29c8259 100644 --- a/modules/pdp11/lib/rl11.js +++ b/modules/pdp11/lib/rl11.js @@ -67,7 +67,7 @@ function RL11(parms) * We record any 'autoMount' object now, but we no longer parse it until initBus(), * because the Computer's getMachineParm() service may have an override for us. */ - this.configMount = parms['autoMount'] || {}; + this.configMount = this.parseConfig(parms['autoMount']); this.cAutoMount = 0; /* @@ -90,6 +90,30 @@ RL11.SOURCE = { REMOTE: "??" }; +/** + * parseConfig(config) + * + * @this {RL11} + * @param {*} config + * @return {*} + */ +RL11.prototype.parseConfig = function(config) +{ + if (config && typeof config == "string") { + try { + /* + * The most likely source of any exception will be right here, where we're parsing + * this JSON-encoded data. + */ + config = eval("(" + config + ")"); + } catch (e) { + Component.error(this.type + " auto-mount error: " + e.message + " (" + config + ")"); + config = null; + } + } + return config || {}; +}; + /** * setBinding(sType, sBinding, control, sValue) * @@ -145,7 +169,7 @@ RL11.prototype.setBinding = function(sType, sBinding, control, sValue) }; return true; - case "loadDrive": + case "loadDisk": this.bindings[sBinding] = control; control.onclick = function onClickLoadDrive(event) { @@ -158,7 +182,15 @@ RL11.prototype.setBinding = function(sType, sBinding, control, sValue) }; return true; - case "saveDrive": + case "bootDisk": + this.bindings[sBinding] = control; + + control.onclick = function onClickBootDisk(event) { + rl11.bootSelectedDisk(); + }; + return true; + + case "saveDisk": /* * Yes, technically, this feature does not require "Local disk support" (which is really a reference * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there @@ -203,7 +235,7 @@ RL11.prototype.setBinding = function(sType, sBinding, control, sValue) }; return true; - case "mountDrive": + case "mountDisk": if (!this.fLocalDisks) { if (DEBUG) this.log("Local disk support not available"); /* @@ -265,21 +297,7 @@ RL11.prototype.initBus = function(cmp, bus, cpu, dbg) this.cpu = cpu; this.dbg = dbg; - var configMount = this.cmp.getMachineParm('autoMount'); - if (configMount) { - if (typeof configMount == "string") { - try { - /* - * The most likely source of any exception will be right here, where we're parsing - * this JSON-encoded data. - */ - configMount = eval("(" + configMount + ")"); - } catch (e) { - Component.error(this.type + " auto-mount error: " + e.message + " (" + configMount + ")"); - configMount = null; - } - } - } + var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount')); /* * Add only drives from the machine-wide autoMount configuration that match drives managed by this component. @@ -529,6 +547,33 @@ RL11.prototype.loadSelectedDrive = function(sDiskName, sDiskPath, file) this.loadDrive(iDrive, sDiskName, sDiskPath, false, file); }; +/** + * bootSelectedDisk() + * + * @this {RL11} + */ +RL11.prototype.bootSelectedDisk = function() +{ + var drive; + var controlDrives = this.bindings["listDrives"]; + var iDrive = controlDrives && str.parseInt(controlDrives.value, 10); + + if (iDrive == null || iDrive < 0 || iDrive >= this.aDrives.length || !(drive = this.aDrives[iDrive])) { + this.notice("Unable to boot the selected drive"); + return; + } + if (!drive.disk) { + this.notice("No disk loaded in the selected drive"); + return; + } + var err = this.readData(drive, 0, 0, 0, drive.cbSector >> 1, 0); + if (err) { + this.notice("Unable to read the boot sector (" + err + ")"); + return; + } + this.cpu.setReset(0, true); +}; + /** * loadDrive(iDrive, sDiskName, sDiskPath, fAutoMount, file) * @@ -639,7 +684,7 @@ RL11.prototype.finishLoadDrive = function onLoadDrive(drive, disk, sDiskName, sD * With the addition of notify(), users are now "alerted" whenever a disk has finished loading; * notify() is selective about its output, using print() if a print window is open, alert() otherwise. */ - this.notice("Mounted disk \"" + sDiskName + "\" in drive " + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount); + this.notice("Loaded disk \"" + sDiskName + "\" in drive " + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount); /* * Since you usually want the Computer to have focus again after loading a new disk, let's try automatically @@ -901,8 +946,8 @@ RL11.prototype.initDrive = function(drive, iDrive, data) */ RL11.prototype.processCommand = function() { - var fnReadWrite; var fInterrupt = true; + var fnReadWrite, sFunc = ""; var iDrive = (this.regRLCS & PDP11.RL11.RLCS.DS) >> PDP11.RL11.RLCS.SHIFT.DS; var drive = this.aDrives[iDrive]; var disk = drive.disk; @@ -954,11 +999,14 @@ RL11.prototype.processCommand = function() break; case PDP11.RL11.FUNC.RDATA: + sFunc = "READ"; fnReadWrite = this.readData; /* falls through */ case PDP11.RL11.FUNC.WDATA: + if (!sFunc) sFunc = "WRITE"; if (!fnReadWrite) fnReadWrite = this.writeData; + iCylinder = this.regRLDA >> PDP11.RL11.RLDA.SHIFT.RW_CA; iHead = (this.regRLDA & PDP11.RL11.RLDA.RW_HS)? 1 : 0; iSector = this.regRLDA & PDP11.RL11.RLDA.RW_SA; @@ -966,12 +1014,11 @@ RL11.prototype.processCommand = function() this.regRLCS |= PDP11.RL11.ERRC.HNF | PDP11.RL11.RLCS.ERR; break; } - addr = (((this.regRLBE & PDP11.RL11.RLBE.MASK)) << 16) | this.regRLBA; // 22 bit mode nWords = (0x10000 - this.regRLMP) & 0xffff; - var pos = ((((iCylinder << 1) + iHead) * drive.nSectors) + iSector) * 128; - if (DEBUG && (this.messageEnabled(MessagesPDP11.READ) || this.messageEnabled(MessagesPDP11.WRITE))) { - console.log((fnReadWrite == this.readData? "readData" : "writeData") + "(pos=" + pos + ",addr=" + str.toOct(addr) + ",bytes=" + (nWords * 2) + ")"); - } + addr = (((this.regRLBE & PDP11.RL11.RLBE.MASK)) << 16) | this.regRLBA; // 22 bit mode + + if (this.messageEnabled()) this.printMessage(this.type + ": " + sFunc + "(" + iCylinder + ":" + iHead + ":" + iSector + ") @" + str.toOct(addr) + "-" + str.toOct(addr + ((nWords - 1) << 1)), true); + fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, this.endReadWrite.bind(this)); break; @@ -1021,8 +1068,8 @@ RL11.prototype.endReadWrite = function(err, iCylinder, iHead, iSector, nWords, a * @param {number} iSector * @param {number} nWords * @param {number} addr - * @param {function(...)} done - * @return {boolean} true if complete, false if queued + * @param {function(...)} [done] + * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any) */ RL11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, addr, done) { @@ -1091,7 +1138,7 @@ RL11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, add console.log("checksum: " + (checksum|0)); } - return done(err, iCylinder, iHead, iSector, nWords, addr); + return done? done(err, iCylinder, iHead, iSector, nWords, addr) : err; }; /** @@ -1104,8 +1151,8 @@ RL11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, add * @param {number} iSector * @param {number} nWords * @param {number} addr - * @param {function(...)} done - * @return {boolean} true if complete, false if queued + * @param {function(...)} [done] + * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any) */ RL11.prototype.writeData = function(drive, iCylinder, iHead, iSector, nWords, addr, done) { @@ -1173,7 +1220,7 @@ RL11.prototype.writeData = function(drive, iCylinder, iHead, iSector, nWords, ad console.log("checksum: " + (checksum|0)); } - return done(err, iCylinder, iHead, iSector, nWords, addr); + return done? done(err, iCylinder, iHead, iSector, nWords, addr) : err; }; /** diff --git a/pubs/pc/programming/Graphics_for_the_IBM_PC/demos/basic.xml b/pubs/pc/programming/Graphics_for_the_IBM_PC/demos/basic.xml index 4d534c534..fef99abac 100644 --- a/pubs/pc/programming/Graphics_for_the_IBM_PC/demos/basic.xml +++ b/pubs/pc/programming/Graphics_for_the_IBM_PC/demos/basic.xml @@ -9,7 +9,7 @@ BASIC Programs - Load + Load - +