From 3e30bde786026b447d4a0566eabb12efb74f3fd1 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Sat, 25 Feb 2017 21:19:41 -0800 Subject: [PATCH] Some PDP-10 disassembler clean-up --- modules/pdp10/lib/cpuops.js | 2 +- modules/pdp10/lib/debugger.js | 121 +++++++++++++++------------------- modules/pdp10/lib/defines.js | 43 ++++++++++-- 3 files changed, 91 insertions(+), 75 deletions(-) diff --git a/modules/pdp10/lib/cpuops.js b/modules/pdp10/lib/cpuops.js index cd815f4ff..14147d7e8 100644 --- a/modules/pdp10/lib/cpuops.js +++ b/modules/pdp10/lib/cpuops.js @@ -3790,7 +3790,7 @@ PDP10.opUndefined = function(opCode) */ PDP10.opKA10 = function(opCode) { - var op = (opCode / PDP10.OPCODE.SHIFT)|0; + var op = (opCode / PDP10.OPCODE.O_SHIFT)|0; PDP10.aOpXXX_KA10[op].call(this, opCode); }; diff --git a/modules/pdp10/lib/debugger.js b/modules/pdp10/lib/debugger.js index 6f472e9f9..c074484d1 100644 --- a/modules/pdp10/lib/debugger.js +++ b/modules/pdp10/lib/debugger.js @@ -3456,50 +3456,62 @@ class DebuggerPDP10 extends Debugger { /** * doTest() * + * This function exercises the disassembler by performing look-ups for all possible operation codes + * and displaying the results. It's not intended to be included in the compiled version of the Debugger + * (DEBUG only). + * * @this {DebuggerPDP10} */ doTest() { - var ops = {}, aOpXXX = []; - var op, opXXX, opCode, sOperation; - for (op = 0o00000; op <= 0o77774; op += 4) { - opCode = op * Math.pow(2, 21); - sOperation = this.findInstruction(opCode, false); - if (!sOperation) continue; - if (ops[sOperation] === undefined) { - ops[sOperation] = op; - } else { - ops[sOperation] &= op; + if (DEBUG) { + var ops = {}, aOpXXX = []; + var op, opXXX, opCode, sOperation; + for (op = 0o00000; op <= 0o77774; op += 4) { + opCode = op * Math.pow(2, 21); + sOperation = this.findInstruction(opCode, false); + if (!sOperation) continue; + if (ops[sOperation] === undefined) { + ops[sOperation] = op; + } else { + ops[sOperation] &= op; + } + opXXX = op >> 6; + if (!aOpXXX[opXXX]) { + aOpXXX[opXXX] = sOperation; + } else if (aOpXXX[opXXX] != sOperation) { + aOpXXX[opXXX] = "XXX"; + } } - opXXX = op >> 6; - if (!aOpXXX[opXXX]) { - aOpXXX[opXXX] = sOperation; - } else if (aOpXXX[opXXX] != sOperation) { - aOpXXX[opXXX] = "XXX"; + for (sOperation in ops) { + op = ops[sOperation]; + this.println(Str.pad(sOperation + ":", 8) + this.toStrWord(op * Math.pow(2, 21))); + // + // The following code leveraged the disassembler to generate opcode handlers for all known opcodes. + // + // this.println("/**"); + // this.println(" * op" + sOperation + "(" + this.toStrWord(op * Math.pow(2, 21)) + ")"); + // this.println(" *"); + // this.println(" * @this {CPUStatePDP10}"); + // this.println(" * @param {number} opCode"); + // this.println(" */"); + // this.println("PDP10.op" + sOperation + " = function(opCode)"); + // this.println("{"); + // this.println("};\n"); } + // + // The following code leveraged the disassembler to generate an opcode dispatch table for all known opcodes. + // + // this.println("PDP10.aOpXXX = ["); + // for (opXXX = 0o000; opXXX <= 0o777; opXXX++) { + // sOperation = aOpXXX[opXXX]; + // sOperation = sOperation? (" PDP10.op" + sOperation + ",") : " PDP10.opUndefined,"; + // sOperation = Str.pad(sOperation, 32); + // sOperation += "// " + Str.toOct(opXXX, 3, true) + "xxx yyyyyy"; + // this.println(sOperation); + // } + // this.println("];"); } - for (sOperation in ops) { - op = ops[sOperation]; - this.println(sOperation + ": " + this.toStrWord(op * Math.pow(2, 21))); - // this.println("/**"); - // this.println(" * op" + sOperation + "(" + this.toStrWord(op * Math.pow(2, 21)) + ")"); - // this.println(" *"); - // this.println(" * @this {CPUStatePDP10}"); - // this.println(" * @param {number} opCode"); - // this.println(" */"); - // this.println("PDP10.op" + sOperation + " = function(opCode)"); - // this.println("{"); - // this.println("};\n"); - } - // this.println("PDP10.aOpXXX = ["); - // for (opXXX = 0o000; opXXX <= 0o777; opXXX++) { - // sOperation = aOpXXX[opXXX]; - // sOperation = sOperation? (" PDP10.op" + sOperation + ",") : " PDP10.opUndefined,"; - // sOperation = Str.pad(sOperation, 32); - // sOperation += "// " + Str.toOct(opXXX, 3, true) + "xxx yyyyyy"; - // this.println(sOperation); - // } - // this.println("];"); } /** @@ -3634,37 +3646,10 @@ if (DEBUGGER) { ]; /* - * PDP-10 opcodes are 36-bit values, many of which use the following layout: - * - * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - * - * or using modern bit-numbering: - * - * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - * - * where OOOOOOOMM represents the operation, and MM (if used) represents the mode: - * - * Mode Suffix Source Destination - * ---- ------ ----- ----------- - * 0: BASIC None E AC - * 1: IMMEDIATE I 0,E AC - * 2: MEMORY M AC E - * 3: SELF S E E (and AC if A is non-zero) - * - * Input-output instructions look like: - * - * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * 1 1 1 D D D D D D D O O O I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - * - * Bits 0-22 (I,X,Y) contain what we call a "reference address" (R), which is used to - * calculate the "effective address" (E). To determine E from R, we must extract I, X, - * and Y from R, set E to Y, then add [X] to E if X is non-zero. If I is zero, then - * we're done; otherwise, we must set set R to [E] and repeat the process. + * OPTABLE is a collection of masks, and each mask refers to a collection of opcode + * patterns associated with that mask; the disassembler applies each mask to the opcode, + * and when a masked opcode matches one of the associated patterns, the corresponding + * instruction is considered a match. */ DebuggerPDP10.OPTABLE = { [PDP10.OPCODE.OPUUO]: { // 0o70000 diff --git a/modules/pdp10/lib/defines.js b/modules/pdp10/lib/defines.js index b4d1121cb..58f52b949 100644 --- a/modules/pdp10/lib/defines.js +++ b/modules/pdp10/lib/defines.js @@ -101,7 +101,37 @@ var PDP10 = { DATA_LIMIT: Math.pow(2, 36), /* - * Opcode definitions + * PDP-10 opcodes are 36-bit values, most of which use the following layout: + * + * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y + * + * or using modern bit-numbering: + * + * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y + * + * where OOOOOOOMM represents the operation, and MM (if used) represents the mode: + * + * Mode Suffix Source Destination + * ---- ------ ----- ----------- + * 0: BASIC None E AC + * 1: IMMEDIATE I 0,E AC + * 2: MEMORY M AC E + * 3: SELF S E E (and AC if A is non-zero) + * + * Input-output instructions look like: + * + * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * 1 1 1 D D D D D D D O O O I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y + * + * Bits 0-22 (I,X,Y) contain what we call a "reference address" (R), which is used to + * calculate the "effective address" (E). To determine E from R, we must extract I, X, + * and Y from R, set E to Y, then add [X] to E if X is non-zero. If I is zero, then + * we're done; otherwise, we must set set R to [E] and repeat the process. */ OPCODE: { OPMASK: 0o77700, // operation mask @@ -115,11 +145,12 @@ var PDP10 = { FNMASK: 0o17, // accumulator/function mask (after shift) IOSHIFT: Math.pow(2, 26), // input-output device code shift IOMASK: 0o177, // input-output device code mask (after shift) - SHIFT: Math.pow(2, 27), // operation code shift - Y_MASK: 0o777777, - X_SHIFT: 18, - X_MASK: 0o17, - I_BIT: 0o20000000, + O_SHIFT: Math.pow(2, 27), // operation shift + O_MASK: 0o777, // operation mask (after shift) + I_BIT: 0o20000000, // indirect bit + X_SHIFT: 18, // X shift + X_MASK: 0o17, // X mask (after shift) + Y_MASK: 0o777777, // Y mask HALT: 0o5304 // operation code for HALT },