PCjs can now connect a serial port to the console
This commit is contained in:
parent
0cc582405d
commit
464219a4c1
6 changed files with 367 additions and 117 deletions
|
|
@ -1,12 +1,15 @@
|
|||
{
|
||||
"machine": {
|
||||
"id": "ibm5150"
|
||||
},
|
||||
"computer": {
|
||||
"id": "ibm5150.pc-mda-64k",
|
||||
"id": "pc-mda-64k",
|
||||
"name": "IBM PC",
|
||||
"resume": "1",
|
||||
"state": ""
|
||||
},
|
||||
"ram": [
|
||||
{ "id": "ibm5150.ramLow",
|
||||
{ "id": "ramLow",
|
||||
"name": "",
|
||||
"addr": 0x00000,
|
||||
"size": 0,
|
||||
|
|
@ -14,14 +17,14 @@
|
|||
}
|
||||
],
|
||||
"rom": [
|
||||
{ "id": "ibm5150.romBASIC",
|
||||
{ "id": "romBASIC",
|
||||
"name": "",
|
||||
"addr": 0xf6000,
|
||||
"size": 0x08000,
|
||||
"file": "/devices/pc/basic/ibm-basic-1.00.json",
|
||||
"notify": ""
|
||||
},
|
||||
{ "id": "ibm5150.romBIOS",
|
||||
{ "id": "romBIOS",
|
||||
"name": "",
|
||||
"addr": 0xfe000,
|
||||
"size": 0x02000,
|
||||
|
|
@ -30,7 +33,7 @@
|
|||
}
|
||||
],
|
||||
"video": [
|
||||
{ "id": "ibm5150.videoMDA",
|
||||
{ "id": "videoMDA",
|
||||
"name": "Monochrome Display",
|
||||
"model": "",
|
||||
"mode": 7,
|
||||
|
|
@ -45,7 +48,7 @@
|
|||
}
|
||||
],
|
||||
"cpu": {
|
||||
"id": "ibm5150.cpu8088",
|
||||
"id": "cpu8088",
|
||||
"name": "",
|
||||
"model": 8088,
|
||||
"clock": 0,
|
||||
|
|
@ -56,12 +59,12 @@
|
|||
"csStop": -1
|
||||
},
|
||||
"keyboard": {
|
||||
"id": "ibm5150.keyboard",
|
||||
"id": "keyboard",
|
||||
"name": "",
|
||||
"model": ""
|
||||
},
|
||||
"fdc": {
|
||||
"id": "ibm5150.fdcNEC",
|
||||
"id": "fdcNEC",
|
||||
"name": "",
|
||||
"autoMount": {
|
||||
"A": {
|
||||
|
|
@ -75,7 +78,7 @@
|
|||
}
|
||||
},
|
||||
"chipset": {
|
||||
"id": "ibm5150.chipset",
|
||||
"id": "chipset",
|
||||
"name": "",
|
||||
"model": "5150",
|
||||
"sw1": "01000001",
|
||||
|
|
@ -83,7 +86,7 @@
|
|||
"sound": true
|
||||
},
|
||||
"debugger": {
|
||||
"id": "ibm5150.debugger",
|
||||
"id": "debugger",
|
||||
"name": "",
|
||||
"messages": ""
|
||||
},
|
||||
|
|
|
|||
|
|
@ -217,15 +217,32 @@ function loadMachine(sFile)
|
|||
* in the browser, by walking the list of PCjs components we loaded above and looking for
|
||||
* matches.
|
||||
*/
|
||||
var idMachine = "";
|
||||
|
||||
/*
|
||||
* 'machine' is a pseudo-component that is only used to define an ID for the entire machine;
|
||||
* if it exists, then that ID is prepended to every component ID, just as our XSLT code would
|
||||
* do for a machine XML file. This relieves the JSON file from having to manually prepend
|
||||
* a machine ID to every component ID itself.
|
||||
*
|
||||
* This doesn't mean I anticipate a Node environment running multiple machines, as we do in
|
||||
* a browser; it only means that I'm trying to make both environments operate similarly.
|
||||
*/
|
||||
if (machine['machine']) {
|
||||
idMachine = machine['machine']['id'];
|
||||
}
|
||||
|
||||
for (i = 0; i < aComponents.length; i++) {
|
||||
var parms = machine[aComponents[i].name];
|
||||
|
||||
var component = aComponents[i];
|
||||
var parms = machine[component.name];
|
||||
/*
|
||||
* If parms is undefined, it means there is no component with that name defined in the
|
||||
* machine object (NOT that the component has no parms), and therefore we should skip it.
|
||||
*/
|
||||
if (parms === undefined) continue;
|
||||
/*
|
||||
* If parms is an Array, then we must create an object for each parms element; and yes,
|
||||
* If parms is an Array, then we must create an object for each parms element; and yes,
|
||||
* I'm relying on the fact that none of my parm objects use a "length" property, as a quick
|
||||
* and dirty way of differentiating objects from arrays.
|
||||
*/
|
||||
|
|
@ -233,22 +250,27 @@ function loadMachine(sFile)
|
|||
for (j = 0; j < aParms.length; j++) {
|
||||
|
||||
var obj;
|
||||
if (fDebug) console.log("creating " + aComponents[i].name + "...");
|
||||
if (fDebug) console.log(aParms[j]);
|
||||
var parmsObj = aParms[j];
|
||||
if (idMachine) parmsObj['id'] = idMachine + '.' + parmsObj['id'];
|
||||
|
||||
if (aComponents[i].name == "cpu") {
|
||||
aParms[j]['autoStart'] = false;
|
||||
if (fDebug) {
|
||||
console.log("creating " + component.name + "...");
|
||||
console.log(parmsObj);
|
||||
}
|
||||
|
||||
if (component.name == "cpu") {
|
||||
parmsObj['autoStart'] = false;
|
||||
}
|
||||
|
||||
try {
|
||||
obj = new aComponents[i].Create(aParms[j]);
|
||||
obj = new component.Create(parmsObj);
|
||||
} catch(err) {
|
||||
console.log("error creating " + aComponents[i].name + ": " + err.message);
|
||||
console.log("error creating " + component.name + ": " + err.message);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(obj['id'] + " object created");
|
||||
aComponents[i].objects.push(obj);
|
||||
component.objects.push(obj);
|
||||
|
||||
if (obj.type == "Debugger") {
|
||||
dbg = obj;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
{
|
||||
"machine": {
|
||||
"id": "pc386"
|
||||
},
|
||||
"computer": {
|
||||
"id": "pc386.computer",
|
||||
"id": "computer",
|
||||
"name": "Compaq DeskPro 386",
|
||||
"resume": 0,
|
||||
"state": "",
|
||||
"busWidth": 32
|
||||
},
|
||||
"ram": [
|
||||
{ "id": "pc386.ramLow",
|
||||
{ "id": "ramLow",
|
||||
"name": "",
|
||||
"addr": 0,
|
||||
"size": 655360,
|
||||
|
|
@ -15,17 +18,17 @@
|
|||
}
|
||||
],
|
||||
"rom": [
|
||||
{ "id": "pc386.romTests",
|
||||
{ "id": "test386",
|
||||
"name": "",
|
||||
"addr": 983296,
|
||||
"size": 65280,
|
||||
"alias": 4294902016,
|
||||
"file": "/tests/pc/80386/tests.json",
|
||||
"file": "/tests/pc/80386/test386.json",
|
||||
"notify": ""
|
||||
}
|
||||
],
|
||||
"video": [
|
||||
{ "id": "pc386.videoMDA",
|
||||
{ "id": "videoMDA",
|
||||
"name": "Monochrome Display",
|
||||
"model": "",
|
||||
"mode": 7,
|
||||
|
|
@ -40,7 +43,7 @@
|
|||
}
|
||||
],
|
||||
"cpu": {
|
||||
"id": "pc386.cpu",
|
||||
"id": "cpu",
|
||||
"name": "",
|
||||
"model": 80386,
|
||||
"clock": 0,
|
||||
|
|
@ -51,12 +54,12 @@
|
|||
"csStop": -1
|
||||
},
|
||||
"keyboard": {
|
||||
"id": "pc386.keyboard",
|
||||
"id": "keyboard",
|
||||
"name": "",
|
||||
"model": ""
|
||||
},
|
||||
"fdc": {
|
||||
"id": "pc386.fdcNEC",
|
||||
"id": "fdcNEC",
|
||||
"name": "",
|
||||
"autoMount": {
|
||||
"A": {
|
||||
|
|
@ -70,13 +73,18 @@
|
|||
}
|
||||
},
|
||||
"chipset": {
|
||||
"id": "pc386.chipset",
|
||||
"id": "chipset",
|
||||
"name": "",
|
||||
"model": "deskpro386",
|
||||
"sound": false
|
||||
},
|
||||
"serialport": {
|
||||
"id": "com2",
|
||||
"adapter": 2,
|
||||
"binding": "console"
|
||||
},
|
||||
"debugger": {
|
||||
"id": "pc386.debugger",
|
||||
"id": "debugger",
|
||||
"name": "",
|
||||
"commands": "",
|
||||
"messages": ""
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
"use strict";
|
||||
|
||||
if (NODE) {
|
||||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
|
|
@ -79,9 +80,17 @@ function SerialPort(parmsSerial) {
|
|||
Component.warning("Unrecognized serial adapter #" + this.iAdapter);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* consoleOutput becomes a string that records serial port output if the 'binding' property is set to the
|
||||
* reserved name "console". Nothing is written to the console, however, until a linefeed (0x0A) is output
|
||||
* or the string length reaches a threshold (currently, 1024 characters).
|
||||
*
|
||||
* @type {string|null}
|
||||
*/
|
||||
this.consoleOutput = null;
|
||||
|
||||
/**
|
||||
* controlIOBuffer is a DOM element, if any, bound to the port (currently for output purposes only; see echoByte())
|
||||
* controlIOBuffer is a DOM element, if any, bound to the port (currently used for output only; see echoByte()).
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
|
@ -89,7 +98,15 @@ function SerialPort(parmsSerial) {
|
|||
|
||||
Component.call(this, "SerialPort", parmsSerial, SerialPort, Messages.SERIAL);
|
||||
|
||||
Component.bindExternalControl(this, parmsSerial['binding'], SerialPort.sIOBuffer);
|
||||
var sBinding = parmsSerial['binding'];
|
||||
if (sBinding == "console") {
|
||||
this.consoleOutput = "";
|
||||
} else {
|
||||
/*
|
||||
* NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.
|
||||
*/
|
||||
Component.bindExternalControl(this, sBinding, SerialPort.sIOBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -787,6 +804,14 @@ SerialPort.prototype.echoByte = function(b)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (this.consoleOutput != null) {
|
||||
this.consoleOutput += String.fromCharCode(b);
|
||||
if (b == 0x0A || this.consoleOutput.length >= 1024) {
|
||||
this.println(str.trim(this.consoleOutput));
|
||||
this.consoleOutput = "";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue