Eliminate PDP-10 dependencies on the Int36 class (which is now used only for prototyping and command-line testing)

This commit is contained in:
Jeff 2017-03-07 17:21:59 -08:00 committed by Jeff Parsons
commit 48792873de
5 changed files with 54 additions and 25 deletions

View file

@ -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;
};

View file

@ -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);
}
/**

View file

@ -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);
}
/**