Merge branch 'master' into gh-pages
This commit is contained in:
commit
785702eac3
19 changed files with 45045 additions and 582 deletions
|
|
@ -22,7 +22,7 @@ indent_style = space
|
|||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{php,xml,xsl}]
|
||||
[*.{php,xml,xsl,sh}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
<?xml-stylesheet type="text/xsl" href="/versions/pcx86/1.35.0/machine.xsl"?>
|
||||
<machine id="ibm5150" type="pcx86" border="1" pos="center" background="white">
|
||||
<name pos="center">IBM PC (Model 5150), CGA, 256K, Debugger</name>
|
||||
<computer id="pc-cga-256k" name="IBM PC" resume="1"/>
|
||||
<computer id="pc-cga-256k" name="IBM PC"/>
|
||||
<cpu id="cpu8088" model="8088"/>
|
||||
<debugger id="debugger"/>
|
||||
<ram id="ramLow" addr="0x00000" test="false" comment="no memory test"/>
|
||||
<rom id="romBASIC" addr="0xf6000" size="0x8000" file="/devices/pcx86/rom/5150/basic/BASIC100.json"/>
|
||||
<rom id="romBIOS" addr="0xfe000" size="0x2000" file="/devices/pcx86/rom/5150/1981-04-24/PCBIOS-REV1.json"/>
|
||||
<video ref="/devices/pcx86/video/ibm/cga/ibm-cga.xml"/>
|
||||
<fdc ref="/disks/pcx86/compiled/library.xml"/>
|
||||
<keyboard ref="/devices/pcx86/keyboard/us83-buttons-minimal.xml"/>
|
||||
<debugger id="debugger"/>
|
||||
<panel ref="/devices/pcx86/panel/wide.xml"/>
|
||||
<chipset id="chipset" model="5150" sw1="01001001" sw2="10011000" pos="left" padLeft="8px" padBottom="8px">
|
||||
<control type="switches" label="SW1" binding="sw1" left="0px"/>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<?xml-stylesheet type="text/xsl" href="/versions/pcx86/1.35.0/machine.xsl"?>
|
||||
<machine id="ibm5150" type="pcx86" border="1" pos="center" background="white">
|
||||
<name pos="center">IBM PC (Model 5150), CGA, 256K</name>
|
||||
<computer id="pc-cga-256k" name="IBM PC"/>
|
||||
<computer id="pc-cga-256k" name="IBM PC" resume="1"/>
|
||||
<cpu id="cpu8088" model="8088"/>
|
||||
<ram id="ramLow" addr="0x00000" test="false" comment="no memory test"/>
|
||||
<rom id="romBASIC" addr="0xf6000" size="0x8000" file="/devices/pcx86/rom/5150/basic/BASIC100.json"/>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -46,6 +46,11 @@ computer diagnostics, programming tools, and more.
|
|||
* [Infocom Games](games/infocom/)
|
||||
* [Microsoft Games](games/microsoft/)
|
||||
|
||||
### Shareware
|
||||
|
||||
* [PC-SIG Library 8th Edition CD-ROM (April 1990)](shareware/pcsig08/)
|
||||
* [Other...](shareware/)
|
||||
|
||||
### Tools
|
||||
|
||||
* [Borland Tools](tools/borland/)
|
||||
|
|
|
|||
11
disks/pcx86/shareware/README.md
Normal file
11
disks/pcx86/shareware/README.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
layout: page
|
||||
title: Shareware Disks
|
||||
permalink: /disks/pcx86/shareware/
|
||||
---
|
||||
|
||||
Shareware Disks
|
||||
---------------
|
||||
|
||||
- [PC-SIG Library 8th Edition CD-ROM (April 1990)](/disks/pcx86/shareware/pcsig08/)
|
||||
|
||||
23
disks/pcx86/shareware/pcsig08/README.md
Normal file
23
disks/pcx86/shareware/pcsig08/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
layout: page
|
||||
title: PC-SIG Library 8th Edition CD-ROM (April 1990)
|
||||
permalink: /disks/pcx86/shareware/pcsig08/
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: ibm5150-pcsig08
|
||||
config: /disks/pcx86/shareware/pcsig08/machine.xml
|
||||
autoMount:
|
||||
A:
|
||||
path: /disks/pcx86/dos/ibm/3.30/PCDOS330-DISK1.json
|
||||
B:
|
||||
path: /disks/pcx86/dos/ibm/3.30/PCDOS330-DISK2.json
|
||||
---
|
||||
|
||||
PC-SIG Library 8th Edition CD-ROM (April 1990)
|
||||
----------------------------------------------
|
||||
|
||||
The machine below has access to all 2,121 diskette images from the PC-SIG Library 8th Edition CD-ROM (April 1990).
|
||||
|
||||
The same machine is also available [with the PCjs Debugger](debugger/).
|
||||
|
||||
{% include machine.html id="ibm5150-pcsig08" %}
|
||||
23
disks/pcx86/shareware/pcsig08/debugger/README.md
Normal file
23
disks/pcx86/shareware/pcsig08/debugger/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
layout: page
|
||||
title: PC-SIG Library 8th Edition CD-ROM (April 1990) (with Debugger)
|
||||
permalink: /disks/pcx86/shareware/pcsig08/debugger/
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: ibm5150-pcsig08
|
||||
config: /disks/pcx86/shareware/pcsig08/debugger/machine.xml
|
||||
autoMount:
|
||||
A:
|
||||
path: /disks/pcx86/dos/ibm/3.30/PCDOS330-DISK1.json
|
||||
B:
|
||||
path: /disks/pcx86/dos/ibm/3.30/PCDOS330-DISK2.json
|
||||
---
|
||||
|
||||
PC-SIG Library 8th Edition CD-ROM (April 1990)
|
||||
----------------------------------------------
|
||||
|
||||
The machine below has access to all 2,121 diskette images from the PC-SIG Library 8th Edition CD-ROM (April 1990).
|
||||
|
||||
The same machine is also available [without the PCjs Debugger](../).
|
||||
|
||||
{% include machine.html id="ibm5150-pcsig08" %}
|
||||
20
disks/pcx86/shareware/pcsig08/debugger/machine.xml
Normal file
20
disks/pcx86/shareware/pcsig08/debugger/machine.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pcx86/1.35.0/machine.xsl"?>
|
||||
<machine id="ibm5150" type="pcx86" border="1" pos="center" background="white">
|
||||
<name pos="center">IBM PC (Model 5150), CGA, 256K</name>
|
||||
<computer id="pc-cga-256k" name="IBM PC"/>
|
||||
<cpu id="cpu8088" model="8088"/>
|
||||
<ram id="ramLow" addr="0x00000" test="false" comment="no memory test"/>
|
||||
<rom id="romBASIC" addr="0xf6000" size="0x8000" file="/devices/pcx86/rom/5150/basic/BASIC100.json"/>
|
||||
<rom id="romBIOS" addr="0xfe000" size="0x2000" file="/devices/pcx86/rom/5150/1981-04-24/PCBIOS-REV1.json"/>
|
||||
<video ref="/devices/pcx86/video/ibm/cga/ibm-cga.xml"/>
|
||||
<fdc ref="/disks/pcx86/shareware/pcsig08/fdc.xml"/>
|
||||
<keyboard ref="/devices/pcx86/keyboard/us83-buttons-minimal.xml"/>
|
||||
<debugger id="debugger"/>
|
||||
<panel ref="/devices/pcx86/panel/wide.xml"/>
|
||||
<chipset id="chipset" model="5150" sw1="01001001" sw2="10011000" pos="left" padLeft="8px" padBottom="8px">
|
||||
<control type="switches" label="SW1" binding="sw1" left="0px"/>
|
||||
<control type="switches" label="SW2" binding="sw2" left="0px"/>
|
||||
<control type="description" binding="swdesc" left="0px"/>
|
||||
</chipset>
|
||||
</machine>
|
||||
19
disks/pcx86/shareware/pcsig08/fdc.xml
Normal file
19
disks/pcx86/shareware/pcsig08/fdc.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fdc id="fdcNEC" automount='{A:{name:"PC-DOS 2.00 (Disk 1)",path:"/disks/pcx86/dos/ibm/2.00/PCDOS200-DISK1.json"}, B:{name:"PC-DOS 2.00 (Disk 2)",path:"/disks/pcx86/dos/ibm/2.00/PCDOS200-DISK2.json"}}' pos="left" padLeft="8px" padBottom="8px">
|
||||
<control type="list" binding="listDrives"/>
|
||||
<control type="list" binding="listDisks">
|
||||
<manifest ref="/disks/pcx86/dos/ibm/1.00/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/1.10/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/2.00/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/2.10/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/3.00/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/3.10/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/3.20/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/dos/ibm/3.30/manifest.xml"/>
|
||||
<manifest ref="/disks/pcx86/shareware/pcsig08/manifest.xml"/>
|
||||
</control>
|
||||
<control type="button" binding="loadDisk">Load</control>
|
||||
<control type="button" binding="saveDisk" padRight="8px">Save</control>
|
||||
<control type="description" binding="descDisk" padRight="8px"/>
|
||||
<control type="file" binding="mountDisk"/>
|
||||
</fdc>
|
||||
14
disks/pcx86/shareware/pcsig08/machine.xml
Normal file
14
disks/pcx86/shareware/pcsig08/machine.xml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pcx86/1.35.0/machine.xsl"?>
|
||||
<machine id="ibm5150" type="pcx86" border="1" pos="center" background="white">
|
||||
<name pos="center">IBM PC (Model 5150), CGA, 256K</name>
|
||||
<computer id="pc-cga-256k" name="IBM PC" resume="1"/>
|
||||
<cpu id="cpu8088" model="8088"/>
|
||||
<ram id="ramLow" addr="0x00000" test="false" comment="no memory test"/>
|
||||
<rom id="romBASIC" addr="0xf6000" size="0x8000" file="/devices/pcx86/rom/5150/basic/BASIC100.json"/>
|
||||
<rom id="romBIOS" addr="0xfe000" size="0x2000" file="/devices/pcx86/rom/5150/1981-04-24/PCBIOS-REV1.json"/>
|
||||
<video ref="/devices/pcx86/video/ibm/cga/ibm-cga.xml"/>
|
||||
<fdc ref="/disks/pcx86/shareware/pcsig08/fdc.xml"/>
|
||||
<keyboard ref="/devices/pcx86/keyboard/us83-buttons-minimal.xml"/>
|
||||
<chipset id="chipset" model="5150" sw1="01001001" sw2="10011000"/>
|
||||
</machine>
|
||||
44323
disks/pcx86/shareware/pcsig08/manifest.xml
Normal file
44323
disks/pcx86/shareware/pcsig08/manifest.xml
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -74,10 +74,10 @@ var logFile = null;
|
|||
|
||||
/*
|
||||
* fNormalize attempts to enforce consistency across multiple dump requests, including the order of files within every
|
||||
* directory, the use of hard-coded volume label timestamps, etc. And since I assume that normalization is a wonderful
|
||||
* thing, I don't provide any UI for turning it off.
|
||||
* directory, the use of hard-coded volume label timestamps, replacement of line-endings in text files, etc. And since
|
||||
* I assume that normalization is a wonderful thing, I don't provide any UI for turning it off.
|
||||
*/
|
||||
var fNormalize = true;
|
||||
var fNormalize = false;
|
||||
|
||||
/**
|
||||
* BufferPF(init, start, end)
|
||||
|
|
@ -961,13 +961,13 @@ DiskDump.updateManifest = function(disk, sManifestFile, sDiskPath, sOutputFile,
|
|||
}
|
||||
|
||||
if (!sIDDisk) {
|
||||
for (i = 1; i < 1000; i++) {
|
||||
for (i = 1; i < 10000; i++) {
|
||||
sIDDisk = i.toString();
|
||||
if (sIDDisk.length < 2) sIDDisk = '0' + sIDDisk;
|
||||
sIDDisk = "disk" + sIDDisk;
|
||||
if (sXML.indexOf(' id="' + sIDDisk + '"') < 0) break;
|
||||
}
|
||||
if (i == 1000) {
|
||||
if (i == 10000) {
|
||||
err = new Error("manifest already contains " + i + " disks");
|
||||
}
|
||||
}
|
||||
|
|
@ -1030,7 +1030,7 @@ DiskDump.updateManifest = function(disk, sManifestFile, sDiskPath, sOutputFile,
|
|||
sAttrs += ' dir="' + sDir + '"';
|
||||
}
|
||||
}
|
||||
sXMLDisk += '\t\t<file' + sAttrs + '>' + fileInfo.FILE_NAME + '</file>\n';
|
||||
sXMLDisk += '\t\t<file' + sAttrs + '>' + fileInfo.FILE_NAME.replace(/&/g, "&") + '</file>\n';
|
||||
}
|
||||
sXMLDisk += '\t</disk>\n';
|
||||
sXMLDisk = sXMLDisk.replace(/(<disk[^>]*)>\s*<\/disk>/, "$1/>");
|
||||
|
|
@ -1577,9 +1577,11 @@ DiskDump.prototype.addManifestInfo = function(fileInfo)
|
|||
*/
|
||||
DiskDump.prototype.isTextFile = function(sFileName)
|
||||
{
|
||||
if (fNormalize) {
|
||||
for (var i = 0; i < DiskDump.asTextFileExts.length; i++) {
|
||||
if (str.endsWith(sFileName, DiskDump.asTextFileExts[i])) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
@ -1633,7 +1635,7 @@ DiskDump.prototype.readDir = function(sDir, fRoot, done)
|
|||
* file name order that I was originally seeing may have simply been due to out-of-order fs.stat()
|
||||
* calls, because I used to call addManifestInfo() in the callback.
|
||||
*/
|
||||
// if (fNormalize) asFiles.sort();
|
||||
if (fNormalize) asFiles.sort();
|
||||
|
||||
for (iFile = 0; iFile < asFiles.length; iFile++) {
|
||||
var sFileName = asFiles[iFile];
|
||||
|
|
@ -1927,7 +1929,7 @@ DiskDump.prototype.buildVolLabel = function(sDir)
|
|||
*
|
||||
* UPDATE: I'm not sure I care about that anymore. Time-stamping the created disk image seems more useful.
|
||||
*/
|
||||
fileInfo.FILE_TIME = /* fNormalize? new Date(1981, 7, 12, 12) : */ new Date();
|
||||
fileInfo.FILE_TIME = fNormalize? new Date(1981, 7, 12, 12) : new Date();
|
||||
this.validateTime(fileInfo.FILE_TIME);
|
||||
fileInfo.FILE_SIZE = 0;
|
||||
}
|
||||
|
|
@ -2247,31 +2249,27 @@ DiskDump.prototype.buildImage = function(fDir, done)
|
|||
};
|
||||
|
||||
/**
|
||||
* calcFileSizes(aFiles)
|
||||
*
|
||||
* WARNING: Our "total data" calculation should be rounding up to the next cluster,
|
||||
* not the next sector, because data on the disk is cluster-granular, not sector-granular.
|
||||
* But we have a chicken-and-egg problem: we won't know the cluster size until we've
|
||||
* calculated total data and found a BPB we think will accommodate it. So, the code below
|
||||
* will still have to be prepared for running out of disk space. This is just a good estimate.
|
||||
* calcFileSizes(aFiles, cSectorsPerCluster)
|
||||
*
|
||||
* @this {DiskDump}
|
||||
* @param {Array} aFiles
|
||||
* @param {number} [cSectorsPerCluster] (default is 1)
|
||||
* @return {number} of bytes required for all files, including all subdirectories
|
||||
*/
|
||||
DiskDump.prototype.calcFileSizes = function(aFiles)
|
||||
DiskDump.prototype.calcFileSizes = function(aFiles, cSectorsPerCluster)
|
||||
{
|
||||
var cbTotal = 0;
|
||||
var cbCluster = (cSectorsPerCluster || 1) * 512;
|
||||
for (var iFile = 0; iFile < aFiles.length; iFile++) {
|
||||
var cb = aFiles[iFile].FILE_SIZE;
|
||||
var cbSubTotal = 0;
|
||||
if (cb < 0) {
|
||||
cb = (aFiles[iFile].FILE_DATA.length + 2) * 32;
|
||||
cbSubTotal = this.calcFileSizes(aFiles[iFile].FILE_DATA);
|
||||
cbSubTotal = this.calcFileSizes(aFiles[iFile].FILE_DATA, cSectorsPerCluster);
|
||||
}
|
||||
cbTotal += cb;
|
||||
if ((cb %= 512)) {
|
||||
cbTotal += 512 - cb; // WARNING: rounding to next sector may not be enough (see above)
|
||||
if ((cb %= cbCluster)) {
|
||||
cbTotal += cbCluster - cb;
|
||||
}
|
||||
cbTotal += cbSubTotal;
|
||||
}
|
||||
|
|
@ -2370,6 +2368,12 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
|||
*/
|
||||
var cbMax = (this.kbTarget || 1440) * 1024;
|
||||
var nTargetSectors = (this.kbTarget? this.kbTarget * 2 : 0);
|
||||
|
||||
/*
|
||||
* This initializes cbTotal assuming a "best case scenario" (ie, one sector per cluster); as soon as
|
||||
* we find a BPB that will support that size, we recalculate cbTotal using that BPB's cluster size, and
|
||||
* then we re-verify that that BPB will work. If not, then we keep looking.
|
||||
*/
|
||||
var cbTotal = this.calcFileSizes(aFiles);
|
||||
|
||||
if (fDebug) DiskDump.logConsole("total calculated size for " + aFiles.length + " files/folders: " + cbTotal + " bytes (" + str.toHex(cbTotal, 0, true) + ")");
|
||||
|
|
@ -2397,43 +2401,48 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
|||
*
|
||||
* UPDATE: I've undone the above change, because when creating a disk image for an old application like:
|
||||
*
|
||||
* /apps/pcx86/1983/adventmath ["Adventures in Math" (1983)]
|
||||
* /apps/pcx86/1983/adventmath ["Adventures in Math (1983)"]
|
||||
*
|
||||
* it's important to create a disk image that will work with PC-DOS 1.0, which didn't understand 180Kb and 360Kb
|
||||
* disk images.
|
||||
*/
|
||||
for (var iBPB = 0; iBPB < DiskDump.aDefaultBPBs.length; iBPB++) {
|
||||
/*
|
||||
* Use slice() to copy the default BPB, as a precaution (to avoid any changes to the default).
|
||||
* Use slice() to copy the BPB, to ensure we don't alter the original.
|
||||
*/
|
||||
abBoot = DiskDump.aDefaultBPBs[iBPB].slice();
|
||||
/*
|
||||
* If this BPB is for a hard drive but a disk size was not specified, skip it.
|
||||
*/
|
||||
if ((abBoot[0x15] == 0xF8) != (this.kbTarget >= 10000)) continue;
|
||||
cbSector = abBoot[0x0B] | (abBoot[0x0C] << 8);
|
||||
cSectorsPerCluster = abBoot[0x0D];
|
||||
if ((abBoot[DiskAPI.BPB.MEDIA_TYPE] == DiskAPI.FAT.MEDIA_FIXED) != (this.kbTarget >= 10000)) continue;
|
||||
cRootEntries = abBoot[DiskAPI.BPB.ROOT_DIRENTS] | (abBoot[DiskAPI.BPB.ROOT_DIRENTS + 1] << 8);
|
||||
if (aFiles.length > cRootEntries) continue;
|
||||
cbSector = abBoot[DiskAPI.BPB.SECTOR_BYTES] | (abBoot[DiskAPI.BPB.SECTOR_BYTES + 1] << 8);
|
||||
cSectorsPerCluster = abBoot[DiskAPI.BPB.CLUSTER_SECS];
|
||||
cbCluster = cbSector * cSectorsPerCluster;
|
||||
cFATs = abBoot[0x10];
|
||||
cFATSectors = abBoot[0x16] | (abBoot[0x17] << 8);
|
||||
cRootEntries = abBoot[0x11] | (abBoot[0x12] << 8);
|
||||
cRootSectors = (((cRootEntries * 0x20) + cbSector - 1) / cbSector) | 0;
|
||||
cTotalSectors = abBoot[0x13] | (abBoot[0x14] << 8);
|
||||
cSectorsPerTrack = abBoot[0x18] | (abBoot[0x19] << 8);
|
||||
cHeads = abBoot[0x1A] | (abBoot[0x1B] << 8);
|
||||
cDataSectors = cTotalSectors - cRootSectors - cFATs * cFATSectors + 1;
|
||||
cFATs = abBoot[DiskAPI.BPB.TOTAL_FATS];
|
||||
cFATSectors = abBoot[DiskAPI.BPB.FAT_SECS] | (abBoot[DiskAPI.BPB.FAT_SECS + 1] << 8);
|
||||
cRootSectors = (((cRootEntries * DiskAPI.DIRENT.LENGTH) + cbSector - 1) / cbSector) | 0;
|
||||
cTotalSectors = abBoot[DiskAPI.BPB.TOTAL_SECS] | (abBoot[DiskAPI.BPB.TOTAL_SECS + 1] << 8);
|
||||
cSectorsPerTrack = abBoot[DiskAPI.BPB.TRACK_SECS] | (abBoot[DiskAPI.BPB.TRACK_SECS + 1] << 8);
|
||||
cHeads = abBoot[DiskAPI.BPB.TOTAL_HEADS] | (abBoot[DiskAPI.BPB.TOTAL_HEADS + 1] << 8);
|
||||
cDataSectors = cTotalSectors - (cRootSectors + cFATs * cFATSectors + 1);
|
||||
cbAvail = cDataSectors * cbSector;
|
||||
if (nTargetSectors && cTotalSectors == nTargetSectors || !nTargetSectors && cbTotal <= cbAvail) break;
|
||||
if (!nTargetSectors) {
|
||||
if (cbTotal <= cbAvail) {
|
||||
var cb = this.calcFileSizes(aFiles, cSectorsPerCluster);
|
||||
if (cb <= cbAvail) {
|
||||
cbTotal = cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cTotalSectors == nTargetSectors) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iBPB == DiskDump.aDefaultBPBs.length) {
|
||||
err = new Error("file(s) too large for disk image (" + cbTotal + " vs. " + cbAvail + " bytes)");
|
||||
done(err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aFiles.length > cRootEntries) {
|
||||
err = new Error("too many files for disk image (" + aFiles.length + " vs. " + cRootEntries + " max)");
|
||||
err = new Error("too many file(s) for disk image (" + aFiles.length + " files, " + cbTotal + " bytes)");
|
||||
done(err);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2467,8 +2476,8 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
|||
/*
|
||||
* Output a boot sector.
|
||||
*/
|
||||
abBoot[DiskAPI.BOOT.SIG_OFFSET] = 0x55;
|
||||
abBoot[DiskAPI.BOOT.SIG_OFFSET + 1] = 0xAA;
|
||||
abBoot[DiskAPI.BOOT.SIG_OFFSET] = DiskAPI.BOOT.SIGNATURE & 0xff; // 0x55
|
||||
abBoot[DiskAPI.BOOT.SIG_OFFSET + 1] = (DiskAPI.BOOT.SIGNATURE >> 8) & 0xff; // 0xAA
|
||||
abSector = this.buildData(cbSector, abBoot);
|
||||
offDisk += this.copyData(offDisk, abSector);
|
||||
|
||||
|
|
@ -2479,7 +2488,7 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
|||
* BPB at offset 0x15. For old BPB-less diskettes, this is where you must look for the media type.
|
||||
*/
|
||||
var abFAT = [];
|
||||
this.buildFATEntry(abFAT, 0, abBoot[0x15] | 0xF00);
|
||||
this.buildFATEntry(abFAT, 0, abBoot[DiskAPI.BPB.MEDIA_TYPE] | 0xF00);
|
||||
this.buildFATEntry(abFAT, 1, 0xFFF);
|
||||
this.buildFAT(abFAT, aFiles, 2, cbCluster);
|
||||
|
||||
|
|
@ -2502,10 +2511,10 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
|||
* PC-DOS 1.0 requires ALL unused directory entries to start with 0xE5; 0x00 isn't good enough,
|
||||
* so we must loop through all the remaining directory entries and zap them with 0xE5.
|
||||
*/
|
||||
var offRoot = cEntries * 32;
|
||||
var offRoot = cEntries * DiskAPI.DIRENT.LENGTH;
|
||||
while (cEntries++ < cRootEntries) {
|
||||
abRoot[offRoot] = 0xE5;
|
||||
offRoot += 32;
|
||||
abRoot[offRoot] = DiskAPI.DIRENT.INVALID; // 0xE5
|
||||
offRoot += DiskAPI.DIRENT.LENGTH; // 0x20 (32)
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -197,13 +197,17 @@ class Disk extends Component {
|
|||
{
|
||||
super("Disk", {'id': controller.idMachine + ".disk" + Str.toHex(++Disk.nDisks, 4)}, Messages.DISK);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
/*
|
||||
* Route all non-Debugger messages (eg, notice() and println() calls) through
|
||||
* this.controller (eg, controller.notice() and controller.println()), because
|
||||
* the Computer component is unaware of any Disk objects and therefore will not
|
||||
* set up the usual overrides when a Control Panel is installed.
|
||||
*/
|
||||
this.controller = controller;
|
||||
this.notice = controller.notice;
|
||||
this.println = controller.println;
|
||||
|
||||
this.cmp = controller.cmp;
|
||||
this.dbg = controller.dbg;
|
||||
this.drive = drive;
|
||||
|
|
@ -345,7 +349,7 @@ class Disk extends Component {
|
|||
}
|
||||
while ((response = this.findDirtySectors(false))) {
|
||||
if ((nErrorCode = response[0])) {
|
||||
this.controller.notice('Unable to save "' + this.sDiskName + '" (error ' + nErrorCode + ')');
|
||||
this.notice('Unable to save "' + this.sDiskName + '" (error ' + nErrorCode + ')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -358,7 +362,7 @@ class Disk extends Component {
|
|||
* all diskettes to their original state) and discarding remote changes (which could leave the remote disk
|
||||
* in a bad state).
|
||||
*/
|
||||
if (!nErrorCode && fSave) this.controller.notice(this.sDiskName + " saved");
|
||||
if (!nErrorCode && fSave) this.notice(this.sDiskName + " saved");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -527,7 +531,7 @@ class Disk extends Component {
|
|||
}
|
||||
}
|
||||
}
|
||||
return !!Web.getResource(sDiskURL, null, true, function(sURL, sResponse, nErrorCode) {
|
||||
return !!Web.getResource(sDiskURL, null, true, function loadDone(sURL, sResponse, nErrorCode) {
|
||||
disk.doneLoad(sURL, sResponse, nErrorCode);
|
||||
});
|
||||
}
|
||||
|
|
@ -612,7 +616,7 @@ class Disk extends Component {
|
|||
if (BACKTRACK || SYMBOLS) this.buildFileTable();
|
||||
disk = this;
|
||||
} else {
|
||||
this.controller.notice('Unable to connect to disk "' + this.sDiskPath + '" (error ' + nErrorCode + ': ' + sDiskData + ')', fPrintOnly);
|
||||
this.notice('Unable to connect to disk "' + this.sDiskPath + '" (error ' + nErrorCode + ': ' + sDiskData + ')', fPrintOnly);
|
||||
}
|
||||
}
|
||||
else if (nErrorCode) {
|
||||
|
|
@ -623,7 +627,7 @@ class Disk extends Component {
|
|||
* that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the
|
||||
* notify() alert if there's no specific error AND the computer is not powered up yet.
|
||||
*/
|
||||
this.controller.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ": " + sURL + ")", fPrintOnly);
|
||||
this.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ": " + sURL + ")", fPrintOnly);
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage('doneLoad("' + this.sDiskPath + '")');
|
||||
|
|
@ -763,22 +767,28 @@ class Disk extends Component {
|
|||
var ab = sector['bytes'];
|
||||
if (ab === undefined || !ab.length) {
|
||||
/*
|
||||
* It would be odd if there was neither a 'bytes' nor 'data' array; I'm just
|
||||
* being paranoid. It's more likely that the 'bytes' array is simply empty,
|
||||
* in which case we need only create an empty 'data' array and turn the byte
|
||||
* pattern, if any, into a dword pattern.
|
||||
* If there is neither a 'bytes' nor 'data' array, then our job is simple:
|
||||
* create an empty 'data' array; it will be filled in with the dword pattern
|
||||
* as needed later.
|
||||
*
|
||||
* The only wrinkle is if there *is* a 'bytes' array but it's empty, in which
|
||||
* case we must assume that the pattern was a byte pattern, so convert it to a
|
||||
* dword pattern.
|
||||
*/
|
||||
adw = [];
|
||||
sector['data'] = adw = [];
|
||||
if (ab) {
|
||||
this.assert((dwPattern & 0xff) == dwPattern);
|
||||
dwPattern = sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));
|
||||
sector['data'] = adw;
|
||||
} else {
|
||||
sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* To keep the conversion code simple, we'll do any necessary pattern-filling first,
|
||||
* to fully "inflate" the sector, eliminating the possibility of partial dwords and
|
||||
* saving any code downstream from dealing with byte-size patterns.
|
||||
*/
|
||||
var cb = length << 2;
|
||||
this.assert((dwPattern & 0xff) == dwPattern);
|
||||
for (var ib = ab.length; ib < cb; ib++) {
|
||||
ab[ib] = dwPattern; // the pattern for byte-arrays was only a byte
|
||||
}
|
||||
|
|
@ -2096,23 +2106,28 @@ class Disk extends Component {
|
|||
*/
|
||||
}
|
||||
/*
|
||||
* v1.01 failed to indicate an error if either one of these failure conditions occurred. Although maybe that's
|
||||
* just as well, since v1.01 also failed to properly deal with situations where the user mounted different diskette(s)
|
||||
* prior to exiting (hopefully fixed in v1.02).
|
||||
* v1.01 failed to indicate an error if either one of these failure conditions occurred. Although maybe
|
||||
* that's just as well, since v1.01 also failed to properly deal with situations where the user mounted
|
||||
* different diskette(s) prior to exiting (hopefully fixed in v1.02).
|
||||
*
|
||||
* UPDATE: We also check aDiskInfo[0] first, because if it's null, then presumably there was no previous
|
||||
* disk, and I'd like the addition of a disk to a machine to not be fatal to the restoration process.
|
||||
*/
|
||||
else if (aDiskInfo[1] != null && this.dwChecksum != null && aDiskInfo[1] != this.dwChecksum) {
|
||||
else if (aDiskInfo[0] != null) {
|
||||
if (aDiskInfo[1] != null && this.dwChecksum != null && aDiskInfo[1] != this.dwChecksum) {
|
||||
sReason = "original checksum (" + aDiskInfo[1] + ") differs from current checksum (" + this.dwChecksum + ")";
|
||||
nChanges = -2;
|
||||
}
|
||||
/*
|
||||
* Checksum is more important than disk path, and for now, I want the flexibility to move disk images.
|
||||
*
|
||||
else if (aDiskInfo[0] != this.sDiskPath) {
|
||||
sReason = "original path '" + aDiskInfo[0] + "' differs from current path '" + this.sDiskPath + "'";
|
||||
nChanges = -1;
|
||||
}
|
||||
* else if (aDiskInfo[0] != this.sDiskPath) {
|
||||
* sReason = "original path '" + aDiskInfo[0] + "' differs from current path '" + this.sDiskPath + "'";
|
||||
* nChanges = -1;
|
||||
* }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.aDiskData.length) nChanges = -1;
|
||||
|
||||
|
|
@ -2167,7 +2182,7 @@ class Disk extends Component {
|
|||
* We're suppressing checksum messages for the general public for now....
|
||||
*/
|
||||
if (DEBUG || nChanges != -2) {
|
||||
this.controller.notice("Unable to restore disk '" + this.sDiskName + ": " + sReason);
|
||||
this.notice("Unable to restore disk '" + this.sDiskName + ": " + sReason);
|
||||
}
|
||||
} else {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ DiskAPI.FAT = {
|
|||
MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track
|
||||
MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track
|
||||
MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track
|
||||
MEDIA_FIXED: 0xF8, // fixed disk (aka hard drive)
|
||||
MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track
|
||||
MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue