Support for sticky machines when using the Node web server (so that we have parity between the Node and Jekyll web environments)
This commit is contained in:
parent
61be09d54a
commit
0eccf30d3c
4 changed files with 89 additions and 15 deletions
56
_posts/2017-01-03-pdp-11-tutorials.md
Normal file
56
_posts/2017-01-03-pdp-11-tutorials.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: PDP-11 Tutorials
|
||||||
|
date: 2017-01-03 15:00:00
|
||||||
|
permalink: /blog/2017/01/03/
|
||||||
|
machines:
|
||||||
|
- id: test1170
|
||||||
|
type: pdp11
|
||||||
|
debugger: true
|
||||||
|
config: /devices/pdp11/machine/1170/vt100/debugger/machine.xml
|
||||||
|
connection: dl11->vt100.serialPort
|
||||||
|
- id: vt100
|
||||||
|
type: pc8080
|
||||||
|
config: /devices/pc8080/machine/vt100/machine.xml
|
||||||
|
connection: serialPort->test1170.dl11
|
||||||
|
sticky: top
|
||||||
|
---
|
||||||
|
|
||||||
|
Introducing PDP-11 tutorials!
|
||||||
|
|
||||||
|
{% include machine.html id="vt100" %}
|
||||||
|
|
||||||
|
[PDPjs](/devices/pdp11/machine/) is the newest addition to the PCjs family of emulators, joining PCx86, PC8080, and C1Pjs.
|
||||||
|
|
||||||
|
While PDPjs may eventually support a range of DEC PDP machines, my current focus is on the PDP-11, starting with the
|
||||||
|
PDP-11/70. From there, I'll work backwards to support other PDP-11 models, such as the PDP-11/45, until I reach the
|
||||||
|
beginning of the PDP-11 line: the PDP-11/20.
|
||||||
|
|
||||||
|
I'm starting with the top-of-the-line PDP-11/70 largely because the core of the emulator is being adapted from the
|
||||||
|
JavaScript [PDP-11/70 Emulator (v1.3)](http://skn.noip.me/pdp11/pdp11.html) written by
|
||||||
|
Paul Nankervis, who has generously given permission to use his code in PCjs. Since his emulator is a fully functional
|
||||||
|
11/70, it made sense to start there and work backwards, factoring out features as needed.
|
||||||
|
|
||||||
|
The code has already undergone a lot of refactoring. Opcodes are now decoded by function tables rather than a single
|
||||||
|
switch statement, and every opcode is implemented with a discrete function. Other refactoring includes flag management,
|
||||||
|
interrupt management, and device management.
|
||||||
|
|
||||||
|
Most of the work remaining is in device management. Like other PCjs emulators, PDPjs has a Bus component,
|
||||||
|
[bus.js](/modules/pdp11/lib/bus.js), that allows separate device components to register I/O handlers for specific
|
||||||
|
UNIBUS addresses. During the initial port, I moved all of Paul's original device management code into one "catch-all"
|
||||||
|
component, [device.js](/modules/pdp11/lib/device.js), which has now been converted to the new I/O registration model.
|
||||||
|
|
||||||
|
The first new device component is [serial.js](/modules/pdp11/lib/serial.js), which is currently the
|
||||||
|
only means PDPjs has of communicating with the outside world. So you can try
|
||||||
|
[PDPjs connected to a VT100 Terminal](/devices/pdp11/machine/1170/vt100/), by clicking the **Run** button on the test machine.
|
||||||
|
The test machine is running [custom boot code](/apps/pdp11/boot/test/), adapted from boot code written by Paul, but due to the
|
||||||
|
lack of other device support, nothing can be booted yet.
|
||||||
|
|
||||||
|
Obviously PDPjs is very much a work-in-progress. Before I proceed much farther, I really want to put the CPU through
|
||||||
|
some rigorous testing, so I'll be on the lookout for some comprehensive PDP-11 instruction tests. Or I'll write my own,
|
||||||
|
and compare results across 1 or 2 other PDP-11 emulators.
|
||||||
|
|
||||||
|
{% include machine.html id="test1170" %}
|
||||||
|
|
||||||
|
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||||
|
*Jan 3, 2017*
|
||||||
|
|
@ -879,6 +879,7 @@ HTMLOut.prototype.findTokens = function(reTokens)
|
||||||
aParms.push(aMatch[1]);
|
aParms.push(aMatch[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//noinspection JSUnresolvedFunction
|
||||||
fnToken.call(this, sToken, sIndent, aParms);
|
fnToken.call(this, sToken, sIndent, aParms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1968,6 +1969,12 @@ HTMLOut.prototype.processMachines = function(aMachines, buildOptions, done)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.addFilesToHTML(asFiles, sScriptEmbed);
|
this.addFilesToHTML(asFiles, sScriptEmbed);
|
||||||
|
if (infoMachine['sticky']) {
|
||||||
|
asFiles = [];
|
||||||
|
asFiles.push("/modules/shared/lib/sticky.js");
|
||||||
|
sScriptEmbed = '<script type="text/javascript">addStickyMachine("' + infoMachine['id'] + '")</script>';
|
||||||
|
this.addFilesToHTML(asFiles, sScriptEmbed);
|
||||||
|
}
|
||||||
if (buildOptions.id) {
|
if (buildOptions.id) {
|
||||||
asFiles = [];
|
asFiles = [];
|
||||||
asFiles.push("/modules/build/lib/build.js");
|
asFiles.push("/modules/build/lib/build.js");
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,7 @@ MarkOut.aFMBooleanMachineProps = {
|
||||||
'autopower': "autoPower",
|
'autopower': "autoPower",
|
||||||
'autostart': "autoStart"
|
'autostart': "autoStart"
|
||||||
};
|
};
|
||||||
MarkOut.aFMReservedMachineProps = ['id', 'name', 'type', 'debugger', 'config', 'template', 'uncompiled', 'autoMount', 'drives', 'parms'];
|
MarkOut.aFMReservedMachineProps = ['id', 'name', 'type', 'debugger', 'config', 'template', 'uncompiled', 'autoMount', 'drives', 'parms', 'sticky'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convertMD()
|
* convertMD()
|
||||||
|
|
@ -1167,6 +1167,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
||||||
var machine = this.aMachineDefs[sMachineID];
|
var machine = this.aMachineDefs[sMachineID];
|
||||||
sMachineType = machine['type'] || "PCx86";
|
sMachineType = machine['type'] || "PCx86";
|
||||||
sMachineOptions = ((sMachineType.indexOf("-dbg") > 0 || machine['debugger'] == "true")? "debugger" : "");
|
sMachineOptions = ((sMachineType.indexOf("-dbg") > 0 || machine['debugger'] == "true")? "debugger" : "");
|
||||||
|
if (machine['sticky']) sMachineOptions += (sMachineOptions? "," : "") + "sticky";
|
||||||
sMachineType = sMachineType.replace("-dbg", "");
|
sMachineType = sMachineType.replace("-dbg", "");
|
||||||
sMachineXMLFile = machine['config'] || this.sMachineFile || "machine.xml";
|
sMachineXMLFile = machine['config'] || this.sMachineFile || "machine.xml";
|
||||||
sMachineXSLFile = machine['template'] || "";
|
sMachineXSLFile = machine['template'] || "";
|
||||||
|
|
@ -1204,6 +1205,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
||||||
sMachineParms = aMachineParms[4] || "";
|
sMachineParms = aMachineParms[4] || "";
|
||||||
var aMachineOptions = sMachineOptions.split(',');
|
var aMachineOptions = sMachineOptions.split(',');
|
||||||
var fDebugger = (aMachineOptions.indexOf("debugger") >= 0);
|
var fDebugger = (aMachineOptions.indexOf("debugger") >= 0);
|
||||||
|
var fSticky = (aMachineOptions.indexOf("sticky") >= 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Consider validating the existence of this XML file and generating a more meaningful error if not found
|
* TODO: Consider validating the existence of this XML file and generating a more meaningful error if not found
|
||||||
|
|
@ -1247,6 +1249,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
||||||
'xsl': sMachineXSLFile,
|
'xsl': sMachineXSLFile,
|
||||||
'version': sMachineVersion,// eg, "1.10", "*" to select the current version, or "uncompiled"; "*" is the default
|
'version': sMachineVersion,// eg, "1.10", "*" to select the current version, or "uncompiled"; "*" is the default
|
||||||
'debugger': fDebugger, // eg, true or false; false is the default
|
'debugger': fDebugger, // eg, true or false; false is the default
|
||||||
|
'sticky': fSticky, // eg, true or false; false is the default
|
||||||
'parms': sMachineParms}
|
'parms': sMachineParms}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,31 +35,39 @@
|
||||||
*/
|
*/
|
||||||
function addStickyMachine(idMachine)
|
function addStickyMachine(idMachine)
|
||||||
{
|
{
|
||||||
var machine = document.getElementById(idMachine);
|
var topMachine = -1;
|
||||||
if (machine) {
|
var prevOnScroll = window.onscroll;
|
||||||
var machineFooter = document.getElementById(idMachine + '.footer');
|
window.onscroll = function() {
|
||||||
if (machineFooter) {
|
/*
|
||||||
var topMachine = findTop(machine);
|
* TODO: Determine if/when we can cache the machine and machineSibling elements; we already
|
||||||
var prevOnScroll = window.onscroll;
|
* know we can't cache them when addStickyMachine() is first called, because that currently
|
||||||
window.onscroll = function() {
|
* happens *before* embed.js replaces the placeholder machine DIV with the *real* machine DIV.
|
||||||
|
*/
|
||||||
|
var machine = document.getElementById(idMachine);
|
||||||
|
if (machine) {
|
||||||
|
var machineSibling = machine.nextElementSibling;
|
||||||
|
if (machineSibling) {
|
||||||
|
if (topMachine < 0) {
|
||||||
|
topMachine = findTop(machine);
|
||||||
|
}
|
||||||
if (window.pageYOffset <= topMachine) {
|
if (window.pageYOffset <= topMachine) {
|
||||||
machine.style.position = 'relative';
|
machine.style.position = 'relative';
|
||||||
machine.style.zIndex = 'auto';
|
machine.style.zIndex = 'auto';
|
||||||
machine.style.backgroundColor = '';
|
machine.style.backgroundColor = '';
|
||||||
machine.style.paddingRight = 0;
|
machine.style.paddingRight = 0;
|
||||||
if (machineFooter) machineFooter.style.paddingTop = 0;
|
if (machineSibling) machineSibling.style.paddingTop = 0;
|
||||||
} else {
|
} else {
|
||||||
machine.style.position = 'fixed';
|
machine.style.position = 'fixed';
|
||||||
machine.style.zIndex = 1;
|
machine.style.zIndex = 1;
|
||||||
machine.style.backgroundColor = 'white';
|
machine.style.backgroundColor = '#404040';
|
||||||
machine.style.paddingRight = '30px';
|
machine.style.paddingRight = '16px';
|
||||||
machine.style.top = 0;
|
machine.style.top = 0;
|
||||||
if (machineFooter) machineFooter.style.paddingTop = machine.offsetHeight + 'px';
|
if (machineSibling) machineSibling.style.paddingTop = machine.offsetHeight + 'px';
|
||||||
}
|
}
|
||||||
};
|
if (prevOnScroll) prevOnScroll();
|
||||||
if (prevOnScroll) prevOnScroll();
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Loading…
Reference in a new issue