Fixed save/restore (hopefully) when A20 is off, as well as when HDC I/O is in progress (although the latter needs more testing)

This commit is contained in:
Jeff Parsons 2015-08-29 15:22:36 -07:00
commit 63121a1768
6 changed files with 99 additions and 57 deletions

View file

@ -790,8 +790,8 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
stateComputer.set(Computer.STATE_BROWSER, web.getUserAgent());
/*
* Always power the CPU "down" first, just to insure it doesn't ask other
* components to do anything after they're no longer ready.
* Always power the CPU "down" first, just to help insure it doesn't ask other components to do anything
* after they're no longer ready.
*/
if (this.cpu && this.cpu.powerDown) {
if (fShutdown) this.cpu.stopCPU();
@ -960,50 +960,53 @@ Computer.prototype.stop = function(ms, nCycles)
Computer.prototype.setBinding = function(sHTMLType, sBinding, control)
{
var computer = this;
switch (sBinding) {
case "save":
this.bindings[sBinding] = control;
control.onclick = function onClickSave() {
var sUserID = computer.queryUserID(true);
if (sUserID) {
/*
* I modified the test to include a check for sStatePath so that I could save new states
* for machines with existing states; otherwise, I'd have no (easy) way of capturing and
* updating their state. Making the machine (even temporarily) resumable would have been
* one work-around, but it's not appropriate for some machines, as their state is simply
* too large (for localStorage anyway, which is the default storage solution).
*/
var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);
var sState = computer.powerOff(fSave);
if (fSave) {
computer.saveServerState(sUserID, sState);
} else {
computer.notice("Resume disabled, machine state not saved");
}
}
case "save":
this.bindings[sBinding] = control;
control.onclick = function onClickSave() {
var sUserID = computer.queryUserID(true);
if (sUserID) {
/*
* This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:
*
* var sState = computer.powerOff(true);
* if (sState) {
* sState = "data:text/json;charset=utf-8," + encodeURIComponent(sState);
* window.open(sState);
* }
*
* Perhaps if I embedded the data in a link on the current page instead; eg:
*
* $('<a href="' + sState + '" download="state.json">Download</a>').appendTo('#container');
* I modified the test to include a check for sStatePath so that I could save new states
* for machines with existing states; otherwise, I'd have no (easy) way of capturing and
* updating their state. Making the machine (even temporarily) resumable would have been
* one work-around, but it's not appropriate for some machines, as their state is simply
* too large (for localStorage anyway, which is the default storage solution).
*/
};
return true;
case "reset":
this.bindings[sBinding] = control;
control.onclick = function onClickReset() {
computer.onReset();
};
return true;
default:
break;
var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);
var sState = computer.powerOff(fSave);
if (fSave) {
computer.saveServerState(sUserID, sState);
} else {
computer.notice("Resume disabled, machine state not saved");
}
}
/*
* This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:
*
* var sState = computer.powerOff(true);
* if (sState) {
* sState = "data:text/json;charset=utf-8," + encodeURIComponent(sState);
* window.open(sState);
* }
*
* Perhaps if I embedded the data in a link on the current page instead; eg:
*
* $('<a href="' + sState + '" download="state.json">Download</a>').appendTo('#container');
*/
};
return true;
case "reset":
this.bindings[sBinding] = control;
control.onclick = function onClickReset() {
computer.onReset();
};
return true;
default:
break;
}
return false;
};