Added more scripting support to PCx86 (eg, for loading disks, typing keys, and waiting for both to finish)

This commit is contained in:
Jeff Parsons 2017-07-25 10:30:29 -07:00 committed by Jeff Parsons
commit 1b987df6e2
9 changed files with 1251 additions and 1186 deletions

View file

@ -194,7 +194,8 @@ class FDC extends Component {
*/
this['exports'] = {
'loadDisk': this.loadSelectedDisk
'loadDisk': this.loadSelectedDisk,
'wait': this.waitDrives
};
}
@ -274,24 +275,7 @@ class FDC extends Component {
}
}
controlSelect.onchange = function onChangeListDisks(event) {
var controlDesc = fdc.bindings["descDisk"];
var controlOption = controlSelect.options[controlSelect.selectedIndex];
if (controlDesc && controlOption) {
var dataValue = {};
var sValue = controlOption.getAttribute("data-value");
if (sValue) {
try {
dataValue = eval("(" + sValue + ")");
} catch (e) {
Component.error("FDC option error: " + e.message);
}
}
var sHTML = dataValue['desc'];
if (sHTML === undefined) sHTML = "";
var sHRef = dataValue['href'];
if (sHRef !== undefined) sHTML = "<a href=\"" + sHRef + "\" target=\"_blank\">" + sHTML + "</a>";
controlDesc.innerHTML = sHTML;
}
fdc.updateSelectedDiskette();
};
return true;
@ -749,6 +733,7 @@ class FDC extends Component {
drive.iDrive = iDrive;
drive.fBusy = drive.fLocal = false;
drive.fnCallReady = null;
if (data === undefined) {
/*
@ -1106,6 +1091,9 @@ class FDC extends Component {
/**
* loadSelectedDisk()
*
* NOTE: Since this can be called via script command (eg, 'loadDisk FDC'), additional parameters can be
* passed; use the arguments array to access them if necessary.
*
* @this {FDC}
* @return {boolean}
*/
@ -1331,7 +1319,7 @@ class FDC extends Component {
* WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic
* and will not match the drive mappings that DOS ultimately uses (ie, for drives beyond B:).
*/
this.notice("Mounted diskette \"" + sDisketteName + "\" in drive " + String.fromCharCode(0x41 + drive.iDrive), drive.fAutoMount || fAutoMount);
if (!drive.fnCallReady) this.notice("Mounted diskette \"" + sDisketteName + "\" in drive " + String.fromCharCode(0x41 + drive.iDrive), drive.fAutoMount || fAutoMount);
/*
* Update the drive's current media parameters to match the disk's.
@ -1356,6 +1344,11 @@ class FDC extends Component {
}
this.displayDiskette(drive.iDrive);
if (drive.fnCallReady) {
drive.fnCallReady();
drive.fnCallReady = null;
}
}
/**
@ -1481,6 +1474,53 @@ class FDC extends Component {
}
}
/**
* updateSelectedDiskette()
*
* @this {FDC}
*/
updateSelectedDiskette()
{
var control = this.bindings["listDisks"];
var controlDesc = this.bindings["descDisk"];
var controlOption = control.options[control.selectedIndex];
if (controlDesc && controlOption) {
var dataValue = {};
var sValue = controlOption.getAttribute("data-value");
if (sValue) {
try {
dataValue = eval("(" + sValue + ")");
} catch (e) {
Component.error(this.type + " option error: " + e.message);
}
}
var sHTML = dataValue['desc'];
if (sHTML === undefined) sHTML = "";
var sHRef = dataValue['href'];
if (sHRef !== undefined) sHTML = "<a href=\"" + sHRef + "\" target=\"_blank\">" + sHTML + "</a>";
controlDesc.innerHTML = sHTML;
}
}
/**
* waitDrives(fnCallReady)
*
* @this {FDC}
* @param {function()|null} fnCallReady
* @return {boolean} false if wait required, true otherwise
*/
waitDrives(fnCallReady)
{
for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {
var drive = this.aDrives[iDrive];
if (drive && drive.fBusy) {
if (!drive.fnCallReady) drive.fnCallReady = fnCallReady;
return false;
}
}
return true;
}
/**
* unloadDrive(iDrive, fAutoUnload, fQuiet)
*

View file

@ -159,6 +159,11 @@ class Keyboard extends Component {
*/
this.fAllDown = false;
this['exports'] = {
'type': this.injectKeys,
'wait': this.waitReady
};
this.setReady();
}
@ -380,9 +385,7 @@ class Keyboard extends Component {
intDOS(addr)
{
var AH = (this.cpu.regEAX >> 8) & 0xff;
if (AH == 0x0A) {
this.injectInit();
}
if (AH == 0x0A) this.injectInit(this.autoType);
return true;
}
@ -402,7 +405,7 @@ class Keyboard extends Component {
}
/**
* parseAutoType(sKeys)
* parseKeys(sKeys)
*
* The following special sequences are recognized:
*
@ -438,7 +441,7 @@ class Keyboard extends Component {
* @param {string|undefined} sKeys
* @return {string|undefined}
*/
parseAutoType(sKeys)
parseKeys(sKeys)
{
if (sKeys) {
var match, reSpecial = /(?:^|[^$])\$([a-z]+)/g;
@ -862,7 +865,7 @@ class Keyboard extends Component {
data = [];
this.autoInject = null;
} else {
this.autoInject = this.parseAutoType(this.autoType);
this.autoInject = this.autoType;
}
this.fClock = this.fAdvance = data[i++];
this.fData = data[i];
@ -888,6 +891,8 @@ class Keyboard extends Component {
* Make sure the auto-injection buffer is empty (an injection could have been in progress on any reset after the first).
*/
this.sInjectBuffer = "";
this.fnCallReady = null;
return true;
}
@ -950,16 +955,19 @@ class Keyboard extends Component {
}
/**
* injectInit()
* injectInit(sKeys)
*
* @this {Keyboard}
* @param {string|undefined} sKeys
* @return {boolean}
*/
injectInit()
injectInit(sKeys)
{
if (!this.autoInject && this.autoType) {
this.autoInject = this.parseAutoType(this.autoType);
this.injectKeys(this.autoInject);
if (!this.autoInject && sKeys) {
this.autoInject = sKeys;
return this.injectKeys(this.autoInject);
}
return false;
}
/**
@ -968,14 +976,17 @@ class Keyboard extends Component {
* @this {Keyboard}
* @param {string|undefined} sKeys
* @param {number} [msDelay] is an optional injection delay (default is msInjectDelay)
* @return {boolean}
*/
injectKeys(sKeys, msDelay)
{
if (sKeys && !this.sInjectBuffer) {
this.sInjectBuffer = sKeys;
this.sInjectBuffer = this.parseKeys(sKeys);
if (!COMPILED) this.log("injectKeys(" + this.sInjectBuffer.split("\n").join("\\n") + ")");
this.injectKeysFromBuffer(msDelay || this.msInjectDelay);
return true;
}
return false;
}
/**
@ -1014,7 +1025,12 @@ class Keyboard extends Component {
if (charCode == 0x0A) charCode = 0x0D;
this.addActiveKey(charCode, true);
}
if (this.sInjectBuffer.length > 0) {
if (!this.sInjectBuffer.length) {
if (this.fnCallReady) {
this.fnCallReady();
this.fnCallReady = null;
}
} else {
setTimeout(function(kbd) {
return function onInjectKeyTimeout() {
kbd.injectKeysFromBuffer(msDelay);
@ -1023,6 +1039,22 @@ class Keyboard extends Component {
}
}
/**
* waitReady(fnCallReady)
*
* @this {Keyboard}
* @param {function()|null} fnCallReady
* @return {boolean} false if wait required, true otherwise
*/
waitReady(fnCallReady)
{
if (this.sInjectBuffer.length > 0) {
if (!this.fnCallReady) this.fnCallReady = fnCallReady;
return false;
}
return true;
}
/**
* setLED(control, f)
*