From 48792873de5768f17bbb6a4aa42e9ca9f540fff3 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 7 Mar 2017 17:21:59 -0800 Subject: [PATCH] Eliminate PDP-10 dependencies on the Int36 class (which is now used only for prototyping and command-line testing) --- devices/README.md | 1 + modules/pdp10/lib/cpuops.js | 42 ++++++++++++++++++++++++----------- modules/pdp10/lib/cpustate.js | 11 ++++++--- modules/pdp10/lib/memory.js | 24 +++++++++++++------- package.json | 1 - 5 files changed, 54 insertions(+), 25 deletions(-) diff --git a/devices/README.md b/devices/README.md index ce2892d16..de40c0c7b 100644 --- a/devices/README.md +++ b/devices/README.md @@ -16,6 +16,7 @@ All PCjs machines are built from the following sets of devices: * [6502 Devices](c1p/) (e.g., [Challenger 1P](c1p/machine/)) * [8080 Devices](pc8080/) (e.g., [Space Invaders](pc8080/machine/invaders/), [VT100 Terminal](pc8080/machine/vt100/)) * [8086 Devices](pcx86/) (e.g., [IBM PC and compatibles](pcx86/machine/)) +* [PDP-10 Devices](pdp10/) (e.g., [PDP-10 (Model KA10)](pdp10/machine/ka10/)) * [PDP-11 Devices](pdp11/) (e.g., [PDP-11/20](pdp11/machine/1120/), [PDP-11/45](pdp11/machine/1145/), [PDP-11/70](pdp11/machine/1170/)) These devices are user-installable components that you would typically find in a real personal computer, diff --git a/modules/pdp10/lib/cpuops.js b/modules/pdp10/lib/cpuops.js index 1499599c4..83e442a6b 100644 --- a/modules/pdp10/lib/cpuops.js +++ b/modules/pdp10/lib/cpuops.js @@ -338,11 +338,8 @@ PDP10.opILDB = function(op, acc) * opIBP() on phase 1. */ if (this.regBP < 0) { - //noinspection JSUnresolvedFunction PDP10.opIBP.call(this, op, acc); } - - //noinspection JSUnresolvedFunction PDP10.opLDB.call(this, op, acc); }; @@ -375,7 +372,6 @@ PDP10.opLDB = function(op, acc) if (this.regBP < 0) { this.regBP = w; this.regRA = this.regEA | PDP10.OPCODE.I_BIT; - this.advancePC(-1); return; } var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK; @@ -428,11 +424,8 @@ PDP10.opIDPB = function(op, acc) * opIBP() on phase 1. */ if (this.regBP < 0) { - //noinspection JSUnresolvedFunction PDP10.opIBP.call(this, op, acc); } - - //noinspection JSUnresolvedFunction PDP10.opDPB.call(this, op, acc); }; @@ -1668,7 +1661,15 @@ PDP10.opLSH = function(op, acc) }; /** - * opJFFO(0o243000) + * opJFFO(0o243000): Jump if Find First One + * + * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-56: + * + * If AC contains zero, clear AC A+1 and go on to the next instruction in sequence. + * + * If AC is not zero, count the number of leading 0s in it (0s to the left of the leftmost 1), + * and place the count in AC A+1. Take the next instruction from location E and continue sequential + * operation from there. In either case AC is unaffected, the original contents of AC A +1 are lost. * * @this {CPUStatePDP10} * @param {number} op @@ -1676,7 +1677,16 @@ PDP10.opLSH = function(op, acc) */ PDP10.opJFFO = function(op, acc) { - this.opUndefined(op); + var dst = 0; + var src = this.readWord(acc); + if (src) { + while (src < PDP10.INT_LIMIT) { + dst++; + src *= 2; + } + this.setPC(this.regEA); + } + this.writeWord((acc + 1) & 0o17, dst); }; /** @@ -2068,7 +2078,15 @@ PDP10.opJFCL = function(op, acc) }; /** - * opXCT(0o256000) + * opXCT(0o256000): Execute + * + * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-56: + * + * Execute the contents of location E as an instruction. Any instruction may be executed, including another XCT. + * If an XCT executes a skip instruction, the skip is relative to the location of the XCT (the first XCT if there + * are several in a chain). If an XCT executes a jump, program flow is altered as specified by the jump (no matter + * how many XCTs precede a jump instruction, when PC is saved it contains an address one greater than the location + * of the first XCT in the chain). * * @this {CPUStatePDP10} * @param {number} op @@ -2076,7 +2094,7 @@ PDP10.opJFCL = function(op, acc) */ PDP10.opXCT = function(op, acc) { - this.opUndefined(op); + this.regXC = this.regEA; }; /** @@ -5401,7 +5419,6 @@ PDP10.doADD = function(dst, src) * only possible out-of-bounds value is a result >= WORD_LIMIT, which the mod cures. */ var res = (dst + src) % PDP10.WORD_LIMIT; - //noinspection JSUnresolvedFunction PDP10.setAddFlags.call(this, dst, src, res); return res; }; @@ -5632,7 +5649,6 @@ PDP10.doSUB = function(dst, src) * We can leverage setAddFlags() by treating the subtraction as addition; * since res = dst - src, it is also true that dst = res + src. */ - //noinspection JSUnresolvedFunction PDP10.setAddFlags.call(this, res, src, dst); return res; }; diff --git a/modules/pdp10/lib/cpustate.js b/modules/pdp10/lib/cpustate.js index ac9398248..1276eeafa 100644 --- a/modules/pdp10/lib/cpustate.js +++ b/modules/pdp10/lib/cpustate.js @@ -176,6 +176,7 @@ class CPUStatePDP10 extends CPUPDP10 { { this.regEA = this.regRA = this.regOP = 0; this.regPC = this.lastPC = this.addrReset; + this.regXC = -1; // if >= 0 this supersedes regPC (refers to an opcode from XCT) this.regBP = -1; // active byte pointer (-1 if none) this.regPS = 0; // assorted processor flags (see PSFLAG bit definitions) this.regExt = 0; // internal "extension" register used for 72-bit calculations (eg, MUL) @@ -283,6 +284,7 @@ class CPUStatePDP10 extends CPUPDP10 { this.regRA, this.regOP, this.regPC, + this.regXC, this.regBP, this.regPS, this.opFlags, @@ -315,6 +317,7 @@ class CPUStatePDP10 extends CPUPDP10 { this.regRA, this.regOP, this.regPC, + this.regXC, this.regBP, this.regPS, this.opFlags, @@ -394,8 +397,12 @@ class CPUStatePDP10 extends CPUPDP10 { { if ((this.regRA & PDP10.OPCODE.I_BIT)) { this.regRA = this.readWord(this.regEA); + } else if (this.regXC >= 0) { + this.regRA = this.regOP = this.readWord(this.regXC); + this.regXC = -1; } else { this.regRA = this.regOP = this.readWord(this.lastPC = this.regPC); + this.regPC = (this.regPC + 1) % PDP10.ADDR_LIMIT; } /* @@ -418,10 +425,8 @@ class CPUStatePDP10 extends CPUPDP10 { this.regEA = this.regRA & PDP10.OPCODE.Y_MASK; var x = (this.regRA >> PDP10.OPCODE.X_SHIFT) & PDP10.OPCODE.X_MASK; if (x) this.regEA = (this.regEA + this.readWord(x)) & PDP10.ADDR_MASK; - if (this.regRA & PDP10.OPCODE.I_BIT) return -1; - this.regPC = (this.regPC + 1) % PDP10.ADDR_LIMIT; - return (this.regOP / PDP10.OPCODE.A_SCALE)|0; + return (this.regRA & PDP10.OPCODE.I_BIT)? -1 : ((this.regOP / PDP10.OPCODE.A_SCALE)|0); } /** diff --git a/modules/pdp10/lib/memory.js b/modules/pdp10/lib/memory.js index 1b274c2a9..583bedc10 100644 --- a/modules/pdp10/lib/memory.js +++ b/modules/pdp10/lib/memory.js @@ -30,7 +30,6 @@ if (NODE) { var Component = require("../../shared/lib/component"); - var Int36 = require("../../shared/lib/int36"); var PDP10 = require("./defines"); var MessagesPDP10 = require("./messages"); } @@ -202,19 +201,28 @@ class MemoryPDP10 { * @this {MemoryPDP10} * @param {number} [off] (optional starting word offset within block) * @param {number} [len] (optional maximum number of words; default is the entire block) - * @param {number} [pattern] + * @param {number} [pattern] (default is zero) */ - zero(off, len, pattern) + zero(off, len, pattern = 0) { - var i; - off = off || 0; - pattern = Int36.validate(pattern || 0); /* - * NOTE: If len happens to be larger than the block, that's OK, because we also bounds-check the index. + * NOTE: If len is larger than the block, that's OK, because we also bounds-check the index. */ + off = off || 0; if (len === undefined) len = this.size; Component.assert(off >= 0 && off < this.size); - for (i = off; len-- && i < this.size; i++) this.writeWordDirect(pattern, off, this.addr + off); + + /* + * Although it's expected that most callers will supply unsigned 36-bit values, we're nice about + * converting any signed values to their unsigned (two's complement) counterpart, provided they are + * within the acceptable range. Any values outside that range will be dealt with afterward. + */ + if (pattern < 0 && pattern >= -PDP10.MIN_NEG36) { + pattern += PDP10.WORD_LIMIT; + } + pattern = Math.trunc(Math.abs(pattern)) % PDP10.WORD_LIMIT; + + for (var i = off; len-- && i < this.size; i++) this.writeWordDirect(pattern, off, this.addr + off); } /** diff --git a/package.json b/package.json index 89525f536..839213cd6 100644 --- a/package.json +++ b/package.json @@ -179,7 +179,6 @@ "./modules/shared/lib/dumpapi.js", "./modules/shared/lib/reportapi.js", "./modules/shared/lib/userapi.js", - "./modules/shared/lib/int36.js", "./modules/shared/lib/keys.js", "./modules/shared/lib/strlib.js", "./modules/shared/lib/usrlib.js",