Allow gzipped disk images
This commit is contained in:
parent
d3a8160ad8
commit
231bc201e7
7 changed files with 41 additions and 42 deletions
|
|
@ -13,7 +13,7 @@
|
||||||
<fdc ref="/disks/pc/library.xml" automount=''/>
|
<fdc ref="/disks/pc/library.xml" automount=''/>
|
||||||
<debugger id="debugger" messages="" commands=''/>
|
<debugger id="debugger" messages="" commands=''/>
|
||||||
<panel ref="/devices/pc/panel/wide386.xml"/>
|
<panel ref="/devices/pc/panel/wide386.xml"/>
|
||||||
<hdc id="hdcAT" type="at" drives='[{name:"68Mb Hard Disk",type:4,path:"http://static.pcjs.org/devices/pc/machine/compaq/deskpro386/vga/4096kb/WIN95-68Mb.json"}]'/>
|
<hdc id="hdcAT" type="at" drives='[{name:"68Mb Hard Disk",type:4,path:"http://static.pcjs.org/devices/pc/machine/compaq/deskpro386/vga/4096kb/WIN95-68Mb.json.gz"}]'/>
|
||||||
<chipset id="chipset" model="deskpro386" floppies="[1200,1200]" monitor="vga"/>
|
<chipset id="chipset" model="deskpro386" floppies="[1200,1200]" monitor="vga"/>
|
||||||
<serial id="com1" adapter="1"/>
|
<serial id="com1" adapter="1"/>
|
||||||
<serial id="com2" adapter="2" binding="print"/>
|
<serial id="com2" adapter="2" binding="print"/>
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
||||||
if (!sStatePath) {
|
if (!sStatePath) {
|
||||||
this.setReady();
|
this.setReady();
|
||||||
} else {
|
} else {
|
||||||
web.loadResource(sStatePath, true, null, this, this.onLoadSetReady);
|
web.loadResource(sStatePath, true, null, this, this.doneLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fSuspended) {
|
if (!fSuspended) {
|
||||||
|
|
@ -321,20 +321,20 @@ Computer.prototype.getUserID = function()
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onLoadSetReady(sStateFile, sStateData, nErrorCode)
|
* doneLoad(sURL, sStateData, nErrorCode)
|
||||||
*
|
*
|
||||||
* @this {Computer}
|
* @this {Computer}
|
||||||
* @param {string} sStateFile
|
* @param {string} sURL
|
||||||
* @param {string} sStateData
|
* @param {string} sStateData
|
||||||
* @param {number} nErrorCode
|
* @param {number} nErrorCode
|
||||||
*/
|
*/
|
||||||
Computer.prototype.onLoadSetReady = function(sStateFile, sStateData, nErrorCode)
|
Computer.prototype.doneLoad = function(sURL, sStateData, nErrorCode)
|
||||||
{
|
{
|
||||||
if (!nErrorCode) {
|
if (!nErrorCode) {
|
||||||
this.sStateData = sStateData;
|
this.sStateData = sStateData;
|
||||||
this.fStateData = true;
|
this.fStateData = true;
|
||||||
if (DEBUG && this.messageEnabled()) {
|
if (DEBUG && this.messageEnabled()) {
|
||||||
this.printMessage("loaded state file " + sStateFile.replace(this.sUserID || "xxx", "xxx"));
|
this.printMessage("loaded state file " + sURL.replace(this.sUserID || "xxx", "xxx"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.sResumePath = null;
|
this.sResumePath = null;
|
||||||
|
|
|
||||||
|
|
@ -1012,6 +1012,8 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller)
|
||||||
|
|
||||||
this.sDiskName = sDiskName;
|
this.sDiskName = sDiskName;
|
||||||
this.sDiskPath = sDiskPath;
|
this.sDiskPath = sDiskPath;
|
||||||
|
this.sDiskFile = str.getBaseName(sDiskPath);
|
||||||
|
|
||||||
this.fnNotify = fnNotify;
|
this.fnNotify = fnNotify;
|
||||||
this.controllerNotify = controller || this.controller;
|
this.controllerNotify = controller || this.controller;
|
||||||
|
|
||||||
|
|
@ -1036,7 +1038,7 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller)
|
||||||
* converter to return the corresponding JSON-encoded data.
|
* converter to return the corresponding JSON-encoded data.
|
||||||
*/
|
*/
|
||||||
var sDiskExt = str.getExtension(sDiskPath);
|
var sDiskExt = str.getExtension(sDiskPath);
|
||||||
if (sDiskExt == DumpAPI.FORMAT.JSON) {
|
if (sDiskExt == DumpAPI.FORMAT.JSON || sDiskExt == DumpAPI.FORMAT.JSON_GZ) {
|
||||||
sDiskURL = encodeURI(sDiskPath);
|
sDiskURL = encodeURI(sDiskPath);
|
||||||
} else {
|
} else {
|
||||||
if (this.mode == DiskAPI.MODE.DEMANDRW || this.mode == DiskAPI.MODE.DEMANDRO) {
|
if (this.mode == DiskAPI.MODE.DEMANDRW || this.mode == DiskAPI.MODE.DEMANDRO) {
|
||||||
|
|
@ -1076,7 +1078,7 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
web.loadResource(sDiskURL, true, null, this, this.doneLoad, sDiskPath);
|
web.loadResource(sDiskURL, true, null, this, this.doneLoad);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1135,35 +1137,32 @@ Disk.prototype.build = function(buffer, fModified)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* doneLoad(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
* doneLoad(sURL, sDiskData, nErrorCode)
|
||||||
*
|
*
|
||||||
* This function was originally called mount(). If the mount is successful, we pass the Disk object to the
|
* This function was originally called mount(). If the mount is successful, we pass the Disk object to the
|
||||||
* caller's fnNotify handler; otherwise, we pass null.
|
* caller's fnNotify handler; otherwise, we pass null.
|
||||||
*
|
*
|
||||||
* @this {Disk}
|
* @this {Disk}
|
||||||
* @param {string} sDiskFile
|
* @param {string} sURL
|
||||||
* @param {string} sDiskData
|
* @param {string} sDiskData
|
||||||
* @param {number} nErrorCode (response from server if anything other than 200)
|
* @param {number} nErrorCode (response from server if anything other than 200)
|
||||||
* @param {string} sDiskPath (passed through from load() to loadResource())
|
|
||||||
*/
|
*/
|
||||||
Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
Disk.prototype.doneLoad = function(sURL, sDiskData, nErrorCode)
|
||||||
{
|
{
|
||||||
var disk = null;
|
var disk = null;
|
||||||
this.fWriteProtected = false;
|
this.fWriteProtected = false;
|
||||||
var fPrintOnly = (nErrorCode < 0 && this.cmp && !this.cmp.aFlags.fPowered);
|
var fPrintOnly = (nErrorCode < 0 && this.cmp && !this.cmp.aFlags.fPowered);
|
||||||
|
|
||||||
this.sDiskFile = sDiskFile;
|
|
||||||
|
|
||||||
if (this.fOnDemand) {
|
if (this.fOnDemand) {
|
||||||
if (!nErrorCode) {
|
if (!nErrorCode) {
|
||||||
if (DEBUG && this.messageEnabled()) {
|
if (DEBUG && this.messageEnabled()) {
|
||||||
this.printMessage('doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
this.printMessage('doneLoad("' + this.sDiskPath + '")');
|
||||||
}
|
}
|
||||||
this.fRemote = true;
|
this.fRemote = true;
|
||||||
if (BACKTRACK || SYMBOLS) this.buildFileTable();
|
if (BACKTRACK || SYMBOLS) this.buildFileTable();
|
||||||
disk = this;
|
disk = this;
|
||||||
} else {
|
} else {
|
||||||
this.controller.notice('Unable to connect to disk "' + sDiskPath + '" (error ' + nErrorCode + ': ' + sDiskData + ')', fPrintOnly);
|
this.controller.notice('Unable to connect to disk "' + this.sDiskPath + '" (error ' + nErrorCode + ': ' + sDiskData + ')', fPrintOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nErrorCode) {
|
else if (nErrorCode) {
|
||||||
|
|
@ -1174,10 +1173,10 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
||||||
* that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the
|
* 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.
|
* 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 + ")", fPrintOnly);
|
this.controller.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ": " + sURL + ")", fPrintOnly);
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG && this.messageEnabled()) {
|
if (DEBUG && this.messageEnabled()) {
|
||||||
this.printMessage('doneLoad("' + sDiskFile + '","' + sDiskPath + '")');
|
this.printMessage('doneLoad("' + this.sDiskPath + '")');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
|
|
@ -1189,7 +1188,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
||||||
* TODO: Provide some UI for turning write-protection on/off for disks at will, and provide
|
* TODO: Provide some UI for turning write-protection on/off for disks at will, and provide
|
||||||
* an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well.
|
* an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well.
|
||||||
*/
|
*/
|
||||||
var sBaseName = str.getBaseName(sDiskFile, true).toLowerCase();
|
var sBaseName = str.getBaseName(this.sDiskFile, true).toLowerCase();
|
||||||
if (sBaseName.indexOf("-readonly") > 0) {
|
if (sBaseName.indexOf("-readonly") > 0) {
|
||||||
this.fWriteProtected = true;
|
this.fWriteProtected = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1354,7 +1353,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath)
|
||||||
disk = this;
|
disk = this;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Component.error("Disk image error: " + e.message);
|
Component.error("Disk image error (" + sURL + "): " + e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ if (NODE) {
|
||||||
* notify: ID of a component to notify once the ROM is in place (optional)
|
* notify: ID of a component to notify once the ROM is in place (optional)
|
||||||
*
|
*
|
||||||
* NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the
|
* NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the
|
||||||
* ROM data file has finished loading (see onLoadROM()).
|
* ROM data file has finished loading (see doneLoad()).
|
||||||
*
|
*
|
||||||
* Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received
|
* Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received
|
||||||
* is the ROM you expected.
|
* is the ROM you expected.
|
||||||
|
|
@ -117,7 +117,7 @@ function ROM(parmsROM)
|
||||||
if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {
|
if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {
|
||||||
sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';
|
sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';
|
||||||
}
|
}
|
||||||
web.loadResource(sFileURL, true, null, this, ROM.prototype.onLoadROM);
|
web.loadResource(sFileURL, true, null, this, this.doneLoad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,17 +212,17 @@ ROM.prototype.powerDown = function(fSave, fShutdown)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onLoadROM(sROMFile, sROMData, nErrorCode)
|
* doneLoad(sURL, sROMData, nErrorCode)
|
||||||
*
|
*
|
||||||
* @this {ROM}
|
* @this {ROM}
|
||||||
* @param {string} sROMFile
|
* @param {string} sURL
|
||||||
* @param {string} sROMData
|
* @param {string} sROMData
|
||||||
* @param {number} nErrorCode (response from server if anything other than 200)
|
* @param {number} nErrorCode (response from server if anything other than 200)
|
||||||
*/
|
*/
|
||||||
ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode)
|
ROM.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
||||||
{
|
{
|
||||||
if (nErrorCode) {
|
if (nErrorCode) {
|
||||||
this.notice("Unable to load system ROM (error " + nErrorCode + ")");
|
this.notice("Unable to load system ROM (error " + nErrorCode + ": " + sURL + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") {
|
if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") {
|
||||||
|
|
@ -256,7 +256,7 @@ ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode)
|
||||||
this.aSymbols = rom['symbols'];
|
this.aSymbols = rom['symbols'];
|
||||||
|
|
||||||
if (!this.abROM.length) {
|
if (!this.abROM.length) {
|
||||||
Component.error("Empty ROM: " + sROMFile);
|
Component.error("Empty ROM: " + sURL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (this.abROM.length == 1) {
|
else if (this.abROM.length == 1) {
|
||||||
|
|
@ -286,8 +286,8 @@ ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode)
|
||||||
/**
|
/**
|
||||||
* copyROM()
|
* copyROM()
|
||||||
*
|
*
|
||||||
* This function is called by both initBus() and onLoadROM(), but it cannot copy the the ROM data into place
|
* This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place
|
||||||
* until after initBus() has received the Bus component AND onloadROM() has received the abROM data. When both
|
* until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both
|
||||||
* those criteria are satisfied, the component becomes "ready".
|
* those criteria are satisfied, the component becomes "ready".
|
||||||
*
|
*
|
||||||
* @this {ROM}
|
* @this {ROM}
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ function Video(parmsVideo, canvas, context, textarea, container)
|
||||||
if (sFileExt != "json") {
|
if (sFileExt != "json") {
|
||||||
sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + sFileURL + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;
|
sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + sFileURL + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;
|
||||||
}
|
}
|
||||||
web.loadResource(sFileURL, true, null, this, this.onLoadSetFonts);
|
web.loadResource(sFileURL, true, null, this, this.doneLoad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3710,17 +3710,17 @@ Video.prototype.restore = function(data)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onLoadSetFonts(sFontFile, sFontData, nErrorCode)
|
* doneLoad(sURL, sFontData, nErrorCode)
|
||||||
*
|
*
|
||||||
* @this {Video}
|
* @this {Video}
|
||||||
* @param {string} sFontFile
|
* @param {string} sURL
|
||||||
* @param {string} sFontData
|
* @param {string} sFontData
|
||||||
* @param {number} nErrorCode (response from server if anything other than 200)
|
* @param {number} nErrorCode (response from server if anything other than 200)
|
||||||
*/
|
*/
|
||||||
Video.prototype.onLoadSetFonts = function(sFontFile, sFontData, nErrorCode)
|
Video.prototype.doneLoad = function(sURL, sFontData, nErrorCode)
|
||||||
{
|
{
|
||||||
if (nErrorCode) {
|
if (nErrorCode) {
|
||||||
this.notice("Unable to load font ROM image (error " + nErrorCode + ")");
|
this.notice("Unable to load font ROM (error " + nErrorCode + ": " + sURL + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -3730,7 +3730,7 @@ Video.prototype.onLoadSetFonts = function(sFontFile, sFontData, nErrorCode)
|
||||||
var abFontData = eval("(" + sFontData + ")");
|
var abFontData = eval("(" + sFontData + ")");
|
||||||
|
|
||||||
if (!abFontData.length) {
|
if (!abFontData.length) {
|
||||||
Component.error("Empty font ROM image: " + sFontFile);
|
Component.error("Empty font ROM: " + sURL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (abFontData.length == 1) {
|
else if (abFontData.length == 1) {
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ var DumpAPI = {
|
||||||
},
|
},
|
||||||
FORMAT: {
|
FORMAT: {
|
||||||
JSON: "json", // default
|
JSON: "json", // default
|
||||||
|
JSON_GZ: "gz", // gzip is currently used ONLY for compressed JSON
|
||||||
DATA: "data", // same as "json", but built without JSON.stringify() (DiskDump only)
|
DATA: "data", // same as "json", but built without JSON.stringify() (DiskDump only)
|
||||||
HEX: "hex", // deprecated
|
HEX: "hex", // deprecated
|
||||||
BYTES: "bytes", // displays data as hex bytes; normally used only when comments are enabled
|
BYTES: "bytes", // displays data as hex bytes; normally used only when comments are enabled
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,6 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti
|
||||||
}
|
}
|
||||||
var nErrorCode = 0;
|
var nErrorCode = 0;
|
||||||
var sURLData = null;
|
var sURLData = null;
|
||||||
var sURLName = str.getBaseName(sURL);
|
|
||||||
var xmlHTTP = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP"));
|
var xmlHTTP = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP"));
|
||||||
if (fAsync) {
|
if (fAsync) {
|
||||||
xmlHTTP.onreadystatechange = function() {
|
xmlHTTP.onreadystatechange = function() {
|
||||||
|
|
@ -231,9 +230,9 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti
|
||||||
}
|
}
|
||||||
if (fnNotify) {
|
if (fnNotify) {
|
||||||
if (!componentNotify) {
|
if (!componentNotify) {
|
||||||
fnNotify(sURLName, sURLData, nErrorCode, pNotify);
|
fnNotify(sURL, sURLData, nErrorCode, pNotify);
|
||||||
} else {
|
} else {
|
||||||
fnNotify.call(componentNotify, sURLName, sURLData, nErrorCode, pNotify);
|
fnNotify.call(componentNotify, sURL, sURLData, nErrorCode, pNotify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,9 +266,9 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti
|
||||||
}
|
}
|
||||||
if (fnNotify) {
|
if (fnNotify) {
|
||||||
if (!componentNotify) {
|
if (!componentNotify) {
|
||||||
fnNotify(sURLName, sURLData, nErrorCode, pNotify);
|
fnNotify(sURL, sURLData, nErrorCode, pNotify);
|
||||||
} else {
|
} else {
|
||||||
fnNotify.call(componentNotify, sURLName, sURLData, nErrorCode, pNotify);
|
fnNotify.call(componentNotify, sURL, sURLData, nErrorCode, pNotify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response = [nErrorCode, sURLData];
|
response = [nErrorCode, sURLData];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue