Cross-machine serial port connections are only half-working (need to defer initConnection() until all machines on the page have initialized their bus)
This commit is contained in:
parent
f0509bc5d1
commit
0e4ad76b94
27 changed files with 1269 additions and 1191 deletions
|
|
@ -6,11 +6,11 @@ machines:
|
|||
- id: vt100a
|
||||
type: pc8080
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
connection: serialPort=vt100b.serialPort
|
||||
connection: serialPort->vt100b.serialPort
|
||||
- id: vt100b
|
||||
type: pc8080
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
connection: serialPort=vt100a.serialPort
|
||||
connection: serialPort->vt100a.serialPort
|
||||
---
|
||||
|
||||
Dual VT100 Terminals
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ machines:
|
|||
autoStart: true
|
||||
messages: mem|port
|
||||
config: /devices/pc8080/machine/vt100/debugger/machine.xml
|
||||
connection: serialPort=vt100b.serialPort
|
||||
connection: serialPort->vt100b.serialPort
|
||||
- id: vt100b
|
||||
type: pc8080
|
||||
debugger: true
|
||||
autoStart: true
|
||||
messages: mem|port
|
||||
config: /devices/pc8080/machine/vt100/debugger/machine.xml
|
||||
connection: serialPort=vt100a.serialPort
|
||||
connection: serialPort->vt100a.serialPort
|
||||
---
|
||||
|
||||
Dual VT100 Terminals with Debuggers
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ machines:
|
|||
- id: ibm5170
|
||||
type: pcx86
|
||||
debugger: true
|
||||
connection: com2->vt100.serialPort
|
||||
- id: vt100
|
||||
type: pc8080
|
||||
debugger: true
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
connection: serialPort->ibm5170.com2
|
||||
config: /devices/pc8080/machine/vt100/debugger/machine.xml
|
||||
---
|
||||
|
||||
{% include machine.html id="ibm5170" %}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var usr = require("../../shared/lib/usrlib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Memory8080 = require("./memory");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ if (NODE) {
|
|||
var usr = require("../../shared/lib/usrlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -38,13 +38,13 @@ if (NODE) {
|
|||
var UserAPI = require("../../shared/lib/userapi");
|
||||
var ReportAPI = require("../../shared/lib/reportapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
/*
|
||||
* TODO: I'm confused why WebStorm complains if the following require() is missing in THIS file but not other files.
|
||||
*/
|
||||
var PC8080 = require("./defines");
|
||||
var Bus8080 = require("./bus");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var CPU8080 = require("./cpu");
|
||||
var Messages8080= require("./messages");
|
||||
var Memory8080 = require("./memory");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ if (DEBUGGER) {
|
|||
var usr = require("../../shared/lib/usrlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var CPUDef8080 = require("./cpudef");
|
||||
var CPU8080 = require("./cpu");
|
||||
var Keyboard8080= require("./keyboard");
|
||||
var Messages8080= require("./messages");
|
||||
var Memory8080 = require("./memory");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Memory8080 = require("./memory");
|
||||
var ROM8080 = require("./rom");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -404,8 +404,8 @@ SerialPort8080.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/**
|
||||
* initConnection()
|
||||
*
|
||||
* If a machine 'connection' parameter exists of the form "<sourcePort>=<targetMachine>.<targetPort>",
|
||||
* and "<sourcePort>" matches our idComponent, then look for a component with id "<targetMachine>.<targetPort>".
|
||||
* If a machine 'connection' parameter exists of the form "{sourcePort}->{targetMachine}.{targetPort}",
|
||||
* and "{sourcePort}" matches our idComponent, then look for a component with id "{targetMachine}.{targetPort}".
|
||||
*
|
||||
* If the target component is found, then verify that it has exported functions with the following names:
|
||||
*
|
||||
|
|
@ -421,20 +421,22 @@ SerialPort8080.prototype.initConnection = function()
|
|||
{
|
||||
var sConnection = this.cmp.getMachineParm("connection");
|
||||
if (sConnection) {
|
||||
var asParts = sConnection.split('=');
|
||||
var asParts = sConnection.split('->');
|
||||
if (asParts.length == 2) {
|
||||
var sSourceID = str.trim(asParts[0]);
|
||||
if (sSourceID != this.idComponent) return; // this connection string is meant for another instance
|
||||
var sTargetID = str.trim(asParts[1]);
|
||||
if (sSourceID == this.idComponent) {
|
||||
this.connection = Component.getComponentByID(sTargetID);
|
||||
if (this.connection) {
|
||||
var exports = this.connection['exports'];
|
||||
if (exports) {
|
||||
this.sendData = exports['receiveData'];
|
||||
}
|
||||
this.connection = Component.getComponentByID(sTargetID);
|
||||
if (this.connection) {
|
||||
var exports = this.connection['exports'];
|
||||
if (exports) {
|
||||
this.sendData = exports['receiveData'];
|
||||
this.printMessage(this.idMachine + '.' + sSourceID + " connected to " + sTargetID, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.notice("Unable to establish connection: " + sConnection);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ if (NODE) {
|
|||
var web = require("../../shared/lib/weblib");
|
||||
var DumpAPI = require("../../shared/lib/dumpapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var ChipSet8080 = require("./chipset");
|
||||
var Memory8080 = require("./memory");
|
||||
var Messages8080= require("./messages");
|
||||
var State8080 = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var usr = require("../../shared/lib/usrlib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Memory = require("./memory");
|
||||
var Messages = require("./messages");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ if (NODE) {
|
|||
var usr = require("../../shared/lib/usrlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Interrupts = require("./interrupts");
|
||||
var Messages = require("./messages");
|
||||
var State = require("./state");
|
||||
var X86 = require("./x86");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ if (NODE) {
|
|||
var UserAPI = require("../../shared/lib/userapi");
|
||||
var ReportAPI = require("../../shared/lib/reportapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var Bus = require("./bus");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ if (DEBUGGER) {
|
|||
var usr = require("../../shared/lib/usrlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Interrupts = require("./interrupts");
|
||||
var Messages = require("./messages");
|
||||
var Memory = require("./memory");
|
||||
var Keyboard = require("./keyboard");
|
||||
var State = require("./state");
|
||||
var CPU = require("./cpu");
|
||||
var X86 = require("./x86");
|
||||
var X86Seg = require("./x86seg");
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ if (NODE) {
|
|||
var web = require("../../shared/lib/weblib");
|
||||
var DiskAPI = require("../../shared/lib/diskapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var Disk = require("./disk");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ if (NODE) {
|
|||
var web = require("../../shared/lib/weblib");
|
||||
var DiskAPI = require("../../shared/lib/diskapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Interrupts = require("./interrupts");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var Disk = require("./disk");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var State = require("./state");
|
||||
var CPU = require("./cpu");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var SerialPort = require("./serialport");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -623,7 +623,7 @@ Mouse.prototype.sendPacket = function(sDiag, xDiag, yDiag)
|
|||
if (this.messageEnabled(Messages.SERIAL)) {
|
||||
this.printMessage((sDiag? (sDiag + ": ") : "") + (yDiag !== undefined? ("mouse (" + xDiag + "," + yDiag + "): ") : "") + "serial packet [" + str.toHexByte(b1) + "," + str.toHexByte(b2) + "," + str.toHexByte(b3) + "]", 0, true);
|
||||
}
|
||||
this.componentAdapter.sendRBR([b1, b2, b3]);
|
||||
this.componentAdapter.receiveData([b1, b2, b3]);
|
||||
this.xDelta = this.yDelta = 0;
|
||||
};
|
||||
|
||||
|
|
@ -681,7 +681,7 @@ Mouse.prototype.notifyMCR = function(bMCR)
|
|||
* bytes on a reset. This doesn't seem to adversely affect serial mouse emulation for Windows 1.01, so
|
||||
* I'm calling this good enough for now.
|
||||
*/
|
||||
this.componentAdapter.sendRBR([Mouse.ID_SERIAL, Mouse.ID_SERIAL]);
|
||||
this.componentAdapter.receiveData([Mouse.ID_SERIAL, Mouse.ID_SERIAL]);
|
||||
this.printMessage("serial mouse ID sent");
|
||||
}
|
||||
this.captureAll();
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@
|
|||
if (NODE) {
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Memory = require("./memory");
|
||||
var ROM = require("./rom");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,6 +126,19 @@ function SerialPort(parmsSerial) {
|
|||
*/
|
||||
Component.bindExternalControl(this, sBinding, SerialPort.sIOBuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* No connection until initBus() invokes initConnection().
|
||||
*/
|
||||
this.sDataReceived = "";
|
||||
this.connection = this.sendData = null;
|
||||
|
||||
/*
|
||||
* Export all functions required by initConnection(); currently, this is the bare minimum, with no flow control.
|
||||
*/
|
||||
this['exports'] = {
|
||||
'receiveData': this.receiveData
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -386,7 +399,7 @@ SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {
|
||||
if (event.preventDefault) event.preventDefault();
|
||||
if (keyCode > 0x40) keyCode -= 0x40;
|
||||
serial.sendRBR([keyCode]);
|
||||
serial.receiveData(keyCode);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
|
@ -398,7 +411,7 @@ SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
*/
|
||||
event = event || window.event;
|
||||
var keyCode = event.which || event.keyCode;
|
||||
serial.sendRBR([keyCode]);
|
||||
serial.receiveData(keyCode);
|
||||
/*
|
||||
* Since we're going to remove the "readonly" attribute from the <textarea> control
|
||||
* (so that the soft keyboard activates on iOS), instead of calling preventDefault() for
|
||||
|
|
@ -436,15 +449,60 @@ SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
*/
|
||||
SerialPort.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
|
||||
this.chipset = cmp.getMachineComponent("ChipSet");
|
||||
|
||||
bus.addPortInputTable(this, SerialPort.aPortInput, this.portBase);
|
||||
bus.addPortOutputTable(this, SerialPort.aPortOutput, this.portBase);
|
||||
|
||||
this.initConnection();
|
||||
|
||||
this.setReady();
|
||||
};
|
||||
|
||||
/**
|
||||
* initConnection()
|
||||
*
|
||||
* If a machine 'connection' parameter exists of the form "{sourcePort}->{targetMachine}.{targetPort}",
|
||||
* and "{sourcePort}" matches our idComponent, then look for a component with id "{targetMachine}.{targetPort}".
|
||||
*
|
||||
* If the target component is found, then verify that it has exported functions with the following names:
|
||||
*
|
||||
* receiveData(data): called when we have data to transmit; aliased internally to sendData(data)
|
||||
*
|
||||
* For now, we're not going to worry about communication in the other direction, because when the target component
|
||||
* performs its own initConnection(), it will find our receiveByte(b) function, at which point communication in both
|
||||
* directions should be established.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
*/
|
||||
SerialPort.prototype.initConnection = function()
|
||||
{
|
||||
var sConnection = this.cmp.getMachineParm("connection");
|
||||
if (sConnection) {
|
||||
var asParts = sConnection.split('->');
|
||||
if (asParts.length == 2) {
|
||||
var sSourceID = str.trim(asParts[0]);
|
||||
if (sSourceID != this.idComponent) return; // this connection string is meant for another instance
|
||||
var sTargetID = str.trim(asParts[1]);
|
||||
this.connection = Component.getComponentByID(sTargetID);
|
||||
if (this.connection) {
|
||||
var exports = this.connection['exports'];
|
||||
if (exports) {
|
||||
this.sendData = exports['receiveData'];
|
||||
this.printMessage(this.idMachine + '.' + sSourceID + " connected to " + sTargetID, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.notice("Unable to establish connection: " + sConnection);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
|
|
@ -583,14 +641,28 @@ SerialPort.prototype.saveRegisters = function()
|
|||
};
|
||||
|
||||
/**
|
||||
* sendRBR(ab)
|
||||
* receiveData(data)
|
||||
*
|
||||
* This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,
|
||||
* but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we
|
||||
* have added support for numbers and strings as well.
|
||||
*
|
||||
* @this {SerialPort}
|
||||
* @param {Array} ab is an array of bytes to propagate to the bRBR (Receiver Buffer Register)
|
||||
* @param {number|string|Array} data
|
||||
*/
|
||||
SerialPort.prototype.sendRBR = function(ab)
|
||||
SerialPort.prototype.receiveData = function(data)
|
||||
{
|
||||
this.abReceive = this.abReceive.concat(ab);
|
||||
if (typeof data == "number") {
|
||||
this.abReceive.push(data);
|
||||
}
|
||||
else if (typeof data == "string") {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
this.abReceive.push(data.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.abReceive = this.abReceive.concat(data);
|
||||
}
|
||||
this.advanceRBR();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ if (NODE) {
|
|||
var web = require("../../shared/lib/weblib");
|
||||
var DumpAPI = require("../../shared/lib/dumpapi");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Memory = require("./memory");
|
||||
var Messages = require("./messages");
|
||||
var ChipSet = require("./chipset");
|
||||
var Keyboard = require("./keyboard");
|
||||
var Mouse = require("./mouse");
|
||||
var State = require("./state");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("../../shared/lib/state");
|
||||
var Messages = require("./messages");
|
||||
var Memory = require("./memory");
|
||||
var State = require("./state");
|
||||
var CPU = require("./cpu");
|
||||
var X86 = require("./x86");
|
||||
var X86Seg = require("./x86seg");
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ if (NODE) {
|
|||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var State = require("./state");
|
||||
var State = require("../../shared/lib/state");
|
||||
var X86 = require("./x86");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue