Disk in current drive can now be saved as an IMG file, and groundwork has been laid for saving an entire machine
This commit is contained in:
parent
092f07fa9b
commit
9c2ec7a20b
17 changed files with 1684 additions and 1549 deletions
|
|
@ -12,7 +12,7 @@
|
||||||
<keyboard ref="/devices/pc/keyboard/keyboard-minimal.xml"/>
|
<keyboard ref="/devices/pc/keyboard/keyboard-minimal.xml"/>
|
||||||
<debugger id="debugger"/>
|
<debugger id="debugger"/>
|
||||||
<panel ref="/devices/pc/panel/wide.xml"/>
|
<panel ref="/devices/pc/panel/wide.xml"/>
|
||||||
<fdc ref="/disks/pc/compiled/library.xml" width="320px"/>
|
<fdc ref="/disks/pc/compiled/library.xml"/>
|
||||||
<chipset id="chipset" model="5160" sw1="01001001" pos="left" padleft="8px" padbottom="8px">
|
<chipset id="chipset" model="5160" sw1="01001001" pos="left" padleft="8px" padbottom="8px">
|
||||||
<control type="switches" label="SW1" binding="sw1" left="0px"/>
|
<control type="switches" label="SW1" binding="sw1" left="0px"/>
|
||||||
<control type="description" binding="swdesc" left="0px"/>
|
<control type="description" binding="swdesc" left="0px"/>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ machines:
|
||||||
uncompiled: true
|
uncompiled: true
|
||||||
autopower: false
|
autopower: false
|
||||||
build: build-pc
|
build: build-pc
|
||||||
|
sitemap: false
|
||||||
---
|
---
|
||||||
|
|
||||||
Build Your Own PC
|
Build Your Own PC
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<disk path="">None</disk>
|
<disk path="">None</disk>
|
||||||
<disk path="/disks/pc/cpm/1.1b/cpm86-disk1.json">CP/M-86 (Disk 1)</disk>
|
<disk path="/disks/pc/cpm/1.1b/cpm86-disk1.json">CP/M-86 (Disk 1)</disk>
|
||||||
<disk path="/disks/pc/cpm/1.1b/cpm86-disk2.json">CP/M-86 (Disk 2)</disk>
|
<disk path="/disks/pc/cpm/1.1b/cpm86-disk2.json">CP/M-86 (Disk 2)</disk>
|
||||||
<disk path="/disks/pc/diags/ibm/2.20/5150_5155_5160_ADVDIAG_220.json">IBM Advanced Diagnostics 2.20</disk>
|
<disk path="/disks/pc/diags/ibm/2.20/5150_5155_5160_ADVDIAG_220.json">IBM Diagnostics 2.20</disk>
|
||||||
<disk path="/disks/pc/dos/ibm/1.00/PCDOS100.json">PC-DOS 1.00</disk>
|
<disk path="/disks/pc/dos/ibm/1.00/PCDOS100.json">PC-DOS 1.00</disk>
|
||||||
<disk path="/disks/pc/dos/ibm/1.10/PCDOS110.json">PC-DOS 1.10</disk>
|
<disk path="/disks/pc/dos/ibm/1.10/PCDOS110.json">PC-DOS 1.10</disk>
|
||||||
<disk path="/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json">PC-DOS 2.00 (Disk 1)</disk>
|
<disk path="/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json">PC-DOS 2.00 (Disk 1)</disk>
|
||||||
|
|
@ -109,7 +109,7 @@
|
||||||
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DISK3.json">COMPAQ MS-DOS 3.31 (Disk 3)</disk>
|
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DISK3.json">COMPAQ MS-DOS 3.31 (Disk 3)</disk>
|
||||||
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DISK4.json">COMPAQ MS-DOS 3.31 (Disk 4)</disk>
|
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DISK4.json">COMPAQ MS-DOS 3.31 (Disk 4)</disk>
|
||||||
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DISK5.json">COMPAQ MS-DOS 3.31 (Disk 5)</disk>
|
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DISK5.json">COMPAQ MS-DOS 3.31 (Disk 5)</disk>
|
||||||
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DIAG.json">COMPAQ MS-DOS 3.31 (Diagnostics)</disk>
|
<disk path="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DIAG.json">COMPAQ MS-DOS 3.31 (Diags)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.0/OS210-INSTALL.json">IBM OS/2 1.0 (1.44M Install)</disk>
|
<disk path="/disks/pc/os2/ibm/1.0/OS210-INSTALL.json">IBM OS/2 1.0 (1.44M Install)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.0/OS210-DISK1.json">IBM OS/2 1.0 (1.44M Disk 1)</disk>
|
<disk path="/disks/pc/os2/ibm/1.0/OS210-DISK1.json">IBM OS/2 1.0 (1.44M Disk 1)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.0/OS210-DISK2.json">IBM OS/2 1.0 (1.44M Disk 2)</disk>
|
<disk path="/disks/pc/os2/ibm/1.0/OS210-DISK2.json">IBM OS/2 1.0 (1.44M Disk 2)</disk>
|
||||||
|
|
@ -119,8 +119,8 @@
|
||||||
<disk path="/disks/pc/os2/ibm/1.1/OS211-DISK02.json">IBM OS/2 1.1 (1.44M Disk 2)</disk>
|
<disk path="/disks/pc/os2/ibm/1.1/OS211-DISK02.json">IBM OS/2 1.1 (1.44M Disk 2)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.1/OS211-DISK03.json">IBM OS/2 1.1 (1.44M Disk 3)</disk>
|
<disk path="/disks/pc/os2/ibm/1.1/OS211-DISK03.json">IBM OS/2 1.1 (1.44M Disk 3)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.1/OS211-DISK04.json">IBM OS/2 1.1 (1.44M Disk 4)</disk>
|
<disk path="/disks/pc/os2/ibm/1.1/OS211-DISK04.json">IBM OS/2 1.1 (1.44M Disk 4)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.1/OS211-DEVICES.json">IBM OS/2 1.1 (1.44M Devices Disk)</disk>
|
<disk path="/disks/pc/os2/ibm/1.1/OS211-DEVICES.json">IBM OS/2 1.1 (1.44M Devices)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.1/OS211-PRINTERS.json">IBM OS/2 1.1 (1.44M Printers Disk)</disk>
|
<disk path="/disks/pc/os2/ibm/1.1/OS211-PRINTERS.json">IBM OS/2 1.1 (1.44M Printers)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.3/OS213-DISK01.json">IBM OS/2 1.3 (1.44M Disk 1)</disk>
|
<disk path="/disks/pc/os2/ibm/1.3/OS213-DISK01.json">IBM OS/2 1.3 (1.44M Disk 1)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.3/OS213-DISK02.json">IBM OS/2 1.3 (1.44M Disk 2)</disk>
|
<disk path="/disks/pc/os2/ibm/1.3/OS213-DISK02.json">IBM OS/2 1.3 (1.44M Disk 2)</disk>
|
||||||
<disk path="/disks/pc/os2/ibm/1.3/OS213-DISK03.json">IBM OS/2 1.3 (1.44M Disk 3)</disk>
|
<disk path="/disks/pc/os2/ibm/1.3/OS213-DISK03.json">IBM OS/2 1.3 (1.44M Disk 3)</disk>
|
||||||
|
|
@ -428,7 +428,8 @@
|
||||||
<disk path="/apps/pc/1992/moria/disk.json">Moria 5.5</disk>
|
<disk path="/apps/pc/1992/moria/disk.json">Moria 5.5</disk>
|
||||||
<disk path="/tests/pc/vga/VGABIN.json">VGA Tests (Black Book)</disk>
|
<disk path="/tests/pc/vga/VGABIN.json">VGA Tests (Black Book)</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>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?xml-stylesheet type="text/xsl" href="/versions/pcjs/1.20.9/manifest.xsl"?>
|
<?xml-stylesheet type="text/xsl" href="/versions/pcjs/1.20.9/manifest.xsl"?>
|
||||||
<manifest type="software">
|
<manifest type="software">
|
||||||
<title>IBM Advanced Diagnostics</title>
|
<title>IBM Diagnostics</title>
|
||||||
<version>2.20</version>
|
<version>2.20</version>
|
||||||
<type>Diagnostics</type>
|
<type>Diagnostics</type>
|
||||||
<category>Hardware Tests</category>
|
<category>Hardware Tests</category>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,6 @@
|
||||||
<name>COMPAQ MS-DOS 3.31 (Disk 5)</name>
|
<name>COMPAQ MS-DOS 3.31 (Disk 5)</name>
|
||||||
</disk>
|
</disk>
|
||||||
<disk id="disk06" size="368640" chs="40:2:9" img="archive/COMPAQ-DOS331-DIAG.img" href="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DIAG.json" md5="6fc3678180e8d8c2ff5e1c3d99f14d08" md5json="a5e0a418db4fe09c13cfd86635753a05">
|
<disk id="disk06" size="368640" chs="40:2:9" img="archive/COMPAQ-DOS331-DIAG.img" href="/disks/pc/dos/compaq/3.31/COMPAQ-DOS331-DIAG.json" md5="6fc3678180e8d8c2ff5e1c3d99f14d08" md5json="a5e0a418db4fe09c13cfd86635753a05">
|
||||||
<name>COMPAQ MS-DOS 3.31 (Diagnostics)</name>
|
<name>COMPAQ MS-DOS 3.31 (Diags)</name>
|
||||||
</disk>
|
</disk>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,8 @@
|
||||||
<manifest ref="/apps/pc/1992/moria/manifest.xml" disk="disk01"/>
|
<manifest ref="/apps/pc/1992/moria/manifest.xml" disk="disk01"/>
|
||||||
<disk path="/tests/pc/vga/VGABIN.json">VGA Tests (Black Book)</disk>
|
<disk path="/tests/pc/vga/VGABIN.json">VGA Tests (Black Book)</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>
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@
|
||||||
<name>IBM OS/2 1.1 (1.44M Disk 4)</name>
|
<name>IBM OS/2 1.1 (1.44M Disk 4)</name>
|
||||||
</disk>
|
</disk>
|
||||||
<disk id="disk05" size="1474560" chs="80:2:18" img="archive/OS211-DEVICES.img" href="/disks/pc/os2/ibm/1.1/OS211-DEVICES.json" md5="9d3dfde0206b562beae90cab21f9eba5" md5json="2cb39da33b61e762b87259b59bf5ccf5">
|
<disk id="disk05" size="1474560" chs="80:2:18" img="archive/OS211-DEVICES.img" href="/disks/pc/os2/ibm/1.1/OS211-DEVICES.json" md5="9d3dfde0206b562beae90cab21f9eba5" md5json="2cb39da33b61e762b87259b59bf5ccf5">
|
||||||
<name>IBM OS/2 1.1 (1.44M Devices Disk)</name>
|
<name>IBM OS/2 1.1 (1.44M Devices)</name>
|
||||||
</disk>
|
</disk>
|
||||||
<disk id="disk06" size="1474560" chs="80:2:18" img="archive/OS211-PRINTERS.img" href="/disks/pc/os2/ibm/1.1/OS211-PRINTERS.json" md5="36cd9ea1e7184872548598dae4b60cb8" md5json="3ddd4aa8468a17a42aa247cf7b447a65">
|
<disk id="disk06" size="1474560" chs="80:2:18" img="archive/OS211-PRINTERS.img" href="/disks/pc/os2/ibm/1.1/OS211-PRINTERS.json" md5="36cd9ea1e7184872548598dae4b60cb8" md5json="3ddd4aa8468a17a42aa247cf7b447a65">
|
||||||
<name>IBM OS/2 1.1 (1.44M Printers Disk)</name>
|
<name>IBM OS/2 1.1 (1.44M Printers)</name>
|
||||||
</disk>
|
</disk>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,7 @@
|
||||||
<xsl:when test="$url != ''"><div class="{$APPCLASS}-reference">[<a href="{$url}">XML</a>]</div></xsl:when>
|
<xsl:when test="$url != ''"><div class="{$APPCLASS}-reference">[<a href="{$url}">XML</a>]</div></xsl:when>
|
||||||
<xsl:otherwise/>
|
<xsl:otherwise/>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
|
<xsl:if test="$MACHINECLASS = 'pc'"><div class="{$APPCLASS}-reference" style="padding-left:8px">[<a href="#" onclick="savePC('{$machine}');">Save Machine</a>]</div></xsl:if>
|
||||||
<div class="{$APPCLASS}-copyright">
|
<div class="{$APPCLASS}-copyright">
|
||||||
<a href="http://{$SITEHOST}" target="_blank">PCjs</a> v<xsl:value-of select="$APPVERSION"/> © 2012-2016 by <a href="http://twitter.com/jeffpar" target="_blank">@jeffpar</a>
|
<a href="http://{$SITEHOST}" target="_blank">PCjs</a> v<xsl:value-of select="$APPVERSION"/> © 2012-2016 by <a href="http://twitter.com/jeffpar" target="_blank">@jeffpar</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1198,6 +1198,9 @@ Disk.prototype.doneLoad = function(sURL, sDiskData, nErrorCode)
|
||||||
if (DEBUG && this.messageEnabled()) {
|
if (DEBUG && this.messageEnabled()) {
|
||||||
this.printMessage('doneLoad("' + this.sDiskPath + '")');
|
this.printMessage('doneLoad("' + this.sDiskPath + '")');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.addMachineResource(this.controller.idMachine, sURL, sDiskData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
* The following code was a hack to turn on write-protection for a disk image if there was
|
* The following code was a hack to turn on write-protection for a disk image if there was
|
||||||
|
|
@ -1839,55 +1842,22 @@ Disk.prototype.getClusterEntry = function(dir, iCluster, iByte)
|
||||||
*
|
*
|
||||||
* @this {Disk}
|
* @this {Disk}
|
||||||
* @param {number} pba (physical block address)
|
* @param {number} pba (physical block address)
|
||||||
* @return {Object} sector
|
* @return {Object|null} sector
|
||||||
*/
|
*/
|
||||||
Disk.prototype.getSector = function(pba)
|
Disk.prototype.getSector = function(pba)
|
||||||
{
|
{
|
||||||
var nSectorsPerCylinder = this.nHeads * this.nSectors;
|
var nSectorsPerCylinder = this.nHeads * this.nSectors;
|
||||||
var iCylinder = (pba / nSectorsPerCylinder) | 0;
|
var iCylinder = (pba / nSectorsPerCylinder) | 0;
|
||||||
this.assert(iCylinder < this.nCylinders);
|
if (iCylinder < this.nCylinders) {
|
||||||
var nSectorsRemaining = (pba % nSectorsPerCylinder);
|
var nSectorsRemaining = (pba % nSectorsPerCylinder);
|
||||||
var iHead = (nSectorsRemaining / this.nSectors) | 0;
|
var iHead = (nSectorsRemaining / this.nSectors) | 0;
|
||||||
/*
|
/*
|
||||||
* PBA numbers are 0-based, but the sector numbers in CHS addressing are 1-based, so add one to iSector
|
* PBA numbers are 0-based, but the sector numbers in CHS addressing are 1-based, so add one to iSector
|
||||||
*/
|
*/
|
||||||
var iSector = (nSectorsRemaining % this.nSectors) + 1;
|
var iSector = (nSectorsRemaining % this.nSectors) + 1;
|
||||||
return this.seek(iCylinder, iHead, iSector);
|
return this.seek(iCylinder, iHead, iSector);
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* updateSector(file, pba, off)
|
|
||||||
*
|
|
||||||
* Like getSector(), this must convert a PBA into CHS values; consider factoring that conversion code out.
|
|
||||||
*
|
|
||||||
* @this {Disk}
|
|
||||||
* @param {Object} file
|
|
||||||
* @param {number} pba (physical block address from the file's apba)
|
|
||||||
* @param {number} off (file offset corresponding to the given pba of the given file)
|
|
||||||
* @return {boolean} true if successfully updated, false if not
|
|
||||||
*/
|
|
||||||
Disk.prototype.updateSector = function(file, pba, off)
|
|
||||||
{
|
|
||||||
var nSectorsPerCylinder = this.nHeads * this.nSectors;
|
|
||||||
var iCylinder = (pba / nSectorsPerCylinder) | 0;
|
|
||||||
var nSectorsRemaining = (pba % nSectorsPerCylinder);
|
|
||||||
var iHead = (nSectorsRemaining / this.nSectors) | 0;
|
|
||||||
var iSector = (nSectorsRemaining % this.nSectors);
|
|
||||||
var cylinder, head, sector;
|
|
||||||
if ((cylinder = this.aDiskData[iCylinder]) && (head = cylinder[iHead]) && (sector = head[iSector])) {
|
|
||||||
this.assert(sector['sector'] == iSector +1);
|
|
||||||
if (sector['file']) {
|
|
||||||
if (DEBUG && this.messageEnabled()) {
|
|
||||||
this.printMessage('"' + sector['file'].sPath + '" cross-linked at offset ' + sector['file'].offFile + ' with "' + file.sPath + '" at offset ' + off);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sector['file'] = file;
|
|
||||||
sector.offFile = off;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (DEBUG && this.messageEnabled()) this.printMessage("unable to map PBA " + pba + " to CHS");
|
return null;
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1943,6 +1913,41 @@ Disk.prototype.getSectorString = function(sector, off, len)
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updateSector(file, pba, off)
|
||||||
|
*
|
||||||
|
* Like getSector(), this must convert a PBA into CHS values; consider factoring that conversion code out.
|
||||||
|
*
|
||||||
|
* @this {Disk}
|
||||||
|
* @param {Object} file
|
||||||
|
* @param {number} pba (physical block address from the file's apba)
|
||||||
|
* @param {number} off (file offset corresponding to the given pba of the given file)
|
||||||
|
* @return {boolean} true if successfully updated, false if not
|
||||||
|
*/
|
||||||
|
Disk.prototype.updateSector = function(file, pba, off)
|
||||||
|
{
|
||||||
|
var nSectorsPerCylinder = this.nHeads * this.nSectors;
|
||||||
|
var iCylinder = (pba / nSectorsPerCylinder) | 0;
|
||||||
|
var nSectorsRemaining = (pba % nSectorsPerCylinder);
|
||||||
|
var iHead = (nSectorsRemaining / this.nSectors) | 0;
|
||||||
|
var iSector = (nSectorsRemaining % this.nSectors);
|
||||||
|
var cylinder, head, sector;
|
||||||
|
if ((cylinder = this.aDiskData[iCylinder]) && (head = cylinder[iHead]) && (sector = head[iSector])) {
|
||||||
|
this.assert(sector['sector'] == iSector +1);
|
||||||
|
if (sector['file']) {
|
||||||
|
if (DEBUG && this.messageEnabled()) {
|
||||||
|
this.printMessage('"' + sector['file'].sPath + '" cross-linked at offset ' + sector['file'].offFile + ' with "' + file.sPath + '" at offset ' + off);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sector['file'] = file;
|
||||||
|
sector.offFile = off;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (DEBUG && this.messageEnabled()) this.printMessage("unable to map PBA " + pba + " to CHS");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)
|
* initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)
|
||||||
*
|
*
|
||||||
|
|
@ -2497,6 +2502,7 @@ Disk.prototype.write = function(sector, ibSector, b)
|
||||||
var dwPattern = sector['pattern'];
|
var dwPattern = sector['pattern'];
|
||||||
var idw = ibSector >> 2;
|
var idw = ibSector >> 2;
|
||||||
var nShift = (ibSector & 0x3) << 3;
|
var nShift = (ibSector & 0x3) << 3;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure every byte up to the specified byte is properly initialized.
|
* Ensure every byte up to the specified byte is properly initialized.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2520,6 +2526,26 @@ Disk.prototype.write = function(sector, ibSector, b)
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodeAsBase64()
|
||||||
|
*
|
||||||
|
* @this {Disk}
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
Disk.prototype.encodeAsBase64 = function()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Gross, but simple; more importantly, it works -- at least for disks of typical floppy magnitude.
|
||||||
|
*/
|
||||||
|
var s = "", pba = 0, sector;
|
||||||
|
while ((sector = this.getSector(pba++))) {
|
||||||
|
for (var off = 0, len = sector['length']; off < len; off++) {
|
||||||
|
s += String.fromCharCode(this.getSectorData(sector, off, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return btoa(s);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save()
|
* save()
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,37 @@ FDC.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
||||||
};
|
};
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case "saveDrive":
|
||||||
|
this.bindings[sBinding] = control;
|
||||||
|
control.onclick = function onClickLoadDrive(event) {
|
||||||
|
var controlDrives = fdc.bindings["listDrives"];
|
||||||
|
if (controlDrives && controlDrives.options && fdc.aDrives) {
|
||||||
|
var iDriveSelected = str.parseInt(controlDrives.value, 10);
|
||||||
|
var drive = fdc.aDrives[iDriveSelected];
|
||||||
|
if (drive) {
|
||||||
|
if (drive.disk) {
|
||||||
|
if (DEBUG) fdc.println("saving disk " + drive.disk.sDiskPath + "...");
|
||||||
|
var uri = "data:application/octet-stream;base64," + drive.disk.encodeAsBase64();
|
||||||
|
var link = document.createElement('a');
|
||||||
|
if (typeof link.download == 'string') {
|
||||||
|
link.href = uri;
|
||||||
|
link.download = drive.disk.sDiskFile.replace(".json", ".img");
|
||||||
|
document.body.appendChild(link); // Firefox requires the link to be in the body (?)
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
} else {
|
||||||
|
window.open(uri);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fdc.notice("No disk loaded in drive");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fdc.notice("No drive selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
|
||||||
case "mountDrive":
|
case "mountDrive":
|
||||||
if (this.fLocalDisks) {
|
if (this.fLocalDisks) {
|
||||||
this.bindings[sBinding] = control;
|
this.bindings[sBinding] = control;
|
||||||
|
|
@ -1229,10 +1260,10 @@ FDC.prototype.loadSelectedDrive = function(sDisketteName, sDiskettePath, file)
|
||||||
sDiskettePath = window.prompt("Enter the URL of a remote disk image.", "") || "";
|
sDiskettePath = window.prompt("Enter the URL of a remote disk image.", "") || "";
|
||||||
if (!sDiskettePath) return;
|
if (!sDiskettePath) return;
|
||||||
sDisketteName = str.getBaseName(sDiskettePath);
|
sDisketteName = str.getBaseName(sDiskettePath);
|
||||||
this.println("Attempting to load " + sDiskettePath + " as \"" + sDisketteName + "\"");
|
if (DEBUG) this.println("Attempting to load " + sDiskettePath + " as \"" + sDisketteName + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.println("loading disk " + sDiskettePath + "...");
|
if (DEBUG) this.println("loading disk " + sDiskettePath + "...");
|
||||||
|
|
||||||
while (this.loadDiskette(iDrive, sDisketteName, sDiskettePath, false, file)) {
|
while (this.loadDiskette(iDrive, sDisketteName, sDiskettePath, false, file)) {
|
||||||
if (!window.confirm("Click OK to reload the original disk.\n(WARNING: All disk changes will be discarded)")) {
|
if (!window.confirm("Click OK to reload the original disk.\n(WARNING: All disk changes will be discarded)")) {
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,9 @@ ROM.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
||||||
this.notice("Unable to load system ROM (error " + nErrorCode + ": " + sURL + ")");
|
this.notice("Unable to load system ROM (error " + nErrorCode + ": " + sURL + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.addMachineResource(this.idMachine, sURL, sROMData);
|
||||||
|
|
||||||
if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") {
|
if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") {
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -3724,6 +3724,9 @@ Video.prototype.doneLoad = function(sURL, sFontData, nErrorCode)
|
||||||
this.notice("Unable to load font ROM (error " + nErrorCode + ": " + sURL + ")");
|
this.notice("Unable to load font ROM (error " + nErrorCode + ": " + sURL + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.addMachineResource(this.idMachine, sURL, sFontData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
* The most likely source of any exception will be right here, where we're parsing the JSON-encoded data.
|
* The most likely source of any exception will be right here, where we're parsing the JSON-encoded data.
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,7 @@
|
||||||
<xsl:when test="$url != ''"><div class="{$APPCLASS}-reference">[<a href="{$url}">XML</a>]</div></xsl:when>
|
<xsl:when test="$url != ''"><div class="{$APPCLASS}-reference">[<a href="{$url}">XML</a>]</div></xsl:when>
|
||||||
<xsl:otherwise/>
|
<xsl:otherwise/>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
|
<xsl:if test="$MACHINECLASS = 'pc'"><div class="{$APPCLASS}-reference" style="padding-left:8px">[<a href="#" onclick="savePC('{$machine}');">Save Machine</a>]</div></xsl:if>
|
||||||
<div class="{$APPCLASS}-copyright">
|
<div class="{$APPCLASS}-copyright">
|
||||||
<a href="http://{$SITEHOST}" target="_blank">PCjs</a> v<xsl:value-of select="$APPVERSION"/> © 2012-2016 by <a href="http://twitter.com/jeffpar" target="_blank">@jeffpar</a>
|
<a href="http://{$SITEHOST}" target="_blank">PCjs</a> v<xsl:value-of select="$APPVERSION"/> © 2012-2016 by <a href="http://twitter.com/jeffpar" target="_blank">@jeffpar</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ Component.subclass = function(subclass, superclass, methods, statics)
|
||||||
* This enables any component to locate another component by ID (see Component.getComponentByID())
|
* This enables any component to locate another component by ID (see Component.getComponentByID())
|
||||||
* or by type (see Component.getComponentByType()).
|
* or by type (see Component.getComponentByType()).
|
||||||
*/
|
*/
|
||||||
Component.all = [];
|
Component.components = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component.add(component)
|
* Component.add(component)
|
||||||
|
|
@ -225,11 +225,57 @@ Component.all = [];
|
||||||
Component.add = function(component)
|
Component.add = function(component)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This just generates a lot of useless noise, handy in the early days, not so much these days...
|
* This just generates a lot of useless noise, handy in the early days, not so much these days....
|
||||||
*
|
*
|
||||||
* if (DEBUG) Component.log("Component.add(" + component.type + "," + component.id + ")");
|
* if (DEBUG) Component.log("Component.add(" + component.type + "," + component.id + ")");
|
||||||
*/
|
*/
|
||||||
Component.all[Component.all.length] = 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)
|
||||||
|
*
|
||||||
|
* @param {string} idMachine
|
||||||
|
*/
|
||||||
|
Component.addMachine = function(idMachine)
|
||||||
|
{
|
||||||
|
Component.machines[idMachine] = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component.addMachineResource(idMachine, sName, data)
|
||||||
|
*
|
||||||
|
* @param {string} idMachine
|
||||||
|
* @param {string} sName (name of the resource)
|
||||||
|
* @param {*} data
|
||||||
|
*/
|
||||||
|
Component.addMachineResource = function(idMachine, sName, data)
|
||||||
|
{
|
||||||
|
Component.assert(Component.machines[idMachine]);
|
||||||
|
if (Component.machines[idMachine]) {
|
||||||
|
if (!Component.machines[idMachine][sName]) {
|
||||||
|
Component.machines[idMachine][sName] = [];
|
||||||
|
}
|
||||||
|
Component.machines[idMachine][sName].push(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component.getMachineResources(idMachine, sName)
|
||||||
|
*
|
||||||
|
* @param {string} idMachine
|
||||||
|
* @param {string} sName (name of the resource)
|
||||||
|
* @return {Array|undefined}
|
||||||
|
*/
|
||||||
|
Component.getMachineResources = function(idMachine, sName)
|
||||||
|
{
|
||||||
|
return Component.machines[idMachine] && Component.machines[idMachine][sName];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -343,8 +389,8 @@ Component.error = function(s)
|
||||||
/**
|
/**
|
||||||
* Component.getComponents(idRelated)
|
* Component.getComponents(idRelated)
|
||||||
*
|
*
|
||||||
* We could store components as properties of an 'all' object, using the component's ID,
|
* We could store components as properties, using the component's ID, and change
|
||||||
* and change this linear lookup into a property lookup, but some components may have no ID.
|
* this linear lookup into a property lookup, but some components may have no ID.
|
||||||
*
|
*
|
||||||
* @param {string} [idRelated] of related component
|
* @param {string} [idRelated] of related component
|
||||||
* @return {Array} of components
|
* @return {Array} of components
|
||||||
|
|
@ -366,8 +412,8 @@ Component.getComponents = function(idRelated)
|
||||||
else
|
else
|
||||||
idRelated = "";
|
idRelated = "";
|
||||||
}
|
}
|
||||||
for (i = 0; i < Component.all.length; i++) {
|
for (i = 0; i < Component.components.length; i++) {
|
||||||
var component = Component.all[i];
|
var component = Component.components[i];
|
||||||
if (!idRelated || !component.id.indexOf(idRelated)) {
|
if (!idRelated || !component.id.indexOf(idRelated)) {
|
||||||
aComponents.push(component);
|
aComponents.push(component);
|
||||||
}
|
}
|
||||||
|
|
@ -378,8 +424,8 @@ Component.getComponents = function(idRelated)
|
||||||
/**
|
/**
|
||||||
* Component.getComponentByID(id, idRelated)
|
* Component.getComponentByID(id, idRelated)
|
||||||
*
|
*
|
||||||
* We could store components as properties of an 'all' object, using the component's ID,
|
* We could store components as properties, using the component's ID, and change
|
||||||
* and change this linear lookup into a property lookup, but some components may have no ID.
|
* this linear lookup into a property lookup, but some components may have no ID.
|
||||||
*
|
*
|
||||||
* @param {string} id of the desired component
|
* @param {string} id of the desired component
|
||||||
* @param {string} [idRelated] of related component
|
* @param {string} [idRelated] of related component
|
||||||
|
|
@ -397,9 +443,9 @@ Component.getComponentByID = function(id, idRelated)
|
||||||
if (idRelated && (i = idRelated.indexOf('.')) > 0) {
|
if (idRelated && (i = idRelated.indexOf('.')) > 0) {
|
||||||
id = idRelated.substr(0, i + 1) + id;
|
id = idRelated.substr(0, i + 1) + id;
|
||||||
}
|
}
|
||||||
for (i = 0; i < Component.all.length; i++) {
|
for (i = 0; i < Component.components.length; i++) {
|
||||||
if (Component.all[i].id === id) {
|
if (Component.components[i].id === id) {
|
||||||
return Component.all[i];
|
return Component.components[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.log("Component ID '" + id + "' not found", "warning");
|
Component.log("Component ID '" + id + "' not found", "warning");
|
||||||
|
|
@ -431,13 +477,13 @@ Component.getComponentByType = function(sType, idRelated, componentPrev)
|
||||||
idRelated = "";
|
idRelated = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < Component.all.length; i++) {
|
for (i = 0; i < Component.components.length; i++) {
|
||||||
if (componentPrev) {
|
if (componentPrev) {
|
||||||
if (componentPrev == Component.all[i]) componentPrev = null;
|
if (componentPrev == Component.components[i]) componentPrev = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sType == Component.all[i].type && (!idRelated || !Component.all[i].id.indexOf(idRelated))) {
|
if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {
|
||||||
return Component.all[i];
|
return Component.components[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.log("Component type '" + sType + "' not found", "warning");
|
Component.log("Component type '" + sType + "' not found", "warning");
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
/* global document: true, window: true, XSLTProcessor: false, APPNAME: false, APPVERSION: false, DEBUG: true */
|
/* global document: true, window: true, XSLTProcessor: false, APPNAME: false, APPVERSION: false, DEBUG: true */
|
||||||
|
|
||||||
if (NODE) {
|
if (NODE) {
|
||||||
var Component;
|
var Component = require("./component");
|
||||||
var str = require("./strlib");
|
var str = require("./strlib");
|
||||||
var web = require("./weblib");
|
var web = require("./weblib");
|
||||||
}
|
}
|
||||||
|
|
@ -52,8 +52,8 @@ if (NODE) {
|
||||||
* notification events at the start of the embedding process (web.enablePageEvents(false)) and
|
* notification events at the start of the embedding process (web.enablePageEvents(false)) and
|
||||||
* re-enable them at the end (web.enablePageEvents(true)).
|
* re-enable them at the end (web.enablePageEvents(true)).
|
||||||
*/
|
*/
|
||||||
var cMachines = 0;
|
|
||||||
var fAsync = true;
|
var fAsync = true;
|
||||||
|
var cAsyncMachines = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* loadXML(sFile, idMachine, sParms, fResolve, display, done)
|
* loadXML(sFile, idMachine, sParms, fResolve, display, done)
|
||||||
|
|
@ -305,27 +305,28 @@ function resolveXML(sXML, display, done)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sParms)
|
* embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
||||||
*
|
*
|
||||||
* This allows to you embed a machine on a web page, by transforming the machine XML into HTML.
|
* This allows to you embed a machine on a web page, by transforming the machine XML into HTML.
|
||||||
*
|
*
|
||||||
* @param {string} sName is the app name (eg, "PCjs")
|
* @param {string} sName is the app name (eg, "PCjs")
|
||||||
* @param {string} sVersion is the app version (eg, "1.15.7")
|
* @param {string} sVersion is the app version (eg, "1.15.7")
|
||||||
* @param {string} idElement
|
* @param {string} idMachine
|
||||||
* @param {string} sXMLFile
|
* @param {string} sXMLFile
|
||||||
* @param {string} sXSLFile
|
* @param {string} sXSLFile
|
||||||
* @param {string} [sParms]
|
* @param {string} [sParms]
|
||||||
* @return {boolean} true if successful, false if error
|
* @return {boolean} true if successful, false if error
|
||||||
*/
|
*/
|
||||||
function embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sParms)
|
function embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
||||||
{
|
{
|
||||||
var eMachine, eWarning, fSuccess = true;
|
var eMachine, eWarning, fSuccess = true;
|
||||||
|
|
||||||
cMachines++;
|
cAsyncMachines++;
|
||||||
|
Component.addMachine(idMachine);
|
||||||
|
|
||||||
var doneMachine = function() {
|
var doneMachine = function() {
|
||||||
Component.assert(cMachines > 0);
|
Component.assert(cAsyncMachines > 0);
|
||||||
if (!--cMachines) {
|
if (!--cAsyncMachines) {
|
||||||
if (fAsync) web.enablePageEvents(true);
|
if (fAsync) web.enablePageEvents(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -358,7 +359,7 @@ function embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sParms)
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
eMachine = document.getElementById(idElement);
|
eMachine = document.getElementById(idMachine);
|
||||||
if (eMachine) {
|
if (eMachine) {
|
||||||
var sAppClass = sName.toLowerCase(); // eg, "pcjs" or "c1pjs"
|
var sAppClass = sName.toLowerCase(); // eg, "pcjs" or "c1pjs"
|
||||||
if (!sXSLFile) {
|
if (!sXSLFile) {
|
||||||
|
|
@ -380,6 +381,7 @@ function embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sParms)
|
||||||
displayError(sXML);
|
displayError(sXML);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Component.addMachineResource(idMachine, 'xml', sXML);
|
||||||
/*
|
/*
|
||||||
* Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;
|
* Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;
|
||||||
* we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.
|
* we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.
|
||||||
|
|
@ -393,82 +395,75 @@ function embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sParms)
|
||||||
displayError(sXSL);
|
displayError(sXSL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (xsl) {
|
Component.addMachineResource(idMachine, 'xsl', sXSL);
|
||||||
/*
|
/*
|
||||||
* The <machine> template in components.xsl now generates a "machine div" that makes
|
* The <machine> template in components.xsl now generates a "machine div" that makes
|
||||||
* the div we required the caller of embedMachine() to provide redundant, so instead
|
* the div we required the caller of embedMachine() to provide redundant, so instead
|
||||||
* of appending this fragment to the caller's node, we REPLACE the caller's node.
|
* of appending this fragment to the caller's node, we REPLACE the caller's node.
|
||||||
* This works only because because we ALSO inject the caller's "machine div" ID into
|
* This works only because because we ALSO inject the caller's "machine div" ID into
|
||||||
* the fragment's ID during parseXML().
|
* the fragment's ID during parseXML().
|
||||||
*
|
*
|
||||||
* eMachine.innerHTML = sFragment;
|
* eMachine.innerHTML = sFragment;
|
||||||
*
|
*
|
||||||
* Also, if the transform function fails, make sure you're using the appropriate
|
* Also, if the transform function fails, make sure you're using the appropriate
|
||||||
* "components.xsl" and not a "machine.xsl", because the latter will not produce valid
|
* "components.xsl" and not a "machine.xsl", because the latter will not produce valid
|
||||||
* embeddable HTML (and is the most common cause of failure at this final stage).
|
* embeddable HTML (and is the most common cause of failure at this final stage).
|
||||||
*/
|
*/
|
||||||
displayMessage("Processing " + sXMLFile + "...");
|
displayMessage("Processing " + sXMLFile + "...");
|
||||||
/*
|
/*
|
||||||
* Beginning with Microsoft Edge and the corresponding release of Windows 10, all the
|
* Beginning with Microsoft Edge and the corresponding release of Windows 10, all the
|
||||||
* 'ActiveXObject' crud has gone away; but of course, this code must remain in place if
|
* 'ActiveXObject' crud has gone away; but of course, this code must remain in place if
|
||||||
* we want to continue supporting older Internet Explorer browsers (ie, back to IE9).
|
* we want to continue supporting older Internet Explorer browsers (ie, back to IE9).
|
||||||
*/
|
*/
|
||||||
if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1
|
if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1
|
||||||
var sFragment = xml['transformNode'](xsl);
|
var sFragment = xml['transformNode'](xsl);
|
||||||
if (sFragment) {
|
if (sFragment) {
|
||||||
eMachine.outerHTML = sFragment;
|
eMachine.outerHTML = sFragment;
|
||||||
|
doneMachine();
|
||||||
|
} else {
|
||||||
|
displayError("transformNodeToObject failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (document.implementation && document.implementation.createDocument) {
|
||||||
|
var xsltProcessor = new XSLTProcessor();
|
||||||
|
xsltProcessor['importStylesheet'](xsl);
|
||||||
|
var eFragment = xsltProcessor['transformToFragment'](xml, document);
|
||||||
|
if (eFragment) {
|
||||||
|
/*
|
||||||
|
* This fails in Microsoft Edge...
|
||||||
|
*
|
||||||
|
var machine = eFragment.getElementById(idMachine);
|
||||||
|
if (!machine) {
|
||||||
|
displayError("machine generation failed: " + idMachine);
|
||||||
|
} else
|
||||||
|
*/
|
||||||
|
if (eMachine.parentNode) {
|
||||||
|
eMachine.parentNode.replaceChild(eFragment, eMachine);
|
||||||
doneMachine();
|
doneMachine();
|
||||||
} else {
|
} else {
|
||||||
displayError("transformNodeToObject failed");
|
displayError("invalid machine element: " + idMachine);
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (document.implementation && document.implementation.createDocument) {
|
|
||||||
var xsltProcessor = new XSLTProcessor();
|
|
||||||
xsltProcessor['importStylesheet'](xsl);
|
|
||||||
var eFragment = xsltProcessor['transformToFragment'](xml, document);
|
|
||||||
if (eFragment) {
|
|
||||||
/*
|
|
||||||
* This fails in Microsoft Edge...
|
|
||||||
*
|
|
||||||
var machine = eFragment.getElementById(idElement);
|
|
||||||
if (!machine) {
|
|
||||||
displayError("machine generation failed: " + idElement);
|
|
||||||
} else
|
|
||||||
*/
|
|
||||||
if (eMachine.parentNode) {
|
|
||||||
eMachine.parentNode.replaceChild(eFragment, eMachine);
|
|
||||||
doneMachine();
|
|
||||||
} else {
|
|
||||||
displayError("invalid machine element: " + idElement);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayError("transformToFragment failed");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
displayError("transformToFragment failed");
|
||||||
* Perhaps I should have performed this test at the outset; on the other hand, I'm
|
|
||||||
* not aware of any browsers don't support one or both of the above XSLT transformation
|
|
||||||
* methods, so treat this as a bug.
|
|
||||||
*/
|
|
||||||
displayError("unable to transform XML: unsupported browser");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayError("failed to load XSL file: " + sXSLFile);
|
/*
|
||||||
|
* Perhaps I should have performed this test at the outset; on the other hand, I'm
|
||||||
|
* not aware of any browsers don't support one or both of the above XSLT transformation
|
||||||
|
* methods, so treat this as a bug.
|
||||||
|
*/
|
||||||
|
displayError("unable to transform XML: unsupported browser");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (xml) {
|
loadXML(sXSLFile, null, null, false, displayMessage, transformXML);
|
||||||
loadXML(sXSLFile, null, null, false, displayMessage, transformXML);
|
|
||||||
} else {
|
|
||||||
displayError("failed to load XML file: " + sXMLFile);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if (sXMLFile.charAt(0) != '<') {
|
if (sXMLFile.charAt(0) != '<') {
|
||||||
loadXML(sXMLFile, idElement, sParms, true, displayMessage, loadXSL);
|
loadXML(sXMLFile, idMachine, sParms, true, displayMessage, loadXSL);
|
||||||
} else {
|
} else {
|
||||||
parseXML(sXMLFile, null, idElement, sParms, false, displayMessage, loadXSL);
|
parseXML(sXMLFile, null, idMachine, sParms, false, displayMessage, loadXSL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayError("missing machine element: " + idElement);
|
displayError("missing machine element: " + idMachine);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
displayError(e.message);
|
displayError(e.message);
|
||||||
|
|
@ -477,32 +472,54 @@ function embedMachine(sName, sVersion, idElement, sXMLFile, sXSLFile, sParms)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* embedC1P(idElement, sXMLFile, sXSLFile)
|
* embedC1P(idMachine, sXMLFile, sXSLFile)
|
||||||
*
|
*
|
||||||
* @param {string} idElement
|
* @param {string} idMachine
|
||||||
* @param {string} sXMLFile
|
* @param {string} sXMLFile
|
||||||
* @param {string} sXSLFile
|
* @param {string} sXSLFile
|
||||||
* @return {boolean} true if successful, false if error
|
* @return {boolean} true if successful, false if error
|
||||||
*/
|
*/
|
||||||
function embedC1P(idElement, sXMLFile, sXSLFile)
|
function embedC1P(idMachine, sXMLFile, sXSLFile)
|
||||||
{
|
{
|
||||||
if (fAsync) web.enablePageEvents(false);
|
if (fAsync) web.enablePageEvents(false);
|
||||||
return embedMachine("C1Pjs", APPVERSION, idElement, sXMLFile, sXSLFile);
|
return embedMachine("C1Pjs", APPVERSION, idMachine, sXMLFile, sXSLFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* embedPC(idElement, sXMLFile, sXSLFile, sParms)
|
* embedPC(idMachine, sXMLFile, sXSLFile, sParms)
|
||||||
*
|
*
|
||||||
* @param {string} idElement
|
* @param {string} idMachine
|
||||||
* @param {string} sXMLFile
|
* @param {string} sXMLFile
|
||||||
* @param {string} sXSLFile
|
* @param {string} sXSLFile
|
||||||
* @param {string} [sParms]
|
* @param {string} [sParms]
|
||||||
* @return {boolean} true if successful, false if error
|
* @return {boolean} true if successful, false if error
|
||||||
*/
|
*/
|
||||||
function embedPC(idElement, sXMLFile, sXSLFile, sParms)
|
function embedPC(idMachine, sXMLFile, sXSLFile, sParms)
|
||||||
{
|
{
|
||||||
if (fAsync) web.enablePageEvents(false);
|
if (fAsync) web.enablePageEvents(false);
|
||||||
return embedMachine("PCjs", APPVERSION, idElement, sXMLFile, sXSLFile, sParms);
|
return embedMachine("PCjs", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* savePC(idMachine)
|
||||||
|
*
|
||||||
|
* @param {string} idMachine
|
||||||
|
* @return {boolean} true if successful, false if error
|
||||||
|
*/
|
||||||
|
function savePC(idMachine)
|
||||||
|
{
|
||||||
|
var cmp = Component.getComponentByType("Computer", idMachine);
|
||||||
|
var dbg = Component.getComponentByType("Debugger", idMachine);
|
||||||
|
if (cmp) {
|
||||||
|
var sPCJSFile = "/versions/pcjs/" + XMLVERSION + "/pc" + (dbg? "-dbg" : "") + ".js";
|
||||||
|
var sPCJSCode = web.loadResource(sPCJSFile);
|
||||||
|
/*
|
||||||
|
* Next, we need to enumerate the FDC drives and "dump" the disks in them....
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
web.alertUser("Unable to identify machine '" + idMachine + "'");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -511,6 +528,7 @@ function embedPC(idElement, sXMLFile, sXSLFile, sParms)
|
||||||
*/
|
*/
|
||||||
if (APPNAME == "PCjs") {
|
if (APPNAME == "PCjs") {
|
||||||
window['embedPC'] = embedPC;
|
window['embedPC'] = embedPC;
|
||||||
|
window['savePC'] = savePC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (APPNAME == "C1Pjs") {
|
if (APPNAME == "C1Pjs") {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue