Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

Commit

Permalink
Merge branch 'next-release'
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffpar committed Dec 27, 2016
2 parents 0b207b7 + 0ab16dc commit da4c902
Show file tree
Hide file tree
Showing 28 changed files with 652 additions and 509 deletions.
13 changes: 10 additions & 3 deletions apps/pdp11/tapes/diags/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Running Paper Tape Diagnostics

Instructions for running "TEST 1 - BRANCH" through "TEST 12 - JUMP" come from the
[MAINDEC-11-DZQAB MAINDEC USER REFERENCE MANUAL (Oct 1973)](http://archive.pcjs.org/pubs/dec/pdp11/diags/MAINDEC-11-DZQAB-B-D_User_Reference_Manual_Oct73.pdf),
p. 19:
page 19:

MAINDEC-11-D0AA to D0LA (NEW NUMBER - DZKAA to DZKAL)

Expand Down Expand Up @@ -250,7 +250,7 @@ so for now, I'm just going to pick out selected tapes and archive them here.

From [bitsavers.org](http://bitsavers.trailing-edge.com/bits/DEC/pdp11/papertapeimages/20040101/), Tray 02:

* Tape 04: [MAINDEC-11-DEQKC-B1-PB 06/12/78; 11/70 cpu instruction exerciser; (c)1975,76](#md-11-1170-cpu-exerciser)
* Tape 04: [MAINDEC-11-DEQKC-B1-PB 06/12/78; 11/70 cpu instruction exerciser; (c)1975,76](#md-11-1170-cpu-exerciser) [[1980 Listing](http://bitsavers.org/pdf/dec/pdp11/microfiche/ftp.j-hoppe.de/bw/gh/AH-7996E-MC__PDP11-70-74__11-70_INST_EXR__CEQKCE0__%28C%2975,80.pdf)]

MD-11 11/70 CPU EXERCISER
-------------------------
Expand Down Expand Up @@ -336,7 +336,7 @@ I disassembled the code responsible for that failure:
I wasn't able to locate a source code listing for this particular (1978) version of the 11/70 CPU Instruction Exerciser,
but I did find another useful document,
[MAINDEC-11-DCQKC 11/40 and 11/45 INSTRUCTION EXERCISER (Sep 1974)](http://archive.pcjs.org/pubs/dec/pdp11/diags/MAINDEC-11-DCQKC-D-D_1140_1145_INSTRUCTION_EXERCISER_Sep74.pdf),
where I discovered a matching test sequence on p. 86.
where I discovered a matching test sequence on page 86.

Here's an excerpt:

Expand Down Expand Up @@ -373,6 +373,13 @@ to trap when SP is 150. That contradicts this newer test (ie, that TST should n
trap "BECAUSE TST IS A NON MODIFYING INST"). For this and other reasons, PDPjs now installs different
checkStackLimit() handlers based on the CPU model.

UPDATE: Another (1980) version of the source code for this diagnostic has been located and archived
with the rest of our [DEC PDP-11 Diagnostic Publications](/pubs/dec/pdp11/diags/):

- [CEQKCE0 11/70 INSTRUCTION EXERCISER (May 1980)](http://archive.pcjs.org/pubs/dec/pdp11/diags/AC-7994E-MC_CEQKCE0_1170_INSTRUCTION_EXERCISER_May80.pdf) [[Original PDF](http://bitsavers.org/pdf/dec/pdp11/microfiche/ftp.j-hoppe.de/bw/gh/AH-7996E-MC__PDP11-70-74__11-70_INST_EXR__CEQKCE0__%28C%2975,80.pdf)]

You'll find the above excerpt on page 114, at address 024624.

---

Here's the next test that PDPjs failed. Again, I found the same sequence of instructions in the 11/40 and 11/45
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<device id="default" type="default"/>
<serial id="dl11" adapter="0" binding="print"/>
<panel ref="/devices/pdp11/panel/1170/debugger/front.xml"/>
<debugger id="debugger" base="8" messages="rk11" commands='bp 33330 "bp 037772; bp 041734; bp 042164"'/>
<debugger id="debugger" base="8" messages="rk11|pc11" commands='bp 033330 "bp 037772; bp 041734; bp 042164"'/>
<device ref="/devices/pdp11/pc11/default.xml"/>
<device ref="/devices/pdp11/rk11/default.xml"/>
<device ref="/devices/pdp11/rl11/default.xml"/>
Expand Down
1 change: 1 addition & 0 deletions modules/markout/lib/markout.js
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ MarkOut.prototype.convertMDLinks = function(sBlock)
} else {
sURL = net.encodeURL(sURL, this.req, this.fDebug);
}
sURL = sURL.replace(/_/g, "%5F"); // this helps prevent emphasis detection in URLs
sBlock = str.replaceAll(aMatch[0], '<' + sTag + ' ' + sType + '="' + sURL + '"' + sTitle + '>' + sText + '</' + sTag + '>', sBlock);
}
return sBlock;
Expand Down
4 changes: 2 additions & 2 deletions modules/pcx86/lib/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
kbd.addActiveKey(simCode);
};
}(this, sBinding, Keyboard.SOFTCODES[sBinding]);
var fnUp = function (kbd, sKey, simCode) {
var fnUp = function(kbd, sKey, simCode) {
return function onKeyboardBindingUp(event) {
kbd.removeActiveKey(simCode);
};
Expand Down Expand Up @@ -1655,7 +1655,7 @@ Keyboard.prototype.injectKeysFromBuffer = function(msDelay)
this.addActiveKey(ch, true);
}
if (this.sInjectBuffer.length > 0) {
setTimeout(function (kbd) {
setTimeout(function(kbd) {
return function onInjectKeyTimeout() {
kbd.injectKeysFromBuffer(msDelay);
};
Expand Down
99 changes: 82 additions & 17 deletions modules/pdp11/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,94 @@ PDP-11 Machine Emulation Module (PDPjs)

Overview
---
PDPjs, our [PDP-11 Machine](/devices/pdp11/machine/) emulation module, is adapted from
the [PDP-11/70 Emulator (v1.4)](http://skn.noip.me/pdp11/pdp11.html) written by
Paul Nankervis.
PDPjs, our [PDP-11 Machine](/devices/pdp11/machine/) emulation module, was written in 2016. It was adapted from
the [PDP-11/70 Emulator (v1.4)](http://skn.noip.me/pdp11/pdp11.html) written by Paul Nankervis.

PDPjs is currently comprised of the following non-shared components, as listed in
[package.json](../../package.json) (see the *pdp11Files* property):
PDPjs is currently comprised of the following PDP-11 components, as listed in [package.json](../../package.json)
(see the *pdp11Files* property):

* [defines.js](/modules/pdp11/lib/defines.js)
* [messages.js](/modules/pdp11/lib/messages.js)
* [panel.js](/modules/pdp11/lib/panel.js)
* [bus.js](/modules/pdp11/lib/bus.js)
* [device.js](/modules/pdp11/lib/device.js)
* [memory.js](/modules/pdp11/lib/memory.js)
* [computer.js](/modules/pdp11/lib/computer.js)
* [cpu.js](/modules/pdp11/lib/cpu.js)
* [cpustate.js](/modules/pdp11/lib/cpustate.js)
* [cpuops.js](/modules/pdp11/lib/cpuops.js)
* [rom.js](/modules/pdp11/lib/rom.js)
* [ram.js](/modules/pdp11/lib/ram.js)
* [cpustate.js](/modules/pdp11/lib/cpustate.js)
* [debugger.js](/modules/pdp11/lib/debugger.js)
* [defines.js](/modules/pdp11/lib/defines.js)
* [device.js](/modules/pdp11/lib/device.js)
* [disk.js](/modules/pdp11/lib/disk.js)
* [keyboard.js](/modules/pdp11/lib/keyboard.js)
* [serialport.js](/modules/pdp11/lib/serialport.js)
* [memory.js](/modules/pdp11/lib/memory.js)
* [messages.js](/modules/pdp11/lib/messages.js)
* [panel.js](/modules/pdp11/lib/panel.js)
* [pc11.js](/modules/pdp11/lib/pc11.js)
* [disk.js](/modules/pdp11/lib/disk.js)
* [ram.js](/modules/pdp11/lib/ram.js)
* [rk11.js](/modules/pdp11/lib/rk11.js)
* [rl11.js](/modules/pdp11/lib/rl11.js)
* [debugger.js](/modules/pdp11/lib/debugger.js)
* [computer.js](/modules/pdp11/lib/computer.js)
* [rom.js](/modules/pdp11/lib/rom.js)
* [serialport.js](/modules/pdp11/lib/serialport.js)

Since this module was written in 2016, it seemed appropriate to start adopting some of the more useful features of
[ECMAScript](http://www.ecma-international.org/ecma-262/6.0/index.html) 2015 (aka ES6), including:

* Classes
* *const* and *let*
* Computed Properties
* Default Parameters
* Octal and Binary Constants
* Template Literals
- String Interpolation (i.e., ${*expr*})
* New Built-in Methods
- String.repeat()
* *import* and *export*

However, I've still configured the Closure Compiler to "transpile" to ECMAScript 5 (aka ES5), because some people
may still be using older browsers that don't support ES6 -- or at least the subset of ES6 features I'm currently
using.

Eventually, I need to do some performance testing and determine whether the ES6 version performs any faster and/or
consumes fewer resources than the ES5 version. If it does, then I should either bite the bullet and generate ES6 code,
or generate both versions and use a loader that detects the browser's capabilities and loads the appropriate version.

Caveats
-------

### Shared modules

All PCjs machines rely on shared modules that are normally stored in [/shared/lib](/shared/lib/). However, until
ALL the machines have been converted to use ES6 classes, shared code must now exist in two flavors:
[/shared/lib](/shared/lib/) and [/shared/es6](/shared/es6/).

Once all the other machines have been converted to use ES6 classes, the shared ES6 code will be folded back into
[/shared/lib](/shared/lib/), and the temporary ES6 folder will go away. Obviously, there is incentive for me to do
this sooner rather than later, since in the interim, I must make any changes to shared code in both places.

There's also a less obvious problem: if you load a web page that attempts to load two or more PCjs machines, one of
which uses [/shared/lib](/shared/lib/) and another of which uses [/shared/es6](/shared/es6/), at least one of them will
fail to start, because the two sets of shared code cannot coexist. Well, they *could* have coexisted if I had been
willing to change the names of all the shared global objects (like **Component**), but I wasn't.

### *import* and *export*

With regard to *import* and *export* statements, the main reason I use them is to inform my development environment
(WebStorm) about each file's dependencies, thereby preventing inspection warnings. And ultimately, I plan to make PDPjs
run as a Node application, so explicitly declaring all imports and exports will be required, but for now, it's just
a web application, so strictly speaking, they're not required.

When loading uncompiled PDPjs files into a web browser, the Node-based web server bundled with PCjs still relies on
the `<script>` tag to load all JavaScript files, and as far as I know, no browser currently knows what to do with the
*import* and *export* keywords under those conditions. Chrome, for example, will immediately throw an exception when
it encounters a file containing them.

As a work-around, the bundled web server intercepts all requests for .js files and inserts line comments in front of
every *import* and *export* statement, so that your web browser won't barf on them. The statements are completely
superfluous anyway, since the web server generates `<script>` tags for all the necessary scripts, in the order they are
listed in [package.json](../../package.json).

This work-around assumes that all *export* statements appear AFTER the object they're exporting; e.g.:

export default ComputerPDP11;

and NOT as part of the object declaration; e.g.:

export default class ComputerPDP11 extends Component { ... }

12 changes: 7 additions & 5 deletions modules/pdp11/lib/bus.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ class BusPDP11 extends Component {
var block = this.aBusBlocks[iBlock];
info.cbTotal += block.size;
if (block.size) {
info.aBlocks.push(Usr.initBitFields(BlockInfoPDP11, iBlock, 0, 0, block.type));
info.aBlocks.push(/** @type {BlockInfoPDP11} */ (Usr.initBitFields(BlockInfoPDP11, iBlock, 0, 0, block.type)));
info.cBlocks++
}
iBlock++;
Expand Down Expand Up @@ -982,7 +982,7 @@ class BusPDP11 extends Component {
var fnWriteWord = afn[3]? afn[3].bind(component) : null;

/*
* As discussed in the IOController comments above, when handlers are being registered for these
* As discussed in the IOController comments below, when handlers are being registered for these
* BYTE-granular UNIBUS addresses, we must install custom fallback handlers for all BYTE accesses.
*/
if (addr >= PDP11.UNIBUS.R0SET0 && addr <= PDP11.UNIBUS.R6USER) {
Expand Down Expand Up @@ -1131,12 +1131,14 @@ class BusPDP11 extends Component {
}
}

BusPDP11.IOPAGE_16BIT = 0xE000; /*000160000*/ // eg, PDP-11/20
BusPDP11.IOPAGE_18BIT = 0x3E000; /*000760000*/ // eg, PDP-11/45
BusPDP11.IOPAGE_16BIT = 0x00E000; /*000160000*/ // eg, PDP-11/20
BusPDP11.IOPAGE_18BIT = 0x03E000; /*000760000*/ // eg, PDP-11/45
BusPDP11.IOPAGE_22BIT = 0x3FE000; /*017760000*/ // eg, PDP-11/70
BusPDP11.IOPAGE_LENGTH = 0x2000; // ie, 8Kb
BusPDP11.IOPAGE_LENGTH = 0x002000; // ie, 8Kb
BusPDP11.IOPAGE_MASK = BusPDP11.IOPAGE_LENGTH - 1;

BusPDP11.MASK_18BIT = 0x03FFFF; /*000777777*/

BusPDP11.UNIBUS_22BIT = 0x3C0000; /*017000000*/
BusPDP11.MASK_22BIT = 0x3FFFFF; /*017777777*/

Expand Down
90 changes: 60 additions & 30 deletions modules/pdp11/lib/cpustate.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ import MemoryPDP11 from "./memory";
* queue would constantly grow and shrink as requests were issued and dispatched, and as long as there was something
* in the queue, the CPU was constantly examining it.
*
* Now we are trying something more efficient. First, for devices that require delays (like a serial port's receiver
* and transmitter buffer registers that are supposed to "clock" the data in and out at a specific baud rate), the
* Now we are trying something more efficient. First, for devices that require delays (like the SerialPort's receiver
* and transmitter buffer registers, which are supposed to "clock" the data in and out at a specific baud rate), the
* CPU offers timer services that will "fire" a callback after a specified delay, which are much more efficient than
* requiring the CPU to dive into an interrupt queue and decrement delay counts on every instruction.
*
Expand Down Expand Up @@ -337,11 +337,29 @@ class CPUStatePDP11 extends CPUPDP11 {
this.mmuLastPage = 0;
this.mmuMask = 0x3ffff;

this.addrLast = 0; // this is queried by the Panel when it's not using its own ADDRESS register
this.opLast = 0; // stores the PC and any auto-incs or auto-decs from the last opcode; used to update MMR1 and MMR2
/*
* This is queried and displayed by the Panel when it's not displaying its own ADDRESS register
* (which takes precedence when, for example, you've manually halted the CPU and are independently
* examining the contents of other addresses).
*
* We initialize it to whatever the current PC is, because according to @paulnank's pdp11.js: "Reset
* displays next instruction address" and initMMU() is called on a RESET.
*/
this.addrLast = this.regsGen[7];

/*
* This stores the PC in the lower 16 bits, and any auto-incs or auto-decs from the last opcode in the
* upper 16 bits; the lower 16 bits are used to update MMR2, and the upper 16 bits are used to update MMR1.
* The upper bits are automatically zeroed at the start of every operation when PC is copied to opLast.
*/
this.opLast = 0;

this.resetIRQs();

/*
* As initCPU() explains, we shouldn't be calling this function until well after initBus() has been
* called, but we still make absolutely sure we have Bus access.
*/
if (this.bus) {
this.setMemoryAccess();
this.addrInvalid = this.bus.getMemoryLimit(MemoryPDP11.TYPE.RAM);
Expand Down Expand Up @@ -479,8 +497,8 @@ class CPUStatePDP11 extends CPUPDP11 {
getMMR1()
{
/*
* If updates to MMR1 have not been shut off (ie, MMR0.ABORT bits are clear),
* then we are allowed to sync MMR1 with its real-time counterpart in opLast.
* If updates to MMR1 have not been shut off (ie, MMR0.ABORT bits are clear), then we are allowed
* to sync MMR1 with its real-time counterpart in opLast.
*/
if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {
this.regMMR1 = (this.opLast >> 16) & 0xffff;
Expand All @@ -501,8 +519,8 @@ class CPUStatePDP11 extends CPUPDP11 {
getMMR2()
{
/*
* If updates to MMR2 have not been shut off (ie, MMR0.ABORT bits are clear),
* then we are allowed to sync MMR2 with its real-time counterpart in opLast.
* If updates to MMR2 have not been shut off (ie, MMR0.ABORT bits are clear), then we are allowed
* to sync MMR2 with its real-time counterpart in opLast.
*/
if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {
this.regMMR2 = this.opLast & 0xffff;
Expand Down Expand Up @@ -530,14 +548,14 @@ class CPUStatePDP11 extends CPUPDP11 {
setMMR3(newMMR3)
{
/*
* Don't allow the 11/45 to use 22-bit addressing or the UNIBUS map
* Don't allow the 11/45 to use 22-bit addressing or the UNIBUS map.
*/
if (this.model < PDP11.MODEL_1170) {
newMMR3 &= ~(PDP11.MMR3.MMU_22BIT | PDP11.MMR3.UNIBUS_MAP);
}
if (this.regMMR3 != newMMR3) {
this.regMMR3 = newMMR3;
this.mmuMask = (newMMR3 & PDP11.MMR3.MMU_22BIT)? 0x3fffff : 0x3ffff;
this.mmuMask = (newMMR3 & PDP11.MMR3.MMU_22BIT)? BusPDP11.MASK_22BIT : BusPDP11.MASK_18BIT;
this.setMemoryAccess();
}
}
Expand Down Expand Up @@ -817,6 +835,26 @@ class CPUStatePDP11 extends CPUPDP11 {
return pc;
}

/**
* branch(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
* @param {boolean|number} condition
*/
branch(opCode, condition)
{
if (condition) {
var off = ((opCode << 24) >> 23);
if (DEBUG && DEBUGGER && this.dbg && off == -2) {
this.dbg.stopInstruction("branch to self");
}
this.setPC(this.getPC() + off);
this.nStepCycles -= 2;
}
this.nStepCycles -= (2 + 1);
}

/**
* getPC()
*
Expand Down Expand Up @@ -2151,6 +2189,9 @@ class CPUStatePDP11 extends CPUPDP11 {
/**
* getByteChecked(addr)
*
* This is the getByte() handler whenever the Debugger has one or more virtual memory READ breakpoints set;
* otherwise, getByte() is bound to Bus.getByte().
*
* @this {CPUStatePDP11}
* @param {number} addr
* @return {number}
Expand All @@ -2166,6 +2207,9 @@ class CPUStatePDP11 extends CPUPDP11 {
/**
* getWordChecked(addr)
*
* This is the getWord() handler whenever the Debugger has one or more virtual memory READ breakpoints set;
* otherwise, getWord() is bound to Bus.getWord().
*
* @this {CPUStatePDP11}
* @param {number} addr
* @return {number}
Expand All @@ -2181,6 +2225,9 @@ class CPUStatePDP11 extends CPUPDP11 {
/**
* setByteChecked(addr, data)
*
* This is the setByte() handler whenever the Debugger has one or more virtual memory WRITE breakpoints set;
* otherwise, setByte() is bound to Bus.setByte().
*
* @this {CPUStatePDP11}
* @param {number} addr
* @param {number} data
Expand All @@ -2196,6 +2243,9 @@ class CPUStatePDP11 extends CPUPDP11 {
/**
* setWordChecked(addr, data)
*
* This is the setWord() handler whenever the Debugger has one or more virtual memory WRITE breakpoints set;
* otherwise, setWord() is bound to Bus.setWord().
*
* @this {CPUStatePDP11}
* @param {number} addr
* @param {number} data
Expand Down Expand Up @@ -2767,26 +2817,6 @@ class CPUStatePDP11 extends CPUPDP11 {
}
}

/**
* branch(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
* @param {boolean|number} condition
*/
branch(opCode, condition)
{
if (condition) {
var off = ((opCode << 24) >> 23);
if (DEBUG && DEBUGGER && this.dbg && off == -2) {
this.dbg.stopInstruction("branch to self");
}
this.setPC(this.getPC() + off);
this.nStepCycles -= 2;
}
this.nStepCycles -= (2 + 1);
}

/**
* stepCPU(nMinCycles)
*
Expand Down
Loading

0 comments on commit da4c902

Please sign in to comment.