/** * @fileoverview Implements PDP-10 opcode handlers. * @author Jeff Parsons * @copyright © Jeff Parsons 2012-2017 * * This file is part of PCjs, a computer emulation software project at . * * PCjs is free software: you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with PCjs. If not, * see . * * You are required to include the above copyright notice in every modified copy of this work * and to display that copyright notice when the software starts running; see COPYRIGHT in * . * * Some PCjs files also attempt to load external resource files, such as character-image files, * ROM files, and disk image files. Those external resource files are not considered part of PCjs * for purposes of the GNU General Public License, and the author does not claim any copyright * as to their contents. */ "use strict"; if (NODE) { var Str = require("../../shared/lib/strlib"); var Component = require("../../shared/lib/component"); var PDP10 = require("./defines"); } /* From the "PDP-10 System Reference Manual", May 1968, p. 1-4: 1.1 NUMBER SYSTEM The program can interpret a data word as a 36-digit, unsigned binary number, or the left and right halves of a word can be taken as separate 18-bit numbers. The PDP-10 repertoire includes instructions that effectively add or subtract one from both halves of a word, so the right half can be used for address modification when the word is addressed as an index register, while the left half is used to keep a control count. The standard arithmetic instructions in the PDP-10 use twos complement, fixed point conventions to do binary arithmetic. In a word used as a number, bit 0 (the leftmost bit) represents the sign, 0 for positive, 1 for negative. In a positive number the remaining 35 bits are the magnitude in ordinary binary notation. The negative of a number is obtained by taking its twos complement. If x is an n-digit binary number, its twos complement is 2^n - x, and its ones complement is (2^n - 1) - x, or equivalently (2^n - x) - 1. Subtracting a number from 2^n - 1 (ie, from all 1s) is equivalent to performing the logical complement, ie changing all 0s to 1s and all 1s to 0s. Therefore, to form the twos complement one takes the logical complement (usually referred to merely as the complement) of the entire word including the sign, and adds 1 to the result. In a negative number the sign bit is 1, and the remaining bits are the twos complement of the magnitude. Zero is represented by a word containing all 0s. Complementing this number produces all 1s, and adding 1 to that produces all 0s again. Hence there is only one zero representation and its sign is positive. Since the numbers are symmetrical in magnitude about a single zero representation, all even numbers both positive and negative end in 0, all odd numbers in 1 (a number all 1s represents -1). But since there are the same number of positive and negative numbers and zero is positive, there is one more negative number than there are nonzero positive numbers. This is the most negative number and it cannot be produced by negating any positive number (its octal representation is 400000 000000 and its magnitude is one greater than the largest positive number). If ones complements were used for negatives one could read a negative number by attaching significance to the as instead of the 1s. In twos complement notation each negative number is one greater than the complement of the positive number of the same magnitude, so one can read a negative number by attaching significance to the rightmost 1 and attaching significance to the 0s at the left of it (the negative number of largest magnitude has a 1 in only the sign position). In a negative integer, 1s may be discarded at the left, just as leading 0s may be dropped in a positive integer. In a negative fraction, 0s may be discarded at the right. So long as only 0s are discarded, the number remains in twos complement form because it still has a 1 that possesses significance; but if a portion including the rightmost 1 is discarded, the remaining part of the fraction is now a ones complement. The computer does not keep track of a binary point - the programmer must adopt a point convention and shift the magnitude of the result to conform to the convention used. Two common conventions are to regard a number as an integer (binary point at the right) or as a proper fraction (binary point at the left); in these two cases the range of numbers represented by a single word is -2^35 to 2^35 - 1, or -1 to 1 - 2^35. Since multiplication and division make use of double length numbers, there are special instructions for performing these operations with integral operands. SIDEBAR: Multiplication produces a double length product, and the programmer must remember that discarding the low order part of a double length negative leaves the high order part in correct twos complement form only if the low order part is null. ... 2.5 FIXED POINT ARITHMETIC For fixed point arithmetic the PDP-10 has instructions for arithmetic shifting (which is essentially multiplication by a power of 2) as well as for performing addition, subtraction, multiplication and division of numbers in fixed point format [§ 1.1]. In such numbers the position of the binary point is arbitrary (the programmer may adopt any point convention). The add and subtract instructions involve only single length numbers, whereas multiply supplies a double length product, and divide uses a double length dividend. The high and low order words respectively of a double length fixed point number are in accumulators A and A+1 (mod 20), where the magnitude is the 70-bit string in bits 1-35 of the two words and the signs of the two are identical. There are also integer multiply and divide instructions that involve only single length numbers and are especially suited for handling smaller integers, particularly those of eighteen bits or less such as addresses (of course they can be used for small fractions as well provided the programmer keeps track of the binary point). For convenience in the following, all operands are assumed to be integers (binary point at the right). The processor has four flags, Overflow, Carry 0, Carry 1 and No Divide, that indicate when the magnitude of a number is or would be larger than can be accommodated. Carry 0 and Carry 1 actually detect carries out of bits 0 and 1 in certain instructions that employ fixed point arithmetic operations: the add and subtract instructions treated here, the move instructions that produce the negative or magnitude of the word moved [§ 2.2], and the arithmetic test instructions that increment or decrement the test word [§ 2.7]. In these instructions an incorrect result is indicated - and the Overflow flag set - if the carries are different, ie if there is a carry into the sign but not out of it, or vice versa. The Overflow flag is also set by No Divide being set, which means the processor has failed to perform a division because the magnitude of the dividend is greater than or equal to that of the divisor, or in integer divide, simply that the divisor is zero. In other overflow cases only Overflow itself is set: these include too large a product in multiplication, and loss of significant bits in left arithmetic shifting. SIDEBAR: Overflow is determined directly from the carries, not from the carry flags, as their states may reflect events in previous instructions. */ /** * opKA10(op) * * Originally, we received the full opcode (36 bits), then only the upper half-word (18 bits), * and now we receive only the upper 13 bits. However, the octal values shown in the table and * function comments below still include all 18 bits of the original upper half-word, so that * you don't have to mentally un-shift them 5 bits. * * @this {CPUStatePDP10} * @param {number} op (the top 13 bits of the original opcode, shifted right to bit 0) */ PDP10.opKA10 = function(op) { /* * We shift op right 4 more bits, leaving only the 9 bits required for the table index. Those * 4 bits are normally an accumulator index, which we also mask and pass along, since most instructions * will use an accumulator, and those that don't simply ignore it. */ PDP10.aOpXXX_KA10[op >> 4].call(this, op, op & PDP10.OPCODE.A_MASK); }; /** * opUUO(0o0NN000): Unimplemented User Operation * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-64: * * Store the instruction code, A and the effective address E in bits 0-8, 9-12 and 18-35 respectively of * location 40; clear bits 13-17. Execute the instruction contained in location 41. The original contents * of location 40 are lost. * * All of these codes are equivalent when they occur in the Monitor or when time sharing is not in effect. * But when a UUO appears in a user program, a code in the range 001-037 uses relocated locations 40 and 41 * (ie 40 and 41 in the user's block) and is thus entirely a part of and under control of the user program. * * A code in the range 040-077 on the other hand uses unrelocated 40 and 41, and the instruction in the latter * location is under control of the Monitor; these codes are thus specifically for user communication with * the Monitor, which interprets them (refer to the Monitor manual for the meanings of the various codes). * * The code 000 executes in the same way as 040-077 but is not a standard communication code: it is included * so that control returns to the Monitor should a user program wipe itself out. * * For a second processor connected to the same memory, the UUO trap is locations 140-141 instead of 40-41. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opUUO = function(op, ac) { this.opUndefined(op); }; /** * opUFA(0o130000): Unnormalized Floating Add * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-37: * * Floating add the contents of location E to AC. If the double length fraction in the sum is zero, clear * accumulator A+1. Otherwise normalize the sum only if the magnitude of its fractional part is >= 1, and place * the high order part of the result in AC A+1. The original contents of AC and E are unaffected. * * NOTE: The result is placed in accumulator A+1. T his is the only arithmetic instruction that stores the result * in a second accumulator, leaving the original operands intact. * * If the exponent of the sum following the one-step normalization is > 127, set Overflow and Floating Overflow; * the result stored has an exponent 256 less than the correct one. * * SIDEBAR: The exponent of the sum is equal to that of the larger summand unless addition of the fractions * overflows, in which case it is greater by 1. Exponent overflow can occur only in the latter case. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opUFA = function(op, ac) { this.opUndefined(op); }; /** * opDFN(0o131000): Double Floating Negate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-37: * * Negate the double length floating point number composed of the contents of AC and location E with AC on the left. * Do this by taking the twos complement of the number whose sign is AC bit 0, whose exponent is in AC bits 1-8, and * whose fraction is the 54-bit string in bits 9-35 of AC and location E. Place the high order word of the result * in AC; place the low order part of the fraction in bits 9-35 of location E without altering the original contents * of bits 0-8 of that location. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opDFN = function(op, ac) { this.opUndefined(op); }; /** * opFSC(0o132000): Floating Scale * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-34: * * If the fractional part of AC is zero, clear AC. Otherwise add the scale factor given by E to the exponent part * of AC (thus multiplying AC by 2^E), normalize the resulting word bringing 0s into bit positions vacated at the * right, and place the result back in AC. * * NOTE: A negative E is represented in standard twos complement notation, but the hardware compensates for this * when scaling the exponent. * * If the exponent after normalization is > 127, set Overflow and Floating Overflow; the result stored has an * exponent 256 less than the correct one. If < -128, set Overflow, Floating Overflow and Floating Underflow; * the result stored has an exponent 256 greater than the correct one. * * SIDEBAR: This instruction can be used to float a fixed number with 27 or fewer significant bits. To float an * integer contained within AC bits 9-35, * * FSC AC,233 * * inserts the correct exponent to move the binary point from the right end to the left of bit 9 and then normalizes * (233 [base 8] = 155 [base 10] = 128 + 27). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSC = function(op, ac) { this.opUndefined(op); }; /** * opIBP(0o133000): Increment Byte Pointer * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16: * * Increment the byte pointer in location E as explained [below]. The pointer has the format: * * 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 * P P P P P P S S S S S S - I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y * * where S is the size of the byte as a number of bits, and P is its position as the number of bits * remaining at the right of the byte in the word (eg if P is 3 the rightmost bit of the byte is bit 32 * of the word). The rest of the pointer is interpreted in the same way as in an instruction: I, X and Y * are used to calculate the address of the location that is the source or destination of the byte. * * To facilitate processing a series of bytes, several of the byte instructions increment the * pointer, ie, modify it so that it points to the next byte position in a set of memory locations. * Bytes are processed from left to right in a word, so incrementing merely replaces the current value * of P by P - S, unless there is insufficient space in the present location for another byte of the * specified size (P - S < 0). In this case Y is increased by one to point to the next consecutive * location, and P is set to 36 - S to point to the first byte at the left in the new location. * * CAUTION: Do not allow Y to reach maximum value. The whole pointer is incremented, so if Y is 2^18 - 1 * it becomes zero and X is also incremented. The address calculation for the pointer uses the original X, * but if a priority interrupt should occur before the calculation is complete, the incremented X is used * when the instruction is repeated. * * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36, * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited * in position P. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIBP = function(op, ac) { var inc = 0; var w = this.readWord(this.regEA); var p = (w / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK; var s = (w >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK; p -= s; if (p < 0) { inc++; p = 36 - s; if (p < 0) p = 100 - s; // see SPECIAL CONSIDERATIONS and NOTE above } /* * Since the documentation above makes clear that the effect of the increment (of w) extends past the Y * bits and into (at least) the X bits, we first re-assemble a new pointer with updated P bits (along with * the original S bits and the remaining bits covered by PTR_MASK) and then increment as needed. * * Yes, PTR_MASK could have included the S bits as well and made the following expression a TINY bit simpler, * but I would like to keep PTR_MASK distinct from both the P and S fields. */ w = (p * PDP10.OPCODE.P_SCALE) + (s << PDP10.OPCODE.S_SHIFT) + (w & PDP10.OPCODE.PTR_MASK); if (inc) w = (w + inc) % PDP10.WORD_LIMIT; this.writeWord(this.regEA, w); }; /** * opILDB(0o134000): Increment Pointer and Load Byte * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16: * * Increment the byte pointer in location E as explained above. Then retrieve a byte of S bits from the * location and position specified by the newly incremented pointer, load it into the right end of AC, * and clear the remaining AC bits. The location containing the byte is unaffected, the original contents * of AC are lost. * * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36, * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited * in position P. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opILDB = function(op, ac) { /* * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2 * is with regEA containing the address of the bits to be loaded. * * We can implement this as a simple combination of opIBP() and opLDB(), but taking care that we only call * opIBP() on phase 1 (and only if the BIS flag is not set). */ if (!(this.regPS & PDP10.PSFLAG.BIS)) { PDP10.opIBP.call(this, op, ac); this.regPS |= PDP10.PSFLAG.BIS; } PDP10.opLDB.call(this, op, ac); }; /** * opLDB(0o135000): Load Byte *z * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16: * * Retrieve a byte of S bits from the location and position specified by the pointer contained in location E, * load it into the right end of AC, and clear the remaining AC bits. The location containing the byte is * unaffected, the original contents of AC are lost. * * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36, * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited * in position P. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opLDB = function(op, ac) { /* * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2 * is with regEA containing the address of the bits to be loaded. */ var w = this.readWord(this.regEA); if (this.regBP < 0) { this.regBP = w; this.regRA = this.regEA | PDP10.OPCODE.I_FIELD; return; } var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK; var s = (this.regBP >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK; if (p + s < 32) { /* * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is * positive. */ w = ((w >> p) & ((1 << s) - 1)) >>> 0; } else { /* * Regarding the SPECIAL CONSIDERATIONS above, even if the P ("shift") and/or S ("mask") values are * over-large, that should be fine, because nothing but additional zero bits will be included (provided * our memory is working properly and didn't give us more than 36 bits of unsigned data). */ w = Math.trunc(w / Math.pow(2, p)) % Math.pow(2, s); } this.writeWord(ac, w); this.regPS &= ~PDP10.PSFLAG.BIS; this.regBP = -1; }; /** * opIDPB(0o136000): Increment Pointer and Deposit Byte * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16: * * Increment the byte pointer in location E as explained above. Then deposit the right S bits of AC into * the location and position specified by the newly incremented pointer. The original contents of the bits * that receive the byte are lost, AC and the remaining bits of the deposit location are unaffected. * * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36, * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited * in position P. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIDPB = function(op, ac) { /* * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2 * is with regEA containing the address of the bits to be stored. * * We can implement this as a simple combination of opIBP() and opDDB(), but taking care that we only call * opIBP() on phase 1 (and only if the BIS flag is not set). */ if (!(this.regPS & PDP10.PSFLAG.BIS)) { PDP10.opIBP.call(this, op, ac); this.regPS |= PDP10.PSFLAG.BIS; } PDP10.opDPB.call(this, op, ac); }; /** * opDPB(0o137000): Deposit Byte * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16: * * Deposit the right S bits of AC into the location and position specified by the pointer contained * in location E. The original contents of the bits that receive the byte are lost, AC and the remaining * bits of the deposit location are unaffected. * * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36, * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited * in position P. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opDPB = function(op, ac) { /* * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2 * is with regEA containing the address of the bits to be stored. */ var w = this.readWord(this.regEA); if (this.regBP < 0) { this.regBP = w; this.regRA = this.regEA | PDP10.OPCODE.I_FIELD; return; } var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK; var s = (this.regBP >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK; /* * Regarding the SPECIAL CONSIDERATIONS above, even if the P ("shift") and/or S ("mask") values are * over-large, we "mask" the resulting byte value (b) to 36 bits, so that when we re-assemble the final * result (w), there shouldn't be any overlap or overflow. */ var b = ((this.readWord(ac) % Math.pow(2, s)) * Math.pow(2, p)) % PDP10.WORD_LIMIT; w = (w - (w % Math.pow(2, p + s))) + b + (w % Math.pow(2, p)); this.writeWord(this.regEA, w); this.regPS &= ~PDP10.PSFLAG.BIS; this.regBP = -1; }; /** * opFAD(0o140000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFAD = function(op, ac) { this.opUndefined(op); }; /** * opFADI(0o141000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADI = function(op, ac) { this.opUndefined(op); }; /** * opFADM(0o142000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADM = function(op, ac) { this.opUndefined(op); }; /** * opFADB(0o143000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADB = function(op, ac) { this.opUndefined(op); }; /** * opFADR(0o144000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADR = function(op, ac) { this.opUndefined(op); }; /** * opFADRI(0o145000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADRI = function(op, ac) { this.opUndefined(op); }; /** * opFADRM(0o146000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADRM = function(op, ac) { this.opUndefined(op); }; /** * opFADRB(0o147000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFADRB = function(op, ac) { this.opUndefined(op); }; /** * opFSB(0o150000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSB = function(op, ac) { this.opUndefined(op); }; /** * opFSBI(0o151000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBI = function(op, ac) { this.opUndefined(op); }; /** * opFSBM(0o152000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBM = function(op, ac) { this.opUndefined(op); }; /** * opFSBB(0o153000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBB = function(op, ac) { this.opUndefined(op); }; /** * opFSBR(0o154000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBR = function(op, ac) { this.opUndefined(op); }; /** * opFSBRI(0o155000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBRI = function(op, ac) { this.opUndefined(op); }; /** * opFSBRM(0o156000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBRM = function(op, ac) { this.opUndefined(op); }; /** * opFSBRB(0o157000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFSBRB = function(op, ac) { this.opUndefined(op); }; /** * opFMP(0o160000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMP = function(op, ac) { this.opUndefined(op); }; /** * opFMPI(0o161000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPI = function(op, ac) { this.opUndefined(op); }; /** * opFMPM(0o162000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPM = function(op, ac) { this.opUndefined(op); }; /** * opFMPB(0o163000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPB = function(op, ac) { this.opUndefined(op); }; /** * opFMPR(0o164000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPR = function(op, ac) { this.opUndefined(op); }; /** * opFMPRI(0o165000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPRI = function(op, ac) { this.opUndefined(op); }; /** * opFMPRM(0o166000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPRM = function(op, ac) { this.opUndefined(op); }; /** * opFMPRB(0o167000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFMPRB = function(op, ac) { this.opUndefined(op); }; /** * opFDV(0o170000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDV = function(op, ac) { this.opUndefined(op); }; /** * opFDVI(0o171000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVI = function(op, ac) { this.opUndefined(op); }; /** * opFDVM(0o172000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVM = function(op, ac) { this.opUndefined(op); }; /** * opFDVB(0o173000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVB = function(op, ac) { this.opUndefined(op); }; /** * opFDVR(0o174000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVR = function(op, ac) { this.opUndefined(op); }; /** * opFDVRI(0o175000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVRI = function(op, ac) { this.opUndefined(op); }; /** * opFDVRM(0o176000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVRM = function(op, ac) { this.opUndefined(op); }; /** * opFDVRB(0o177000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opFDVRB = function(op, ac) { this.opUndefined(op); }; /** * opMOVE(0o200000): Move * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Move one word from the source to the destination specified by M. The source is unaffected, * the original contents of the destination are lost. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * Equivalents: opSETM(0o414000) and opSETMB(0o417000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVE = function(op, ac) { this.writeWord(ac, this.readWord(this.regEA)); }; /** * opMOVEI(0o201000): Move Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Move one word from the source to the destination specified by M. The source is unaffected, * the original contents of the destination are lost. * * SIDEBAR: MOVEI loads the word 0,E into AC and is thus equivalent to HRRZI. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * Equivalents: opSETMI(0o415000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVEI = function(op, ac) { this.writeWord(ac, this.regEA); }; /** * opMOVEM(0o202000): Move to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Move one word from the source to the destination specified by M. The source is unaffected, * the original contents of the destination are lost. * * NOTE: This is a "Memory" mode instruction: the source is [A] and the destination is [E] (opposite of "Basic"). * * Equivalents: opSETAM(0o426000) and opSETAB(0o427000). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVEM = function(op, ac) { this.writeWord(this.regEA, this.readWord(ac)); }; /** * opMOVES(0o203000): Move to Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Move one word from the source to the destination specified by M. The source is unaffected, * the original contents of the destination are lost. * * SIDEBAR: If A is zero, MOVES is a no-op; otherwise it is equivalent to MOVE. * * NOTE: This is a "Self" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVES = function(op, ac) { if (ac) this.writeWord(ac, this.readWord(this.regEA)); }; /** * opMOVS(0o204000): Move Swapped * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Interchange the left and right halves of the word from the source specified by M and move it to the * specified destination. The source is unaffected, the original contents of the destination are lost. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVS = function(op, ac) { var src = this.readWord(this.regEA); src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT); this.writeWord(ac, src); }; /** * opMOVSI(0o205000): Move Swapped Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Interchange the left and right halves of the word from the source specified by M and move it to the * specified destination. The source is unaffected, the original contents of the destination are lost. * * SIDEBAR: Swapping halves in immediate mode loads the word E,0 into AC. MOVSI is thus equivalent to HRLZI. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVSI = function(op, ac) { this.writeWord(ac, this.regEA * PDP10.HALF_SHIFT); }; /** * opMOVSM(0o206000): Move Swapped to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Interchange the left and right halves of the word from the source specified by M and move it to the * specified destination. The source is unaffected, the original contents of the destination are lost. * * NOTE: This is a "Memory" mode instruction: the source is [A] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVSM = function(op, ac) { var src = this.readWord(ac); src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT); this.writeWord(this.regEA, src); }; /** * opMOVSS(0o207000): Move Swapped to Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Interchange the left and right halves of the word from the source specified by M and move it to the * specified destination. The source is unaffected, the original contents of the destination are lost. * * NOTE: This is a "Self" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVSS = function(op, ac) { var src = this.readWord(this.regEA); src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT); this.writeWord(this.regEA, src); if (ac) this.writeWord(ac, src) }; /** * opMOVN(0o210000): Move Negative * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Negate the word from the source specified by M and move it to the specified destination. * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized * number). * * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original * contents of the destination are lost. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVN = function(op, ac) { this.writeWord(ac, PDP10.doNEG.call(this, this.readWord(this.regEA))); }; /** * opMOVNI(0o211000): Move Negative Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Negate the word from the source specified by M and move it to the specified destination. * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized * number). * * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original * contents of the destination are lost. * * SIDEBAR: MOVNI loads AC with the negative of the word 0,E and can set no flags. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVNI = function(op, ac) { /* * We used to perform an in-line two's complement of regEA, since doNEG() updates the flags, and the * documentation above claimed that MOVNI must "set no flags." It's certainly true that regEA, being an * 18-bit value, could never be -2^35, but it COULD be zero. However, SIMH doesn't treat zero any * differently for MOVNI, so we currently don't either. * * TODO: Verify the "set no flags" assertion on *real* (KA10) hardware. */ this.writeWord(ac, PDP10.doNEG.call(this, this.regEA) /* this.regEA? PDP10.TWO_POW36 - this.regEA : 0 */); }; /** * opMOVNM(0o212000): Move Negative to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Negate the word from the source specified by M and move it to the specified destination. * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized * number). * * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original * contents of the destination are lost. * * NOTE: This is a "Memory" mode instruction: the source is [A] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVNM = function(op, ac) { this.writeWord(this.regEA, PDP10.doNEG.call(this, this.readWord(ac))); }; /** * opMOVNS(0o213000): Move Negative to Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11: * * Negate the word from the source specified by M and move it to the specified destination. * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized * number). * * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original * contents of the destination are lost. * * NOTE: This is a "Self" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVNS = function(op, ac) { var dst = PDP10.doNEG.call(this, this.readWord(this.regEA)); this.writeWord(this.regEA, dst); if (ac) this.writeWord(ac, dst); }; /** * opMOVM(0o214000): Move Magnitude * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12: * * Take the magnitude of the word contained in the source specified by M and move it to the * specified destination. If the source word is fixed point -2^35 (400000 000000) set the * Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized * number). * * The source is unaffected, the original contents of the destination are lost. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVM = function(op, ac) { this.writeWord(ac, PDP10.doABS.call(this, this.readWord(this.regEA))); }; /** * opMOVMI(0o215000): Move Magnitude Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12: * * Take the magnitude of the word contained in the source specified by M and move it to the * specified destination. If the source word is fixed point -2^35 (400000 000000) set the * Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized * number). * * The source is unaffected, the original contents of the destination are lost. * * SIDEBAR: The word 0,E is equivalent to its magnitude, so MOVMI is equivalent to MOVEI. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVMI = function(op, ac) { this.writeWord(ac, this.regEA); // src is an 18-bit immediate value, so there's no need to call doABS() }; /** * opMOVMM(0o216000): Move Magnitude to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12: * * Take the magnitude of the word contained in the source specified by M and move it to the * specified destination. If the source word is fixed point -2^35 (400000 000000) set the * Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized * number). * * The source is unaffected, the original contents of the destination are lost. * * NOTE: This is a "Memory" mode instruction: the source is [A] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVMM = function(op, ac) { this.writeWord(this.regEA, PDP10.doABS.call(this, this.readWord(ac))); }; /** * opMOVMS(0o217000): Move Magnitude to Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12: * * Take the magnitude of the word contained in the source specified by M and move it to the * specified destination. If the source word is fixed point -2^35 (400000 000000) set the * Overflow and Carry 1 flags. * * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized * number). * * The source is unaffected, the original contents of the destination are lost. * * NOTE: This is a "Self" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMOVMS = function(op, ac) { var dst = PDP10.doABS.call(this, this.readWord(this.regEA)); this.writeWord(this.regEA, dst); if (ac) this.writeWord(ac, dst); }; /** * opIMUL(0o220000): Integer Multiply * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order * word of the double length product is not null); the high order word is lost. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIMUL = function(op, ac) { this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true)); }; /** * opIMULI(0o221000): Integer Multiply Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order * word of the double length product is not null); the high order word is lost. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIMULI = function(op, ac) { this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.regEA, true)); }; /** * opIMULM(0o222000): Integer Multiply to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order * word of the double length product is not null); the high order word is lost. * * NOTE: This is a "Memory" mode instruction: the source is [E] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIMULM = function(op, ac) { this.writeWord(this.regEA, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true)); }; /** * opIMULB(0o223000): Integer Multiply to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order * word of the double length product is not null); the high order word is lost. * * NOTE: This is a "Both" mode instruction: the source is [E] and the destination is [E] and [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIMULB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true))); }; /** * opMUL(0o224000): Multiply * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the high order word of the double length result * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMUL = function(op, ac) { this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA))); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opMULI(0o225000): Multiply Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the high order word of the double length result * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A],[A+1]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMULI = function(op, ac) { this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.regEA)); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opMULM(0o226000): Multiply to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the high order word of the double length result * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70. * * NOTE: This is a "Memory" mode instruction: the source is [E] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMULM = function(op, ac) { this.writeWord(this.regEA, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA))); }; /** * opMULB(0o227000): Multiply to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28: * * Multiply AC by the operand specified by M, and place the high order word of the double length result * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70. * * NOTE: This is a "Both" mode instruction: the source is [E] and the destination is [E] and [A],[A+1]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opMULB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA)))); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opIDIV(0o230000): Integer Divide * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand, * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the * dividend, in accumulator A+1. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIDIV = function(op, ac) { var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac)); if (dst < 0) return; this.writeWord(ac, dst); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opIDIVI(0o231000): Integer Divide Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand, * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the * dividend, in accumulator A+1. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A],[A+1]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIDIVI = function(op, ac) { var dst = PDP10.doDIV.call(this, this.regEA, this.readWord(ac)); if (dst < 0) return; this.writeWord(ac, dst); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opIDIVM(0o232000): Integer Divide to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand, * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the * dividend, in accumulator A+1. * * NOTE: This is a "Memory" mode instruction: the source is [E] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIDIVM = function(op, ac) { var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac)); if (dst < 0) return; this.writeWord(this.regEA, dst); }; /** * opIDIVB(0o233000): Integer Divide to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand, * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the * dividend, in accumulator A+1. * * NOTE: This is a "Both" mode instruction: the source is [E] and the destination is [E] and [A],[A+1]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIDIVB = function(op, ac) { var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac)); if (dst < 0) return; this.writeWord(this.regEA, this.writeWord(ac, dst)); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opDIV(0o234000): Divide * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M, * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1 * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder, * with the same sign as the dividend, in accumulator A+1. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opDIV = function(op, ac) { var ext = this.readWord(ac); var dst = this.readWord((ac + 1) & 0o17); dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext); if (dst < 0) return; this.writeWord(ac, dst); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opDIVI(0o235000): Divide Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M, * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1 * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder, * with the same sign as the dividend, in accumulator A+1. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A],[A+1]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opDIVI = function(op, ac) { var ext = this.readWord(ac); var dst = this.readWord((ac + 1) & 0o17); dst = PDP10.doDIV.call(this, this.regEA, dst, ext); if (dst < 0) return; this.writeWord(ac, dst); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opDIVM(0o236000): Divide to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M, * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1 * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder, * with the same sign as the dividend, in accumulator A+1. * * NOTE: This is a "Memory" mode instruction: the source is [E] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opDIVM = function(op, ac) { var ext = this.readWord(ac); var dst = this.readWord((ac + 1) & 0o17); dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext); if (dst < 0) return; this.writeWord(this.regEA, dst); }; /** * opDIVB(0o237000): Divide to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29: * * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M, * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1 * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder, * with the same sign as the dividend, in accumulator A+1. * * NOTE: This is a "Both" mode instruction: the source is [E] and the destination is [E] and [A],[A+1]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opDIVB = function(op, ac) { var ext = this.readWord(ac); var dst = this.readWord((ac + 1) & 0o17); dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext); if (dst < 0) return; this.writeWord(ac, this.writeWord(this.regEA, dst)); this.writeWord((ac + 1) & 0o17, this.regEX); }; /** * opASH(0o240000): Arithmetic Shift * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-31: * * Arithmetic Shifting * * These two instructions [ASH, ASHC] produce an arithmetic shift right or left of the number in AC * or the double length number in accumulators A and A+1. Shifting is the movement of the contents * of a register bit-to-bit. The operation discussed here is similar to logical shifting [see §2.4 * and the illustration on page 2-24], but in an arithmetic shift only the magnitude part is * shifted - the sign is unaffected. In a double length number the 70-bit string made up of the * magnitude parts of the two words is shifted, but the sign of the low order word is made equal * to the sign of the high order word. * * Null bits are brought in at the end being vacated: a left shift brings in 0s at the right, * whereas a right shift brings in the equivalent of the sign bit at the left. In either case, * information shifted out at the other end is lost. A single shift left is equivalent to multiplying * the number by 2 (provided no bit of significance is shifted out); a shift right divides the number * by 2. * * The number of places shifted is specified by the result of the effective address calculation * taken as a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words * the effective shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the * calculation result. Hence the programmer may specify the shift directly in the instruction * (perhaps indexed) or give an indirect address to be used in calculating the shift. A positive E * produces motion to the left, a negative E to the right; E is thus the power of 2 by which the * number is multiplied. Maximum movement is 255 places. * * ASH: Arithmetic Shift * * Shift AC arithmetically the number of places specified by E. Do not shift bit 0. If E is positive, * shift left bringing 0s into bit 35; data shifted out of bit 1 is lost; set Overflow if any bit of * significance is lost (a 1 in a positive number, a 0 in a negative one). If E is negative, shift right * bringing 0s into bit 1 if AC is positive, 1s if negative; data shifted out of bit 35 is lost. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opASH = function(op, ac) { /* * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255). */ var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff); if (s) { var v , bits; var w = this.readWord(ac); if (s > 0) { bits = PDP10.INT_MASK; v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_LIMIT; if (s < 35) { v += (w * Math.pow(2, s)) % PDP10.INT_LIMIT; /* * bits must be set to the mask of all magnitude bits shifted out of * the original word. Using 8-bit signed words as an example, this table shows * the bits values that would correspond to shifting 1-7 bits left: * * shifts bits value calculation * ------ ----------- ------ ----------- * 1 0b01000000 128-64 128-Math.pow(2, 7-1) * 2 0b01100000 128-32 128-Math.pow(2, 7-2) * 3 0b01110000 128-16 128-Math.pow(2, 7-3) * ... * 7 0b01111111 128-1 128-Math.pow(2, 7-7) */ bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s); } if (w < PDP10.INT_LIMIT) { /* * Since w was positive, overflow occurs ONLY if any of the bits we shifted out were 1s. * If all those bits in the original value (w) were 0s, then adding bits to it could NOT * produce a value > INT_MASK. */ if (w + bits > PDP10.INT_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } } else { /* * Since w was negative, overflow occurs ONLY if any of the bits we shifted out were 0s. * If all those bits in the original value (w) were 1s, subtracting bits from it could NOT * produce a value <= INT_MASK. */ if (w - bits < PDP10.INT_LIMIT) { this.regPS |= PDP10.PSFLAG.AROV; } } } else { if (s <= -35) { v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_MASK; } else { v = Math.trunc(w / Math.pow(2, -s)); if (w > PDP10.INT_MASK) { bits = PDP10.WORD_LIMIT - Math.pow(2, 36 + s); v += bits; } } } this.assert(v >= 0 && v < PDP10.WORD_LIMIT); this.writeWord(ac, v); } }; /** * opROT(0o241000): Rotate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25: * * Rotate AC the number of places specified by E. If E is positive, rotate left; bit 0 is rotated * into bit 35. If E is negative, rotate right; bit 35 is rotated into bit O. * * The number of places moved is specified by the result of the effective address calculation taken as * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result. * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an * indirect address to be used in calculating the shift. A positive E produces motion to the left, * a negative E to the right; maximum movement is 255 places. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opROT = function(op, ac) { /* * Convert the unsigned 18-bit value in regEA to a signed 8-bit value, modulo 36 (+/-35). */ var s = ((((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff)) % 36; if (s) { var w = this.readWord(ac); /* * Note that a right rotation (s < 0) of s bits is equivalent to a left rotation (s > 0) of 36 + s bits. */ if (s < 0) s = 36 + s; w = ((w * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(w / Math.pow(2, 36 - s)); this.writeWord(ac, w); } }; /** * opLSH(0o242000): Logical Shift * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-24: * * Shift and Rotate * * The remaining logical instructions shift or rotate right or left the contents of AC or the contents * of two accumulators, A and A+1 (mod 20 [base 8]), concatenated into a 72-bit register with A on the * left. The illustration below shows the movement of information these instructions produce in the * accumulators. In a (logical) shift the contents of a register are moved bit-to-bit with 0s brought * in at the end being vacated; information shifted out at the other end is lost. [For a discussion of * arithmetic shifting see § 2.5.] In rotation the contents are moved cyclically such that information * rotated out at one end is put in at the other. * * The number of places moved is specified by the result of the effective address calculation taken as a * signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective shift * E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result. Hence * the programmer may specify the shift directly in the instruction (perhaps indexed) or give an indirect * address to be used in calculating the shift. A positive E produces motion to the left, a negative E to * the right; maximum movement is 255 places. * * LSH: Logical Shift * * Shift AC the number of places specified by E. If E is positive, shift left bringing 0s into bit 35; * data shifted out of bit 0 is lost. If E is negative, shift right bringing 0s into bit 0; data shifted * out of bit 35 is lost. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opLSH = function(op, ac) { /* * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255). */ var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff); if (s) { var w = this.readWord(ac); if (s > 0) { if (s >= 36) { w = 0; } else { w = (w * Math.pow(2, s)) % PDP10.WORD_LIMIT; } } else { if (s <= -36) { w = 0; } else { w = Math.trunc(w / Math.pow(2, -s)); } } this.writeWord(ac, w); } }; /** * 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 * @param {number} ac */ PDP10.opJFFO = function(op, ac) { var dst = 0; var src = this.readWord(ac); if (src) { while (src < PDP10.INT_LIMIT) { dst++; src *= 2; } this.setPC(this.regEA); } this.writeWord((ac + 1) & 0o17, dst); }; /** * opASHC(0o244000): Arithmetic Shift * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-32: * * Concatenate the magnitude portions of accumulators A and A+1 with A on the left, and shift * the 70-bit combination in bits 1-35 and 37-71 the number of places specified by E. Do not shift * AC bit 0, but make bit 0 of AC A+1 equal to it if at least one shift occurs (ie if E is nonzero). * * If E is positive, shift left bringing 0s into bit 71 (bit 35 of AC A+1); bit 37 (bit 1 of AC A+1) * is shifted into bit 35; data shifted out of bit 1 is lost; set Overflow if any bit of significance * is lost (a 1 in a positive number, a 0 in a negative one). If E is negative, shift right bringing 0s * into bit 1 if AC is positive, 1s if negative; bit 35 is shifted into bit 37; data shifted out of * bit 71 is lost. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opASHC = function(op, ac) { /* * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255). */ var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff); if (s) { var bits; var wLeft = this.readWord(ac); var wRight = this.readWord((ac + 1) & 0o17); if (s > 0) { /* * Handle all the left shift cases below, which don't need to worry about sign-extension * but DO need to worry about overflow. */ var wLeftOrig = wLeft; if (s >= 36) { /* * Since all wLeft bits are being shifted out, any positive value other than zero OR any negative value * other than WORD_MASK indicates an overflow. */ if (wLeft > 0 && wLeft < PDP10.INT_LIMIT || wLeft > PDP10.INT_MASK && wLeft < PDP10.WORD_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } if (s >= 71) { /* * Since all wRight bits are being shifted out, any positive value other than zero OR any negative value * other than WORD_MASK indicates an overflow. */ if (wRight > 0 && wRight < PDP10.INT_LIMIT || wRight > PDP10.INT_MASK && wRight < PDP10.WORD_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } wLeft = 0; } else { /* * Left shift 36-70 bits. */ wLeft = (wRight * Math.pow(2, s - 35)) % PDP10.INT_LIMIT; bits = PDP10.INT_LIMIT - Math.pow(2, 70 - s); if (wLeftOrig <= PDP10.INT_MASK) { /* * Since wLeft was positive, overflow occurs ONLY if any of the bits we shifted out were 1s. * If all those bits in the original value were 0s, then adding bits to it could NOT produce * a value > INT_MASK. */ if (wRight + bits > PDP10.INT_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } } else { /* * Since wLeft was negative, overflow occurs ONLY if any of the bits we shifted out were 0s. * If all those bits in the original value were 1s, subtracting bits from it could NOT produce * a value <= INT_MASK. */ if (wRight - bits <= PDP10.INT_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } } } wRight = 0; if (wLeftOrig > PDP10.INT_MASK) { wLeft += PDP10.INT_LIMIT; wRight += PDP10.INT_LIMIT; } } else { /* * Left shift 1-35 bits. */ wLeft = ((wLeft * Math.pow(2, s)) % PDP10.INT_LIMIT) + Math.trunc((wRight % PDP10.INT_LIMIT) / Math.pow(2, 35 - s)); wRight = (wRight * Math.pow(2, s)) % PDP10.INT_LIMIT; /* * Determine overflow and update the sign bits. */ bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s); if (wLeftOrig <= PDP10.INT_MASK) { /* * Since wLeft was positive, overflow occurs ONLY if any of the bits we shifted out were 1s. * If all those bits in the original value were 0s, then adding bits to it could NOT produce * a value > INT_MASK. */ if (wLeftOrig + bits > PDP10.INT_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } } else { /* * Since wLeft was negative, overflow occurs ONLY if any of the bits we shifted out were 0s. * If all those bits in the original value were 1s, subtracting bits from it could NOT produce * a value <= INT_MASK. */ if (wLeftOrig - bits <= PDP10.INT_MASK) { this.regPS |= PDP10.PSFLAG.AROV; } /* * Last but not least, update the sign bits of wLeft and wRight to indicate negative values. */ wLeft += PDP10.INT_LIMIT; wRight += PDP10.INT_LIMIT; } } } else { /* * Handle all the right shift cases below, which don't need to worry about overflow but DO * need to worry about sign-extension. */ if (s <= -36) { if (s <= -72) { wRight = (wLeft > PDP10.INT_MASK? PDP10.WORD_MASK : 0); } else { wRight = Math.trunc((wLeft % PDP10.INT_LIMIT) / Math.pow(2, -s - 35)); } if (wLeft <= PDP10.INT_MASK) { wLeft = 0; } else { wLeft = PDP10.WORD_MASK; wRight += PDP10.INT_LIMIT; } } else { /* * For this right shift of 1-35 bits, determine the value of bits shifted in from the left. */ bits = (wLeft > PDP10.INT_MASK? PDP10.WORD_LIMIT - Math.pow(2, 36 + s) : 0); /* * The bits that we add to wRight from wLeft must be shifted right one additional bit, because * they must "skip over" the sign bit of wRight. This means we must zero the sign bit of wRight, * which can be done by performing a "mod" with INT_LIMIT. */ wRight = Math.trunc((wRight % PDP10.INT_LIMIT) / Math.pow(2, -s)) + (((wLeft % PDP10.INT_LIMIT) * Math.pow(2, 35 + s)) % PDP10.INT_LIMIT); wLeft = Math.trunc(wLeft / Math.pow(2, -s)) + bits; /* * Last but not least, we must set the sign of wRight to the sign of wLeft. */ if (wLeft > PDP10.INT_MASK) wRight += PDP10.INT_LIMIT; } } this.writeWord(ac, wLeft); this.writeWord((ac + 1) & 0o17, wRight); } }; /** * opROTC(0o245000): Rotate Combined * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-26: * * Concatenate accumulators A and A+1 with A on the left, and rotate the 72-bit combination the * number of places specified by E. If E is positive, rotate left; bit 0 is rotated into bit 71 * (bit 35 of AC A+1) and bit 36 into bit 35. If E is negative, rotate right; bit 35 is rotated * into bit 36 and bit 71 into bit 0. * * The number of places moved is specified by the result of the effective address calculation taken as * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result. * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an * indirect address to be used in calculating the shift. A positive E produces motion to the left, * a negative E to the right; maximum movement is 255 places. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opROTC = function(op, ac) { /* * Convert the unsigned 18-bit value in regEA to a signed 8-bit value, modulo 72 (+/-71). */ var s = ((((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff)) % 72; if (s) { var wLeft = this.readWord(ac); var wRight = this.readWord((ac + 1) & 0o17); var wLeftOrig = wLeft; /* * Note that a right rotation (s < 0) of s bits is equivalent to a left rotation (s > 0) of 72 + s bits. */ if (s < 0) s = 72 + s; if (s < 36) { wLeft = ((wLeft * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 36 - s)); wRight = ((wRight * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wLeftOrig / Math.pow(2, 36 - s)); } else { wLeft = ((wRight * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT) + Math.trunc(wLeft / Math.pow(2, 72 - s)); wRight = ((wLeftOrig * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 72 - s)); } this.writeWord(ac, wLeft); this.writeWord((ac + 1) & 0o17, wRight); } }; /** * opLSHC(0o246000): Logical Shift Combined * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25: * * Concatenate accumulators A and A+1 with A on the left, and shift the 72-bit combination the number * of places specified by E. If E is positive, shift left bringing 0s into bit 71 (bit 35 of AC A+1); * bit 36 is shifted into bit 35; data shifted out of bit 0 is lost. If E is negative, shift right * bringing 0s into bit 0; bit 35 is shifted into bit 36; data shifted out of bit 71 is lost. * * The number of places moved is specified by the result of the effective address calculation taken as * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result. * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an * indirect address to be used in calculating the shift. A positive E produces motion to the left, * a negative E to the right; maximum movement is 255 places. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opLSHC = function(op, ac) { /* * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255). */ var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff); if (s) { var wLeft = this.readWord(ac); var wRight = this.readWord((ac + 1) & 0o17); if (s > 0) { if (s >= 36) { if (s >= 72) { wLeft = 0; } else { wLeft = (wRight * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT; } wRight = 0; } else { wLeft = ((wLeft * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 36 - s)); wRight = (wRight * Math.pow(2, s)) % PDP10.WORD_LIMIT; } } else { if (s <= -36) { if (s <= -72) { wRight = 0; } else { wRight = Math.trunc(wLeft / Math.pow(2, -s - 36)); } wLeft = 0; } else { wRight = Math.trunc(wRight / Math.pow(2, -s)) + ((wLeft * Math.pow(2, 36 + s)) % PDP10.WORD_LIMIT); wLeft = Math.trunc(wLeft / Math.pow(2, -s)); } } this.writeWord(ac, wLeft); this.writeWord((ac + 1) & 0o17, wRight); } }; /** * opEXCH(0o250000): Exchange * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-9: * * Move the contents of location E to AC and move AC to location E. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opEXCH = function(op, ac) { var tmp = this.readWord(ac); this.writeWord(ac, this.readWord(this.regEA)); this.writeWord(this.regEA, tmp); }; /** * opBLT(0o251000): Block Transfer * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-10: * * Beginning at the location addressed by AC left, move words to another area of memory beginning at the * location addressed by AC right. Continue until a word is moved to location E. The total number of words * in the block is thus E - AC(right) + 1. * * CAUTION: Priority interrupts are allowed during the execution of this instruction, following the processing * of each word. If an interrupt occurs, the BLT stores the source and destination addresses for the next word * in AC, so when the processor restarts upon the return to the interrupted program, it actually resumes at * the correct point within the BLT. Therefore, unless the interrupt system is inactive, A and X must not address * the same register as this would produce a different effective address calculation upon resumption should an * interrupt occur; and the program must not attempt to load an accumulator addressed either by A or X unless it * is the final location being loaded. Furthermore, the program cannot assume that AC is the same after the BLT * as it was before. * * TODO: Determine the logic behind SIMH's bizarre treatment of the AC register when it's part of the memory * being transferred. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opBLT = function(op, ac) { var fDone = false; var addrDst = this.readWord(ac); var addrSrc = (addrDst / PDP10.HALF_SHIFT)|0; addrDst &= PDP10.HALF_MASK; while (!fDone) { this.writeWord(addrDst, this.readWord(addrSrc)); if (addrDst == this.regEA) fDone = true; addrSrc = (addrSrc + 1) & PDP10.HALF_MASK; addrDst = (addrDst + 1) & PDP10.HALF_MASK; if (!this.isRunning()) { /* * Since the CPU isn't currently running, the CPU is presumably being stepped, so we'll treat that the * same as the "priority interrupt" condition described above, update the accumulator, rewind the PC, and leave. */ this.writeWord(ac, addrSrc * PDP10.HALF_SHIFT + addrDst); if (!fDone) this.advancePC(-1); fDone = true; } } }; /** * opAOBJP(0o252000): Add One to Both Halves of AC and Jump if Positive * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-41: * * Add 1000001 [base 8] to AC and place the result back in AC. If the result is greater than or equal * to zero (ie if bit 0 is 0, and hence a negative count in the left half has reached zero or a positive * count has not yet reached 2^17), take the next instruction from location E and continue sequential * operation from there. * * The incrementing of both halves of AC simultaneously is effected by adding 1000001 [base 8]. A count * of -2 in AC left is therefore increased to zero if 2^18 - 1 is incremented in AC right. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOBJP = function(op, ac) { var dst = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT; this.writeWord(ac, dst); if (dst < PDP10.INT_LIMIT) this.setPC(this.regEA); }; /** * opAOBJN(0o253000): Add One to Both Halves of AC and Jump if Negative * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-41: * * Add 1000001 [base 8] to AC and place the result back in AC. If the result is less than zero * (ie if bit 0 is 1, and hence a negative count in the left half has not yet reached zero or a positive * count has reached 2^17), take the next instruction from location E and continue sequential operation * from there. * * The incrementing of both halves of AC simultaneously is effected by adding 1000001 [base 8]. A count * of -2 in AC left is therefore increased to zero if 2^18 - 1 is incremented in AC right. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOBJN = function(op, ac) { var dst = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT; this.writeWord(ac, dst); if (dst >= PDP10.INT_LIMIT) this.setPC(this.regEA); }; /** * opJRST(0o254000): Jump and Restore * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57: * * Perform the functions specified by F, then take the next instruction from location E and continue sequential * operation from there. Bits 9-12 are programmed as follows. * * 9 Restore the channel on which the highest priority interrupt is currently being held [§ 2.13]. * * Unless the User In-out flag is set, this function cannot be executed in a user program. Instead * of restoring the channel, it stores its own instruction code, F and effective address E in bits 0-8, * 9-12 and 18-35 respectively of unrelocated location 40 (clearing bits 13-17), and then executes the * instruction contained in location 41, which is under control of the monitor [§ 2.15]. * * 10 Halt the processor. When it stops, the MA lights on the console display an address one greater * than that of the location containing the instruction that caused the halt, and PC displays the jump * address (the location from which the next instruction will be taken if the operator causes the processor * to resume operation without changing PC). * * Unless the User In-out flag is set, this function cannot be executed in a user program. Instead of * halting the processor, it stores its own instruction code, F and effective address E in Bits 0-8, 9-12 * and 18-35 respectively of unrelocated location 40 (clearing bits 13-17), and then executes the * instruction contained in location 41, which is under control of the monitor [§ 2.15]. * * 11 Restore the flags listed above from the left half of the word in the last location referenced in the * effective address calculation. Hence to restore flags requires that the JRST instruction use indexing * or indirect addressing. * * Restoration of all but the user flags is directly according to the contents of the corresponding bits * as given above: a flag is set by a 1 in the bit, cleared by a 0. A 1 in bit 5 sets User but a 0 has no * effect, so the Monitor can restart a user program by restoring flags but the user cannot leave user * mode by this method. A 0 in bit 6 clears User In-out, but a 1 sets it only if the JRST is being * executed by the Monitor, ie if User is clear. * * 12 Enter user mode. The user program starts at relocated location E. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJRST = function(op, ac) { if (ac & 0b0001) { /* * Enter user mode. */ this.setUserMode(); } if (ac & 0b0010) { /* * Restore the flags. */ this.setPS((this.regLA / PDP10.HALF_SHIFT)|0); } if (ac & 0b0100) { /* * Halt the processor. */ this.stopCPU(); } if (ac & 0b1000) { /* * Restore interrupt channel. */ this.opUndefined(op); } this.setPC(this.regEA); }; /** * opJFCL(0o255000): Jump on Flag and Clear * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57: * * If any flag specified by F [ac] is set, clear it and take the next instruction from location E, * continuing sequential operation from there. * * To select one or a combination of these flags (which are among those described above) the programmer can specify * the equivalent of an AC address that places 1s in the appropriate bits, but MACRO recognizes mnemonics for some of * the 13-bit instruction codes (bits 0-12). * * JFCL JFCL 0, No-op 25500 * JOV JFCL 10, Jump on Overflow 25540 * JCRY0 JFCL 4, Jump on Carry 0 25520 * JCRY1 JFCL 2, Jump on Carry 1 25510 * JCRY JFCL 6, Jump on Carry 0 or 1 25530 * JFOV JFCL 1, Jump on Floating Overflow 25504 * * SIDEBAR: This instruction can be used simply to clear the selected flags by having the jump address point to the * next consecutive location, as in: * * JFCL 17,.+1 * * which clears all four flags without disrupting the normal program sequence. A JFCL that selects no flag is the fastest * no-op as it neither fetches nor stores an operand, and bits 18-35 of the instruction word can be used to store information. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJFCL = function(op, ac) { /* * The ac (F) bits from the opcode align perfectly with the top 4 bits of regPS; all we have to do is shift ac left 14. */ var bitsPS = ac << 14; if (this.regPS & bitsPS) { this.regPS &= ~bitsPS; this.setPC(this.regEA); } }; /** * 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 * @param {number} ac */ PDP10.opXCT = function(op, ac) { this.regXC = this.regEA; }; /** * opPUSHJ(0o260000): Push Down and Jump * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-62: * * Add 1000001 [base 8] to AC to increment both halves by one and place the result back in AC. If the addition * causes the count in AC left to reach zero, set the Pushdown Overflow flag. Then place the current contents of * the flags (as described above) in the left half of the location now addressed by AC right and the contents of * PC in the right half of that location (at this time PC contains an address one greater than the location of * the PUSHJ instruction). Take the next instruction from location E and continue sequential operation from there. * * The flags are unaffected except Byte Interrupt, which is cleared. The original contents of the location added * to the list are lost. If this instruction is executed as a result of a priority interrupt or in unrelocated * 41 or 61 while the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opPUSHJ = function(op, ac) { var p = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT; this.writeWord(ac, p); if (!((p / PDP10.HALF_SHIFT)|0)) { this.regPS |= PDP10.PSFLAG.PDOV; } this.writeWord(p & PDP10.ADDR_MASK, this.getPS() * PDP10.HALF_SHIFT + this.getPC()); this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS() this.setPC(this.regEA); }; /** * opPUSH(0o261000): Push Down * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-13: * * Add 000001 000001 to AC to increment both halves by one, then move the contents of location E to the * location now addressed by AC right. If the addition causes the count in AC left to reach zero, set the * Pushdown Overflow flag. The contents of E are unaffected, the original contents of the location added * to the list are lost. * * If we trusted SIMH, then we could not literally interpret this instruction as adding 000001 000001 to AC, * because if AC contained 777777 777777, adding 000001 000001 would result in 000001 000000, not 000000 000000, * and yet 000000 000000 is EXACTLY what we get in SIMH. * * And yet, DEC's documentation clearly contradicts what SIMH is doing: * * The incrementing and decrementing of both halves of AC simultaneously is effected by adding and subtracting * 000001 000001. Hence a count of -2 in AC left is increased to zero if 2^18 - 1 is incremented in AC right, * and conversely, 1 in AC left is decreased to -1 if zero is decremented in AC right. * * Perhaps SIMH is simply emulating the behavior of some later PDP-10 model, which performed independent increments? * * TODO: Investigate. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opPUSH = function(op, ac) { var p = this.readWord(ac); if (!PDP10.SIMH) { /* * This is the behavior that is clearly documented by DEC. */ p += 0o000001000001; this.writeWord(p & PDP10.ADDR_MASK, this.readWord(this.regEA)); if (p >= PDP10.WORD_LIMIT) p -= PDP10.WORD_LIMIT; if (!((p / PDP10.HALF_SHIFT)|0)) { this.regPS |= PDP10.PSFLAG.PDOV; } } else { /* * This is the SIMH behavior, which appears to increment each half of AC independently. */ var addr = (p + 1) & PDP10.ADDR_MASK; this.writeWord(addr, this.readWord(this.regEA)); p = (p + 0o000001000000) - (p & PDP10.ADDR_MASK) + addr; if (p >= PDP10.WORD_LIMIT) { p -= PDP10.WORD_LIMIT; this.regPS |= PDP10.PSFLAG.PDOV; } } this.writeWord(ac, p); }; /** * opPOP(0o262000): Pop Up * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-13: * * Move the contents of the location addressed by AC right to location E, then subtract 000001 000001 * from AC to decrement both halves by one. If the subtraction causes the count in AC left to reach -1, * set the Pushdown Overflow flag. The original contents of E are lost. * * NOTE: Because of the order in which the operands are stored, the instruction POP AC,AC would load the * contents of the location addressed by AC right into AC on top of the pushdown count, destroying it. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opPOP = function(op, ac) { var p = this.readWord(ac); var src = this.readWord(p & PDP10.ADDR_MASK); this.writeWord(this.regEA, src); if (this.regEA == ac) p = src; // this avoids re-reading the accumulator if the write just overwrote it p -= 0o000001000001; if (p < 0) p += PDP10.WORD_LIMIT; if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) { this.regPS |= PDP10.PSFLAG.PDOV; } this.writeWord(ac, p); }; /** * opPOPJ(0o263000): Pop Up and Jump * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-63: * * Subtract 1000001 [base 8] from AC to decrement both halves by one and place the result back in AC. * If the subtraction causes the count in AC left to reach -1, set the Pushdown Overflow flag. Take the * next instruction from the location addressed by the right half of the location that was addressed by * AC right prior to the decrementing, and continue sequential operation from there. * * SIDEBAR: The effective address E is ignored. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opPOPJ = function(op, ac) { var p = this.readWord(ac); var pc = this.readWord(p & PDP10.ADDR_MASK); p -= 0o000001000001; if (p < 0) p += PDP10.WORD_LIMIT; if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) { this.regPS |= PDP10.PSFLAG.PDOV; } this.writeWord(ac, p); this.setPC(pc & PDP10.ADDR_MASK); }; /** * opJSR(0o264000): Jump to Subroutine * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57: * * Place the current contents of the flags (as described above) in the left half of location E and the * contents of PC in the right half (at this time PC contains an address one greater than the location of * the JSR instruction). Take the next instruction from location E + 1 and continue sequential operation * from there. The flags are unaffected except Byte Interrupt, which is cleared. * * If this instruction is executed as a result of a priority interrupt or in un-relocated 41 or 61 while * the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJSR = function(op, ac) { this.writeWord(this.regEA, this.getPS() * PDP10.HALF_SHIFT + this.getPC()); this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS() this.setPC(this.regEA + 1); }; /** * opJSP(0o265000): Jump and Save PC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-58: * * Place the current contents of the flags (as described above) in AC left and the contents of PC in AC right * (at this time PC contains an address one greater than the location of the JSP instruction). Take the next * instruction from location E and continue sequential operation from there. The flags are unaffected except * Byte Interrupt, which is cleared. * * If this instruction is executed as a result of a priority interrupt or in un-relocated 41 or 61 while the * processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJSP = function(op, ac) { this.writeWord(ac, this.getPS() * PDP10.HALF_SHIFT + this.getPC()); this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS() this.setPC(this.regEA); }; /** * opJSA(0o266000): Jump and Save AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-61: * * Place AC in location E, the effective address E in AC left, and the contents of PC in AC right (at this time * PC contains an address one greater than the location of the JSA instruction). Take the next instruction from * location E + 1 and continue sequential operation from there. The original contents of E are lost. * * If this instruction is executed as a result of a priority interrupt or in unrelocated 41 or 61 while the processor * is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode. * * Regarding JSA and JRA: * * A JSA combines advantages of the JSR and JSP. JSA does modify memory, but it saves PC in an accumulator * without losing its previous contents (at a cost of not saving the flags). It is thus convenient for multiple-entry * subroutines. In a subroutine called by a JSR, the returning JRST must refer to the (single) entry point. * Since a JRA can retrieve the original PC by addressing AC as an index register, it is independent of any entry point * without tying up an accumulator to the extent a JSP would. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJSA = function(op, ac) { this.writeWord(this.regEA, this.readWord(ac)); this.writeWord(ac, this.regEA * PDP10.HALF_SHIFT + this.getPC()); this.setPC(this.regEA + 1); }; /** * opJRA(0o267000): Jump and Restore AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-61: * * Place the contents of the location addressed by AC left into AC. Take the next instruction from location E and * continue sequential operation from there. * * This opcode functions as the counterpart to JSA, but ONLY if location E (the effective address calculated by the JRA) indexes * with the same AC that was used with the JSA. * * JSA 17,F1 * R1: ... * ... * F1: 0 ; location to save AC 17, as specified by the A field of "JSA 17,F1" * F2: ... ; first instruction executed after "JSA 17,F1" * JRA 17,(17) ; return to R1, after restoring AC 17 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJRA = function(op, ac) { var acc = this.readWord(ac); this.writeWord(ac, this.readWord((acc / PDP10.HALF_SHIFT)|0)); this.setPC(this.regEA); }; /** * opADD(0o270000): Add * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35 * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35. * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes * are equal or the positive one is the greater in magnitude. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opADD = function(op, ac) { this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA))); }; /** * opADDI(0o271000): Add Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35 * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35. * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes * are equal or the positive one is the greater in magnitude. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opADDI = function(op, ac) { this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.regEA)); }; /** * opADDM(0o272000): Add to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35 * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35. * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes * are equal or the positive one is the greater in magnitude. * * NOTE: This is a "Memory" mode instruction: the source is [E] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opADDM = function(op, ac) { this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA))); }; /** * opADDB(0o273000): Add to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35 * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35. * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes * are equal or the positive one is the greater in magnitude. * * NOTE: This is a "Both" mode instruction: the source is [E] and the destination is [E] and [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opADDB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA)))); }; /** * opSUB(0o274000): Subtract * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative. * * NOTE: This is a "Basic" mode instruction: the source is [E] and the destination is [A] (opposite of "Memory"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSUB = function(op, ac) { this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA))); }; /** * opSUBI(0o275000): Subtract Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative. * * NOTE: This is an "Immediate" mode instruction: the source is the word 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSUBI = function(op, ac) { this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.regEA)); }; /** * opSUBM(0o276000): Subtract to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative. * * NOTE: This is a "Memory" mode instruction: the source is [E] and the destination is [E] (opposite of "Basic"). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSUBM = function(op, ac) { this.writeWord(this.regEA, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA))); }; /** * opSUBB(0o277000): Subtract to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27: * * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative. * * NOTE: This is a "Both" mode instruction: the source is [E] and the destination is [E] and [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSUBB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA)))); }; /** * opCAIL(0o301000): Compare AC Immediate and Skip if AC Less than E * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAIL = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.regEA) < 0) this.setPC(this.regPC + 1); }; /** * opCAIE(0o302000): Compare AC Immediate and Skip if Equal * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAIE = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.regEA) == 0) this.setPC(this.regPC + 1); }; /** * opCAILE(0o303000): Compare AC Immediate and Skip if AC Less than or Equal to E * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAILE = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.regEA) <= 0) this.setPC(this.regPC + 1); }; /** * opCAIA(0o304000): Compare AC Immediate but Always Skip * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAIA = function(op, ac) { // TODO: Determine if there's any need to actually perform the comparison. this.setPC(this.regPC + 1); }; /** * opCAIGE(0o305000): Compare AC Immediate and Skip if AC Greater than or Equal to E * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAIGE = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.regEA) >= 0) this.setPC(this.regPC + 1); }; /** * opCAIN(0o306000): Compare AC Immediate and Skip if Not Equal * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAIN = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.regEA) != 0) this.setPC(this.regPC + 1); }; /** * opCAIG(0o307000): Compare AC Immediate and Skip if AC Greater than E * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42: * * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition * specified by M is satisfied. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAIG = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.regEA) > 0) this.setPC(this.regPC + 1); }; /** * opCAML(0o311000): Compare AC with Memory and Skip if AC Less * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAML = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) < 0) this.setPC(this.regPC + 1); }; /** * opCAME(0o312000): Compare AC with Memory and Skip if Equal * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAME = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) == 0) this.setPC(this.regPC + 1); }; /** * opCAMLE(0o313000): Compare AC with Memory and Skip if AC Less or Equal * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAMLE = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) <= 0) this.setPC(this.regPC + 1); }; /** * opCAMA(0o314000): Compare AC with Memory but Always Skip * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAMA = function(op, ac) { // TODO: Determine if there's any need to actually perform the comparison. this.setPC(this.regPC + 1); }; /** * opCAMGE(0o315000): Compare AC with Memory and Skip if AC Greater or Equal * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAMGE = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) >= 0) this.setPC(this.regPC + 1); }; /** * opCAMN(0o316000): Compare AC with Memory and Skip if Not Equal * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAMN = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) != 0) this.setPC(this.regPC + 1); }; /** * opCAMG(0o317000): Compare AC with Memory and Skip if AC Greater * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC with the contents of location E and skip the next instruction in sequence if the condition * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized * floating point. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opCAMG = function(op, ac) { if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) > 0) this.setPC(this.regPC + 1); }; /** * opJUMPL(0o321000): Jump if AC Less than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPL = function(op, ac) { if (PDP10.SIGN(this.readWord(ac)) < 0) this.setPC(this.regEA); }; /** * opJUMPE(0o322000): Jump if AC Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPE = function(op, ac) { if (PDP10.SIGN(this.readWord(ac)) == 0) this.setPC(this.regEA); }; /** * opJUMPLE(0o323000): Jump if AC Less than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPLE = function(op, ac) { if (PDP10.SIGN(this.readWord(ac)) <= 0) this.setPC(this.regEA); }; /** * opJUMPA(0o324000): Jump Always * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPA = function(op, ac) { this.setPC(this.regEA); }; /** * opJUMPGE(0o325000): Jump if AC Greater than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPGE = function(op, ac) { if (PDP10.SIGN(this.readWord(ac)) >= 0) this.setPC(this.regEA); }; /** * opJUMPN(0o326000): Jump if AC Not Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPN = function(op, ac) { if (PDP10.SIGN(this.readWord(ac)) != 0) this.setPC(this.regEA); }; /** * opJUMPG(0o327000): Jump if AC Greater than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43: * * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied, * take the next instruction from location E and continue sequential operation from there. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opJUMPG = function(op, ac) { if (PDP10.SIGN(this.readWord(ac)) > 0) this.setPC(this.regEA); }; /** * opSKIP(0o330000): Do Not Skip * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIP = function(op, ac) { if (ac) this.writeWord(ac, this.readWord(this.regEA)); }; /** * opSKIPL(0o331000): Skip if Memory Less than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPL = function(op, ac) { var dst = this.readWord(this.regEA); if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSKIPE(0o332000): Skip if Memory Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPE = function(op, ac) { var dst = this.readWord(this.regEA); if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSKIPLE(0o333000): Skip if Memory Less than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPLE = function(op, ac) { var dst = this.readWord(this.regEA); if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSKIPA(0o334000): Skip Always * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPA = function(op, ac) { this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, this.readWord(this.regEA)); }; /** * opSKIPGE(0o335000): Skip if Memory Greater than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPGE = function(op, ac) { var dst = this.readWord(this.regEA); if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSKIPN(0o336000): Skip if Memory Not Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPN = function(op, ac) { var dst = this.readWord(this.regEA); if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSKIPG(0o337000): Skip if Memory Greater than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents * of location E in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSKIPG = function(op, ac) { var dst = this.readWord(this.regEA); if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOJ(0o340000): Add One to AC but Do Not Jump * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJ = function(op, ac) { this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); }; /** * opAOJL(0o341000): Add One to AC and Jump if Less than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJL = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); if (PDP10.SIGN(dst) < 0) this.setPC(this.regEA); }; /** * opAOJE(0o342000): Add One to AC and Jump if Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJE = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); if (PDP10.SIGN(dst) == 0) this.setPC(this.regEA); }; /** * opAOJLE(0o343000): Add One to AC and Jump if Less than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJLE = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); if (PDP10.SIGN(dst) <= 0) this.setPC(this.regEA); }; /** * opAOJA(0o344000): Add One to AC and Jump Always * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJA = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); this.setPC(this.regEA); }; /** * opAOJGE(0o345000): Add One to AC and Jump if Greater than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJGE = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); if (PDP10.SIGN(dst) >= 0) this.setPC(this.regEA); }; /** * opAOJN(0o346000): Add One to AC and Jump if Not Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJN = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); if (PDP10.SIGN(dst) != 0) this.setPC(this.regEA); }; /** * opAOJG(0o347000): Add One to AC and Jump if Greater than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44: * * Increment AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1 * flags; if -1, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOJG = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1)); if (PDP10.SIGN(dst) > 0) this.setPC(this.regEA); }; /** * opAOS(0o350000): Add One to Memory but Do Not Skip * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOS = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (ac) this.writeWord(ac, dst); }; /** * opAOSL(0o351000): Add One to Memory and Skip if Less than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSL = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOSE(0o352000): Add One to Memory and Skip if Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSE = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOSLE(0o353000): Add One to Memory and Skip if Less than to Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSLE = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOSA(0o354000): Add One to Memory and Skip Always * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSA = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOSGE(0o355000): Add One to Memory and Skip if Greater than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSGE = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOSN(0o356000): Add One to Memory and Skip if Not Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSN = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opAOSG(0o357000): Add One to Memory and Skip if Greater than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Increment the contents of location E by one and place the result back in E. Compare the result * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied. * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0 * and Carry 1. If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAOSG = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1)); if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOJ(0o360000): Subtract One from AC but Do Not Jump * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJ = function(op, ac) { this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); }; /** * opSOJL(0o361000): Subtract One from AC and Jump if Less than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJL = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) < 0) this.setPC(this.regEA); }; /** * opSOJE(0o362000): Subtract One from AC and Jump if Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJE = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) == 0) this.setPC(this.regEA); }; /** * opSOJLE(0o363000): Subtract One from AC and Jump if Less than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJLE = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) <= 0) this.setPC(this.regEA); }; /** * opSOJA(0o364000): Subtract One from AC and Jump Always * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJA = function(op, ac) { this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); this.setPC(this.regEA); }; /** * opSOJGE(0o365000): Subtract One from AC and Jump if Greater than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJGE = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) >= 0) this.setPC(this.regEA); }; /** * opSOJN(0o366000): Subtract One from AC and Jump if Not Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJN = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) != 0) this.setPC(this.regEA); }; /** * opSOJG(0o367000): Subtract One from AC and Jump if Greater than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45: * * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the * condition specified by M is satisfied, take the next instruction from location E and continue sequential * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any * other nonzero number, set Carry 0 and Carry 1. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOJG = function(op, ac) { var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) > 0) this.setPC(this.regEA); }; /** * opSOS(0o370000): Subtract One from Memory but Do Not Skip * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOS = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (ac) this.writeWord(ac, dst); }; /** * opSOSL(0o371000): Subtract One from Memory and Skip if Less than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSL = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOSE(0o372000): Subtract One from Memory and Skip if Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSE = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOSLE(0o373000): Subtract One from Memory and Skip if Less than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSLE = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOSA(0o374000): Subtract One from Memory and Skip Always * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSA = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOSGE(0o375000): Subtract One from Memory and Skip if Greater than or Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSGE = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOSN(0o376000): Subtract One from Memory and Skip if Not Equal to Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSN = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSOSG(0o377000): Subtract One from Memory and Skip if Greater than Zero * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46: * * Decrement the contents of location E by one and place the result back in E. Compare the result with zero, * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1. * If A is nonzero also place the result in AC. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSOSG = function(op, ac) { var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK)); if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1); if (ac) this.writeWord(ac, dst); }; /** * opSETZ(0o400000): Set to Zeros * opSETZI(0o401000): Set to Zeros Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18: * * Change the contents of the destination specified by M to all 0s. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETZ = function(op, ac) { this.writeWord(ac, 0); }; /** * opSETZM(0o402000): Set to Zeros Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18: * * Change the contents of the destination specified by M to all 0s. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETZM = function(op, ac) { this.writeWord(this.regEA, 0); }; /** * opSETZB(0o403000): Set to Zeros Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18: * * Change the contents of the destination specified by M to all 0s. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETZB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, 0)); }; /** * opAND(0o404000): And with AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opAND = function(op, ac) { this.writeWord(ac, PDP10.AND(this.readWord(ac), this.readWord(this.regEA))); }; /** * opANDI(0o405000): And with AC Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand (E) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDI = function(op, ac) { this.writeWord(ac, PDP10.AND(this.readWord(ac), this.regEA)); }; /** * opANDM(0o406000): And with AC to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([E]) to the AND function of the specified operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDM = function(op, ac) { this.writeWord(this.regEA, PDP10.AND(this.readWord(ac), this.readWord(this.regEA))); }; /** * opANDB(0o407000): And with AC to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the specified operand ([E]) * and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(this.readWord(ac), this.readWord(this.regEA)))); }; /** * opANDCA(0o410000): And with Complement of AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand ([E]) * and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCA = function(op, ac) { this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))); }; /** * opANDCAI(0o411000): And with Complement of AC Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand (E) * and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCAI = function(op, ac) { this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.regEA)); }; /** * opANDCAM(0o412000): And with Complement of AC to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([E]) to the AND function of the specified operand ([E]) * and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCAM = function(op, ac) { this.writeWord(this.regEA, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))); }; /** * opANDCAB(0o413000): And with Complement of AC to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the specified operand ([E]) * and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCAB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)))); }; /** * opANDCM(0o420000): And Complement of Memory with AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([AC]) to the AND function of the complement of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCM = function(op, ac) { this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opANDCMI(0o421000): And Complement of Memory Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([AC]) to the AND function of the complement of the specified * operand (E) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCMI = function(op, ac) { this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.regEA)); }; /** * opANDCMM(0o422000): And Complement of Memory to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([E]) to the AND function of the complement of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCMM = function(op, ac) { this.writeWord(this.regEA, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opANDCMB(0o423000): And Complement of Memory to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20: * * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the complement of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCMB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)))); }; /** * opXOR(0o430000): Exclusive Or with AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([AC]) to the exclusive OR function of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opXOR = function(op, ac) { this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opXORI(0o431000): Exclusive Or Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([AC]) to the exclusive OR function of the specified * operand (E) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opXORI = function(op, ac) { this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA)); }; /** * opXORM(0o432000): Exclusive Or to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([E]) to the exclusive OR function of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opXORM = function(op, ac) { this.writeWord(this.regEA, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opXORB(0o433000): Exclusive Or to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([E] and [AC]) to the exclusive OR function of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opXORB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)))); }; /** * opIOR(0o434000): Inclusive Or with AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIOR = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opIORI(0o435000): Inclusive Or with AC Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified * operand (E) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIORI = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA)); }; /** * opIORM(0o436000): Inclusive Or with AC to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIORM = function(op, ac) { this.writeWord(this.regEA, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opIORB(0o437000): Inclusive Or with AC to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the specified * operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opIORB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)))); }; /** * opANDCB(0o440000): And Complements of Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([AC]) to the AND function of the complements of both * the specified operand ([E]) and [AC]. The result is the NOR function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCB = function(op, ac) { this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opANDCBI(0o441000): And Complements of Both Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([AC]) to the AND function of the complements of both * the specified operand (E) and [AC]. The result is the NOR function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCBI = function(op, ac) { this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.regEA)); }; /** * opANDCBM(0o442000): And Complements of Both to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([E]) to the AND function of the complements of both * the specified operand ([E]) and [AC]. The result is the NOR function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCBM = function(op, ac) { this.writeWord(this.regEA, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opANDCBB(0o443000): And Complements of Both to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the complements of both * the specified operand ([E]) and [AC]. The result is the NOR function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opANDCBB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)))); }; /** * opEQV(0o444000): Equivalence with AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23: * * Change the contents of the destination specified by M ([AC]) to the complement of the exclusive OR function of the * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opEQV = function(op, ac) { this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA))); }; /** * opEQVI(0o445000): Equivalence Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23: * * Change the contents of the destination specified by M ([AC]) to the complement of the exclusive OR function of the * specified operand (E) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opEQVI = function(op, ac) { this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.regEA)); }; /** * opEQVM(0o446000): Equivalence to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23: * * Change the contents of the destination specified by M ([E]) to the complement of the exclusive OR function of the * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opEQVM = function(op, ac) { this.writeWord(this.regEA, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA))); }; /** * opEQVB(0o447000): Equivalence to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23: * * Change the contents of the destination specified by M ([E] and [AC]) to the complement of the exclusive OR function of the * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opEQVB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA)))); }; /** * opSETCA(0o450000): Set to Complement of AC * opSETCAI(0o451000): Set to Complement of AC Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([AC]) to the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCA = function(op, ac) { this.writeWord(ac, PDP10.WORD_MASK - this.readWord(ac)); }; /** * opSETCAM(0o452000): Set to Complement of AC Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([E]) to the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCAM = function(op, ac) { this.writeWord(this.regEA, PDP10.WORD_MASK - this.readWord(ac)); }; /** * opSETCAB(0o453000): Set to Complement of AC Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([E] and [AC]) to the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCAB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK - this.readWord(ac))); }; /** * opORCA(0o454000): Inclusive Or with Complement of AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified * operand ([E]) and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCA = function(op, ac) { this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))); }; /** * opORCAI(0o455000): Inclusive Or with Complement of AC Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified * operand (E) and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCAI = function(op, ac) { this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.regEA)); }; /** * opORCAM(0o456000): Inclusive Or with Complement of AC to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the specified * operand ([E]) and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCAM = function(op, ac) { this.writeWord(this.regEA, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))); }; /** * opORCAB(0o457000): Inclusive Or with Complement of AC to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21: * * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the specified * operand ([E]) and the complement of [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCAB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)))); }; /** * opSETCM(0o460000): Set to Complement of Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([AC]) to the complement of the specified source * operand ([E]). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCM = function(op, ac) { this.writeWord(ac, PDP10.WORD_MASK - this.readWord(this.regEA)); }; /** * opSETCMI(0o461000): Set to Complement of Memory Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([AC]) to the complement of the specified source * operand (E). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCMI = function(op, ac) { this.writeWord(ac, PDP10.WORD_MASK - this.regEA); }; /** * opSETCMM(0o462000): Set to Complement of Memory Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([E]) to the complement of the specified source * operand ([E]). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCMM = function(op, ac) { this.writeWord(this.regEA, PDP10.WORD_MASK - this.readWord(this.regEA)); }; /** * opSETCMB(0o463000): Set to Complement of Memory Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19: * * Change the contents of the destination specified by M ([E] and [AC]) to the complement of the specified source * operand ([E]). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETCMB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opORCM(0o464000): Inclusive Or Complement of Memory with AC * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complement of the * specified operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCM = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opORCMI(0o465000): Inclusive Or Complement of Memory Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complement of the * specified operand (E) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCMI = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.regEA)); }; /** * opORCMM(0o466000): Inclusive Or Complement of Memory to Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the complement of the * specified operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCMM = function(op, ac) { this.writeWord(this.regEA, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opORCMB(0o467000): Inclusive Or Complement of Memory to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the complement of the * specified operand ([E]) and [AC]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCMB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)))); }; /** * opORCB(0o470000): Inclusive Or Complements of Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complements of both * the specified operand ([E]) and [AC]. The result is the NAND function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCB = function(op, ac) { this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opORCBI(0o471000): Inclusive Or Complements of Both Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complements of both * the specified operand (E) and [AC]. The result is the NAND function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCBI = function(op, ac) { this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.regEA)); }; /** * opORCBM(0o472000): Inclusive Or Complements of Both To Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the complements of both * the specified operand ([E]) and [AC]. The result is the NAND function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCBM = function(op, ac) { this.writeWord(this.regEA, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))); }; /** * opORCBB(0o473000): Inclusive Or Complements of Both to Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22: * * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the complements of both * the specified operand ([E]) and [AC]. The result is the NAND function of the operands. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opORCBB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)))); }; /** * opSETO(0o474000): Set to Ones * opSETOI(0o475000): Set to Ones Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18: * * Change the contents of the destination specified by M (AC) to all 1s. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETO = function(op, ac) { this.writeWord(ac, PDP10.WORD_MASK); }; /** * opSETOM(0o476000): Set to Ones Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18: * * Change the contents of the destination specified by M ([E]) to all 1s. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETOM = function(op, ac) { this.writeWord(this.regEA, PDP10.WORD_MASK); }; /** * opSETOB(0o477000): Set to Ones Both * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18: * * Change the contents of the destination specified by M ([E] and [AC]) to all 1s. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opSETOB = function(op, ac) { this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK)); }; /** * opHLL(0o5N0000): Half Word Left to Left * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3: * * Move the left half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination are lost. * * For HLL, the source is [E] and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLL = function(op, ac) { var src = this.readWord(this.regEA); var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHR(op, dst, src) + (src - (src & PDP10.HALF_MASK))); }; /** * opHLLI(0o5N1000): Half Word Left to Left, Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3: * * Move the left half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination are lost. * * SIDEBAR: HLLI merely clears AC left. * * For HLLI, the source is 0,E and the destination is [A]. But since this is a left-half-only operation, src is * effectively 0. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLLI = function(op, ac) { var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHR(op, dst, 0)); }; /** * opHLLM(0o5N2000): Half Word Left to Left, Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3: * * Move the left half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination are lost. * * For HLLM, the source is [A] and the destination is [E]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLLM = function(op, ac) { var src = this.readWord(ac); var dst = this.readWord(this.regEA); this.writeWord(this.regEA, PDP10.GETHR(op, dst, src) + (src - (src & PDP10.HALF_MASK))); }; /** * opHLLS(0o5N3000): Half Word Left to Left, Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3: * * Move the left half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination are lost. * * SIDEBAR: If A is zero, HLLS is a no-op, otherwise it is equivalent to HLL. * * For HLLS, the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLLS = function(op, ac) { var dst = this.readWord(this.regEA); dst = PDP10.SETHR(op, dst, dst); this.writeWord(this.regEA, dst); if (ac) this.writeWord(ac, dst); }; /** * opHRL(0o504000): Half Word Right to Left * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4: * * Move the right half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination left * half are lost. * * For HRL, the source is [E] and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRL = function(op, ac) { var src = (this.readWord(this.regEA) & PDP10.HALF_MASK) * PDP10.HALF_SHIFT; var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHR(op, dst, src) + src); }; /** * opHRLI(0o505000): Half Word Right to Left, Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4: * * Move the right half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination left * half are lost. * * For HRLI, the source is 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRLI = function(op, ac) { var src = this.regEA * PDP10.HALF_SHIFT; var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHR(op, dst, src) + src); }; /** * opHRLM(0o506000): Half Word Right to Left, Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4: * * Move the right half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination left * half are lost. * * For HRLM, the source is [A] and the destination is [E]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRLM = function(op, ac) { var src = (this.readWord(ac) & PDP10.HALF_MASK) * PDP10.HALF_SHIFT; var dst = this.readWord(this.regEA); this.writeWord(this.regEA, PDP10.GETHR(op, dst, src) + src); }; /** * opHRLS(0o507000): Half Word Right to Left, Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4: * * Move the right half of the source word specified by M to the left half of the specified destination. * The source and the destination right half are unaffected; the original contents of the destination left * half are lost. * * For HRLS, the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRLS = function(op, ac) { var dst = this.readWord(this.regEA); var src = (dst & PDP10.HALF_MASK) * PDP10.HALF_SHIFT; dst = PDP10.GETHR(op, dst, src) + src; this.writeWord(this.regEA, dst); if (ac) this.writeWord(ac, dst); }; /** * opHRR(0o540000): Half Word Right to Right * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6: * * Move the right half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right * half are lost. * * For HRR, the source is [E] and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRR = function(op, ac) { var src = this.readWord(this.regEA) & PDP10.HALF_MASK; var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHL(op, dst, src) + src); }; /** * opHRRI(0o541000): Half Word Right to Right, Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6: * * Move the right half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right * half are lost. * * For HRRI, the source is 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRRI = function(op, ac) { var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHL(op, dst, this.regEA) + this.regEA); }; /** * opHRRM(0o542000): Half Word Right to Right, Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6: * * Move the right half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right * half are lost. * * For HRRM, the source is [A] and the destination is [E]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRRM = function(op, ac) { var src = this.readWord(ac) & PDP10.HALF_MASK; var dst = this.readWord(this.regEA); this.writeWord(this.regEA, PDP10.GETHL(op, dst, src) + src); }; /** * opHRRS(0o543000): Half Word Right to Right, Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6: * * Move the right half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right * half are lost. * * SIDEBAR: If A is zero, HRRS is a no-op; otherwise it is equivalent to HRR. * * For HRRS, the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHRRS = function(op, ac) { var dst = this.readWord(this.regEA); dst = PDP10.SETHL(op, dst, dst); this.writeWord(this.regEA, dst); if (ac) this.writeWord(ac, dst); }; /** * opHLR(0o544000): Half Word Left to Right * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7: * * Move the left half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right half are lost. * * For HLR, the source is [E] and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLR = function(op, ac) { var src = (this.readWord(this.regEA) / PDP10.HALF_SHIFT)|0; var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHL(op, dst, src) + src); }; /** * opHLRI(0o545000): Half Word Left to Right, Immediate * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7: * * Move the left half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right half are lost. * * SIDEBAR: HLRI merely clears AC right. * * For HLRI, the source is 0,E and the destination is [A]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLRI = function(op, ac) { var dst = this.readWord(ac); this.writeWord(ac, PDP10.GETHL(op, dst, 0)); }; /** * opHLRM(0o546000): Half Word Left to Right, Memory * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7: * * Move the left half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right half are lost. * * For HLRM, the source is [A] and the destination is [E]. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLRM = function(op, ac) { var src = (this.readWord(ac) / PDP10.HALF_SHIFT)|0; var dst = this.readWord(this.regEA); this.writeWord(this.regEA, PDP10.GETHL(op, dst, src) + src); }; /** * opHLRS(0o547000): Half Word Left to Right, Self * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7: * * Move the left half of the source word specified by M to the right half of the specified destination. * The source and the destination left half are unaffected; the original contents of the destination right half are lost. * * For HLRS, the source AND destination is [E] (and also [A] if A is non-zero). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opHLRS = function(op, ac) { var dst = this.readWord(this.regEA); var src = (dst / PDP10.HALF_SHIFT)|0; dst = PDP10.GETHL(op, dst, src) + src; this.writeWord(this.regEA, dst); if (ac) this.writeWord(ac, dst); }; /** * opTRNE(0o602000): Test Right, No Modification, and Skip if All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRNE = function(op, ac) { if (PDP10.AND(this.readWord(ac), this.regEA) == 0) this.setPC(this.regPC + 1); }; /** * opTLNE(0o603000): Test Left, No Modification, and Skip if All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLNE = function(op, ac) { if (PDP10.AND(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT) == 0) this.setPC(this.regPC + 1); }; /** * opTRNA(0o604000): Test Right, No Modification, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRNA = function(op, ac) { this.setPC(this.regPC + 1); }; /** * opTLNA(0o605000): Test Left, No Modification, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLNA = function(op, ac) { this.setPC(this.regPC + 1); }; /** * opTRNN(0o606000): Test Right, No Modification, and Skip if Not All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRNN = function(op, ac) { if (PDP10.AND(this.readWord(ac), this.regEA) != 0) this.setPC(this.regPC + 1); }; /** * opTLNN(0o607000): Test Left, No Modification, and Skip if Not All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLNN = function(op, ac) { if (PDP10.AND(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT) != 0) this.setPC(this.regPC + 1); }; /** * opTDNE(0o612000): Test Direct, No Modification, and Skip if All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDNE = function(op, ac) { if (PDP10.AND(this.readWord(ac), this.readWord(this.regEA)) == 0) this.setPC(this.regPC + 1); }; /** * opTSNE(0o613000): Test Swapped, No Modification, and Skip if All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSNE = function(op, ac) { if (PDP10.AND(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))) == 0) this.setPC(this.regPC + 1); }; /** * opTDNA(0o614000): Test Direct, No Modification, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDNA = function(op, ac) { this.setPC(this.regPC + 1); }; /** * opTSNA(0o615000): Test Swapped, No Modification, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSNA = function(op, ac) { this.setPC(this.regPC + 1); }; /** * opTDNN(0o616000): Test Direct, No Modification, and Skip if Not All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDNN = function(op, ac) { if (PDP10.AND(this.readWord(ac), this.readWord(this.regEA)) != 0) this.setPC(this.regPC + 1); }; /** * opTSNN(0o617000): Test Swapped, No Modification, and Skip if Not All Masked Bits Equal 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSNN = function(op, ac) { if (PDP10.AND(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))) != 0) this.setPC(this.regPC + 1); }; /** * opTRZ(0o620000): Test Right, Zeros, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRZ = function(op, ac) { this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA)); }; /** * opTLZ(0o621000): Test Left, Zeros, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLZ = function(op, ac) { this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT)); }; /** * opTRZE(0o622000): Test Right, Zeros, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRZE = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, this.regEA)); }; /** * opTLZE(0o623000): Test Left, Zeros, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLZE = function(op, ac) { var dst = this.readWord(ac); var src = this.regEA * PDP10.HALF_SHIFT; if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, src)); }; /** * opTRZA(0o624000): Test Right, Zeros, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRZA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA)); }; /** * opTLZA(0o625000): Test Left, Zeros, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLZA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT)); }; /** * opTRZN(0o626000): Test Right, Zeros, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRZN = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, this.regEA)); }; /** * opTLZN(0o627000): Test Left, Zeros, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLZN = function(op, ac) { var dst = this.readWord(ac); var src = this.regEA * PDP10.HALF_SHIFT; if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, src)); }; /** * opTDZ(0o630000): Test Direct, Zeros, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDZ = function(op, ac) { this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opTSZ(0o631000): Test Swapped, Zeros, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSZ = function(op, ac) { this.writeWord(ac, PDP10.CLR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA)))); }; /** * opTDZE(0o632000): Test Direct, Zeros, and Skip if All Masked Bits Equaled a * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDZE = function(op, ac) { var dst = this.readWord(ac); var src = this.readWord(this.regEA); if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, src)); }; /** * opTSZE(0o633000): Test Swapped, Zeros, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSZE = function(op, ac) { var dst = this.readWord(ac); var src = PDP10.SWAP(this.readWord(this.regEA)); if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, src)); }; /** * opTDZA(0o634000): Test Direct, Zeros, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDZA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opTSZA(0o635000): Test Swapped, Zeros, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSZA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA)))); }; /** * opTDZN(0o636000): Test Direct, Zeros, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDZN = function(op, ac) { var dst = this.readWord(ac); var src = this.readWord(this.regEA); if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, src)); }; /** * opTSZN(0o637000): Test Swapped, Zeros, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSZN = function(op, ac) { var dst = this.readWord(ac); var src = PDP10.SWAP(this.readWord(this.regEA)); if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.CLR(dst, src)); }; /** * opTRC(0o640000): Test Right, Complement, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRC = function(op, ac) { this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA)); }; /** * opTLC(0o641000): Test Left, Complement, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLC = function(op, ac) { this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT)); }; /** * opTRCE(0o642000): Test Right, Complement, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRCE = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, this.regEA)); }; /** * opTLCE(0o643000): Test Left, Complement, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLCE = function(op, ac) { var dst = this.readWord(ac); var src = this.regEA * PDP10.HALF_SHIFT; if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, src)); }; /** * opTRCA(0o644000): Test Right, Complement, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRCA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA)); }; /** * opTLCA(0o645000): Test Left, Complement, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLCA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT)); }; /** * opTRCN(0o646000): Test Right, Complement, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRCN = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, this.regEA)); }; /** * opTLCN(0o647000): Test Left, Complement, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLCN = function(op, ac) { var dst = this.readWord(ac); var src = this.regEA * PDP10.HALF_SHIFT; if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, src)); }; /** * opTDC(0o650000): Test Direct, Complement, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDC = function(op, ac) { this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opTSC(0o651000): Test Swapped, Complement, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSC = function(op, ac) { this.writeWord(ac, PDP10.XOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA)))); }; /** * opTDCE(0o652000): Test Direct, Complement, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDCE = function(op, ac) { var dst = this.readWord(ac); var src = this.readWord(this.regEA); if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, src)); }; /** * opTSCE(0o653000): Test Swapped, Complement, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSCE = function(op, ac) { var dst = this.readWord(ac); var src = PDP10.SWAP(this.readWord(this.regEA)); if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, src)); }; /** * opTDCA(0o654000): Test Direct, Complement, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDCA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opTSCA(0o655000): Test Swapped, Complement, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSCA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA)))); }; /** * opTDCN(0o656000): Test Direct, Complement, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDCN = function(op, ac) { var dst = this.readWord(ac); var src = this.readWord(this.regEA); if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, src)); }; /** * opTSCN(0o657000): Test Swapped, Complement, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSCN = function(op, ac) { var dst = this.readWord(ac); var src = PDP10.SWAP(this.readWord(this.regEA)); if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.XOR(dst, src)); }; /** * opTRO(0o660000): Test Right, Ones, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRO = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA)); }; /** * opTLO(0o661000): Test Left, Ones, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLO = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT)); }; /** * opTROE(0o662000): Test Right, Ones, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTROE = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, this.regEA)); }; /** * opTLOE(0o663000): Test Left, Ones, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLOE = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA * PDP10.HALF_SHIFT) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, this.regEA * PDP10.HALF_SHIFT)); }; /** * opTROA(0o664000): Test Right, Ones, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTROA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA)); }; /** * opTLOA(0o665000): Test Left, Ones, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLOA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT)); }; /** * opTRON(0o666000): Test Right, Ones, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTRON = function(op, ac) { var dst = this.readWord(ac); if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, this.regEA)); }; /** * opTLON(0o667000): Test Left, Ones, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTLON = function(op, ac) { var dst = this.readWord(ac); var src = this.regEA * PDP10.HALF_SHIFT; if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, src)); }; /** * opTDO(0o670000): Test Direct, Ones, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDO = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opTSO(0o671000): Test Swapped, Ones, but Do Not Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSO = function(op, ac) { this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA)))); }; /** * opTDOE(0o672000): Test Direct, Ones, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDOE = function(op, ac) { var dst = this.readWord(ac); var src = this.readWord(this.regEA); if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, src)); }; /** * opTSOE(0o673000): Test Swapped, Ones, and Skip if All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSOE = function(op, ac) { var dst = this.readWord(ac); var src = PDP10.SWAP(this.readWord(this.regEA)); if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, src)); }; /** * opTDOA(0o674000): Test Direct, Ones, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDOA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA))); }; /** * opTSOA(0o675000): Test Swapped, Ones, but Always Skip * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSOA = function(op, ac) { this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA)))); }; /** * opTDON(0o676000): Test Direct, Ones, and Skip if Not All Masked Bits Equaled 0 * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTDON = function(op, ac) { var dst = this.readWord(ac); var src = this.readWord(this.regEA); if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, src)); }; /** * opTSON(0o677000): Test Swapped, Ones, and Skip if Not All Masked Bits Equaled a * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opTSON = function(op, ac) { var dst = this.readWord(ac); var src = PDP10.SWAP(this.readWord(this.regEA)); if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1); this.writeWord(ac, PDP10.IOR(dst, src)); }; /** * opBLKI(0o700000) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opBLKI = function(op, dev) { this.opUndefined(op); }; /** * opDATAI(0o700040) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opDATAI = function(op, dev) { this.opUndefined(op); }; /** * opBLKO(0o700100) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opBLKO = function(op, dev) { this.opUndefined(op); }; /** * opDATAO(0o700140) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opDATAO = function(op, dev) { this.opUndefined(op); }; /** * opCONO(0o700200) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opCONO = function(op, dev) { switch(dev) { case PDP10.DEVICES.APR: this.writeFlags(this.readWord(this.regEA)); break; default: this.opUndefined(op); break; } }; /** * opCONI(0o700240) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opCONI = function(op, dev) { switch(dev) { case PDP10.DEVICES.APR: this.writeWord(this.regEA, this.readFlags()); break; default: this.opUndefined(op); break; } }; /** * opCONSZ(0o700300) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opCONSZ = function(op, dev) { this.opUndefined(op); }; /** * opCONSO(0o700340) * * @this {CPUStatePDP10} * @param {number} op * @param {number} dev */ PDP10.opCONSO = function(op, dev) { this.opUndefined(op); }; /** * opIO(0o700xxx-0o777xxx): Input-Output Instructions * * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-68: * * The input-output instructions govern all transfers of data to and from the peripheral equipment, and also * perform many operations within the processor. An instruction in the in-out class is designated by 111 in * bits 0-2, ie its left octal digit is 7. Bits 3-9 address the device that is to respond to the instruction. * The format thus allows for 128 codes, two of which, 000 and 004 respectively, address the processor and * priority interrupt, and are used for the console and time share hardware as well. A chart in Appendix A * lists all devices for which codes have been assigned, and gives their mnemonics and DEC option numbers. * * Bits 13-35 are the same as in all other instructions: they are the I, X, and Y parts, which are used to * calculate an effective address, set of conditions, or mask to be used in the execution of the instruction. * The remaining bits, 10-12, select one of the following eight 10 instructions. * * @this {CPUStatePDP10} * @param {number} op */ PDP10.opIO = function(op) { PDP10.aOpIO_KA10[op & 7].call(this, op, (op >> 3) & 0o177); }; /** * opNOP(op, ac) * * Used for all "defined" operations that, in fact, do nothing (eg, SETA, SETAI, CAI, JUMP). * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opNOP = function(op, ac) { }; /** * opNOPM(op, ac) * * Used for all "defined" operations that, in fact, do nothing (eg, SETMM, CAM) EXCEPT reference memory. * * @this {CPUStatePDP10} * @param {number} op * @param {number} ac */ PDP10.opNOPM = function(op, ac) { }; /** * opUndefined(op, ac) * * @this {CPUStatePDP10} * @param {number} op * @param {number} [ac] */ PDP10.opUndefined = function(op, ac) { this.println("undefined opcode: " + Str.toOct(op)); this.advancePC(-1); this.stopCPU(); }; /** * doABS(src) * * Returns the absolute value (ABS) of the 36-bit operand; used by the MOVM* (Move Magnitude) instructions. * * @this {CPUStatePDP10} * @param {number} src (36-bit) * @return {number} (absolute value of src) */ PDP10.doABS = function(src) { if (src > PDP10.INT_MASK) { if (src != PDP10.INT_LIMIT) { src = PDP10.TWO_POW36 - src; } else { this.regPS |= (PDP10.PSFLAG.AROV | PDP10.PSFLAG.CRY1); } } return src; }; /** * doADD(dst, src) * * Performs the addition (ADD) of two signed 36-bit operands. * * @this {CPUStatePDP10} * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst + src) */ PDP10.doADD = function(dst, src) { /* * Since, in our happy little world, 36-bit values are always unsigned, the * only possible out-of-bounds value is a result >= WORD_LIMIT, which the mod cures. */ var res = (dst + src) % PDP10.WORD_LIMIT; PDP10.setAddFlags.call(this, dst, src, res); return res; }; /** * doDIV(src, dst, ext) * * Performs the division (DIV) of a 72-bit operand by a 36-bit operand. * * @this {CPUStatePDP10} * @param {number} src (36-bit divisor) * @param {number} dst (36-bit value) * @param {number} [ext] (36-bit value extension) * @return {number} (dst / src) (the remainder is stored in regEX); -1 if error (no division performed) */ PDP10.doDIV = function(src, dst, ext) { var fNegQ = false, fNegR = false; /* * Perform all the same up-front checks that the PDP-10 performs; if we do our job correctly, then it * will be impossible for the actual division operation to overflow (the asserts below should never fire). */ if (ext === undefined) { if (!src) { this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV; return -1; } ext = (dst > PDP10.INT_MASK)? PDP10.WORD_MASK : 0; } else { var srcAbs = (src < PDP10.INT_LIMIT? src : PDP10.TWO_POW36 - src); var extAbs = (ext < PDP10.INT_LIMIT? ext : PDP10.TWO_POW36 - ext - (dst? 1 : 0)); if (extAbs >= srcAbs) { this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV; return -1; } } /* * We're done with the PDP-10's "dual sign" operands now; produce a (unified) signed 72-bit dividend. */ dst = PDP10.merge72.call(this, dst, ext); ext = this.regEX; /* * Make all the inputs positive now, to keep the division simple. Fix up the results when we're done. */ if (src > PDP10.INT_MASK) { src = PDP10.WORD_LIMIT - src; fNegQ = !fNegQ; } if (ext > PDP10.INT_MASK) { if (dst) { ext = PDP10.WORD_MASK - ext; dst = PDP10.WORD_LIMIT - dst; } else { if (ext) ext = PDP10.WORD_LIMIT - ext; } fNegR = true; fNegQ = !fNegQ; } /* * Initialize the four double-length 72-bit values we need for the division process. * * The process involves shifting the divisor left 1 bit (ie, doubling it) until it equals * or exceeds the dividend, and then repeatedly subtracting the divisor from the dividend and * shifting the divisor right 1 bit until the divisor is "exhausted" (no bits left), with an * "early out" if the dividend gets "exhausted" first. * * Note that each element of these double arrays is a 36-bit value, so it's rarely a good idea * to use bitwise operators on them, because those would operate on only the low 32 bits. * Stick with the double worker functions I've created, and trust your JavaScript engine to * inline/optimize the code. */ PDP10.INITD(this.regRes, 0, 0); PDP10.INITD(this.regPow, 1, 0); PDP10.INITD(this.regDiv, src, 0); PDP10.INITD(this.regRem, dst, ext); while (PDP10.CMPD(this.regRem, this.regDiv) > 0) { PDP10.ADDD(this.regDiv, this.regDiv); PDP10.ADDD(this.regPow, this.regPow); } do { if (PDP10.CMPD(this.regRem, this.regDiv) >= 0) { PDP10.SUBD(this.regRem, this.regDiv); PDP10.ADDD(this.regRes, this.regPow); if (PDP10.ZEROD(this.regRem)) break; } PDP10.SHRD(this.regDiv); PDP10.SHRD(this.regPow); } while (!PDP10.ZEROD(this.regPow)); this.assert(!this.regRes[1], "extended quotient"); this.assert(!this.regRem[1], "extended remainder"); dst = this.regRes[0]; this.regEX = this.regRem[0]; if (fNegQ && dst) { dst = PDP10.WORD_LIMIT - dst; } if (fNegR && this.regEX) { this.regEX = PDP10.WORD_LIMIT - this.regEX; } return dst; }; /** * doMUL(dst, src, fTruncate, fExternal) * * Performs the multiplication (MUL) of two signed 36-bit operands. * * To support 72-bit results, we perform the multiplication process as you would "by hand", * treating the operands to be multiplied as two 2-digit numbers, where each "digit" is an 18-bit * number (base 2^18). Each individual multiplication of these 18-bit "digits" will produce * a result within 2^36, well within JavaScript integer accuracy. * * PDP-10 Diagnostic Notes * ----------------------- * * The "DAKAK" diagnostic contains the following code: * * 036174: 200240 043643 MOVE 5,43643 ; [43643] = 400000000000 * 036175: 200300 043603 MOVE 6,43603 ; [43603] = 777777777777 * 036176: 200140 043604 MOVE 3,43604 ; [43604] = 000000000001 * 036177: 224240 000003 MUL 5,3 ; Multiply 400000000000 by 000000000001 * 036200: 312240 043604 CAME 5,43604 ; high order result in AC should be: 000000000001 * 036201: 003240 033721 UUO 5,33721 ; * 036202: 312300 043602 CAME 6,43602 ; low order result in AC+1 should be: 000000000000 * * The "natural" result is: * * 05=777777777777 06=400000000000 * * And SIMH seems to agree. So why does the DEC diagnostic expect: * * 05=000000000001 06=000000000000 * * The answer can be found in the June 1982 "DECSYSTEM-10 and DECSYSTEM-20 Processor Reference Manual", * in the description of the MUL instruction: * * CAUTION: In the KA10, an AC operand of 2^35 is treated as though it were +2^35, producing the * incorrect sign in the product. * * This behavior is now simulated below for MODEL_KA10, at least to the extent that the diagnostic is happy. * * @this {CPUStatePDP10} * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @param {boolean} [fTruncate] (true to truncate the result to 36 bits; used by IMUL instructions) * @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state) * @return {number} (dst * src) (the high 36 bits of the result; the low 36 bits are stored in regEX) */ PDP10.doMUL = function(dst, src, fTruncate, fExternal) { var n1 = dst, n2 = src; var fNeg = false, res, ext; /* * If either input is in the negative range, record the sign and make it positive; * we'll negate the result afterward if necessary. */ if (n1 > PDP10.INT_MASK) { if (fExternal || this.model != PDP10.MODEL_KA10 || n1 != PDP10.INT_LIMIT) { n1 = PDP10.WORD_LIMIT - n1; fNeg = !fNeg; } } if (n2 > PDP10.INT_MASK) { n2 = PDP10.WORD_LIMIT - n2; fNeg = !fNeg; } if (n1 < PDP10.HALF_SHIFT && n2 < PDP10.HALF_SHIFT) { res = n1 * n2; ext = 0; } else { var n1d1 = (n1 & PDP10.HALF_MASK); var n1d2 = Math.trunc(n1 / PDP10.HALF_SHIFT); var n2d1 = (n2 & PDP10.HALF_MASK); var n2d2 = Math.trunc(n2 / PDP10.HALF_SHIFT); var m1d1 = n1d1 * n2d1; var m1d2 = (n1d2 * n2d1) + Math.trunc(m1d1 / PDP10.HALF_SHIFT); ext = Math.trunc(m1d2 / PDP10.HALF_SHIFT); m1d2 = (m1d2 & PDP10.HALF_MASK) + (n1d1 * n2d2); res = ((m1d2 * PDP10.HALF_SHIFT) + (m1d1 & PDP10.HALF_MASK)) % PDP10.WORD_LIMIT; ext += Math.trunc(m1d2 / PDP10.HALF_SHIFT) + (n1d2 * n2d2); } if (fNeg) { if (res) { ext = PDP10.WORD_MASK - ext; res = PDP10.WORD_LIMIT - res; } else { if (ext) ext = PDP10.WORD_LIMIT - ext; } } ext = PDP10.split72.call(this, res, ext, fExternal); if (fTruncate) { /* * Special code for IMUL. I originally tried to avoid calling split72() in this case, but the PDP-10 * still appears to be splitting the result of the multiplication into separately signed 36-bit values, * so the simplest solution is to call split72() in all cases. */ res = this.regEX; if (!fExternal) { /* * Regarding IMUL overflows, the original spec says: * * Set Overflow if the product is >= 2^35 or < -2^35 (ie, if the high order word of the double * length product is not null); the high order word is lost. * * However, when the "DAKAL" diagnostic performs a sequence like this: * * 00=000000000000 01=000000000000 02=000000000000 03=400000036755 * 04=400000000000 05=000000000003 06=400000000000 07=000000000004 * 10=000000000000 11=000000000011 12=777777400000 13=777777777776 * 14=000000200000 15=400000037134 16=000000000016 17=000000000000 * PC=037145 RA=00400000 EA=400000 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0 * 037145: 220600 000013 IMUL 14,13 ;cycles=1 * * it sets 14=777777400000 and leaves overflow clear; since the 'high order word" would be 777777777777, * not null, I think the spec over-simplifies. So our check is more exhaustive: it verifies that ext is * nothing more than an extension of the sign bit of res (ie, 0 if res is positive, -1 if res is negative). * Any other combination of values implies an overflow. */ if ((ext || res > PDP10.INT_MASK) && (ext != PDP10.WORD_MASK || res <= PDP10.INT_MASK)) { this.regPS |= PDP10.PSFLAG.AROV; } } ext = res; } return ext; }; /** * doNEG(src) * * Returns the negation (NEG) of the 36-bit operand; used by the MOVN* (Move Negative) instructions. * * @this {CPUStatePDP10} * @param {number} src (36-bit) * @return {number} (src negated, but as an unsigned 36-bit result) */ PDP10.doNEG = function(src) { if (!src) { this.regPS |= (PDP10.PSFLAG.CRY0 | PDP10.PSFLAG.CRY1); } else { /* * In the non-zero case, it's always safe to subtract src from TWO_POW36, but since we have to check for * the INT_LIMIT case anyway, and since subtraction in that case doesn't alter src, we skip the subtraction. */ if (src == PDP10.INT_LIMIT) { this.regPS |= (PDP10.PSFLAG.AROV | PDP10.PSFLAG.CRY1); } else { src = PDP10.TWO_POW36 - src; } } return src; }; /** * doSUB(dst, src) * * Performs the subtraction (SUB) of two signed 36-bit operands. * * @this {CPUStatePDP10} * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst - src) */ PDP10.doSUB = function(dst, src) { /* * Since, in our happy little world, 36-bit values are always unsigned, the * only possible out-of-bounds value is a result < 0, which adding WORD_LIMIT cures. */ var res = (dst - src); if (res < 0) res += PDP10.WORD_LIMIT; /* * We can leverage setAddFlags() by treating the subtraction as addition; * since res = dst - src, it is also true that dst = res + src. */ PDP10.setAddFlags.call(this, res, src, dst); return res; }; /** * merge72(dst, ext) * * Returns a unified 72-bit result from two independently-signed 36-bit values. * * @this {CPUStatePDP10} * @param {number} dst (36-bit value) * @param {number} ext (36-bit value) * @return {number} (returns the lower 36 bits; the upper 36 bits are stored in regEX) */ PDP10.merge72 = function(dst, ext) { var sign = (ext - (ext % PDP10.INT_LIMIT)); /* * For 72-bit inputs, the PDP-10 doesn't care whether or not the low word's sign * matches the high word's sign. The high word's sign bit is the controlling bit. * * this.assert(sign == (dst - (dst % PDP10.INT_LIMIT)), "sign mismatch"); * * Compute value without the sign bit and add the low bit of extended in its place. */ dst = (dst % PDP10.INT_LIMIT) + ((ext & 1) * PDP10.INT_LIMIT); this.regEX = sign + Math.trunc(ext / 2); return dst; }; /** * split72(res, ext, fExternal) * * Returns two 36-bit values with matching sign bits from a unified 72-bit result. * * @this {CPUStatePDP10} * @param {number} res (36-bit value) * @param {number} ext (36-bit value) * @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state) * @return {number} (returns the upper 36 bits; the lower 36 bits are stored in regEX) */ PDP10.split72 = function(res, ext, fExternal) { /* * We just produced a signed 72-bit result, whereas the PDP-10 stores 72-bit arithmetic values as two * signed 36-bit results with matching signs. Since that's effectively only 70 bits of magnitude (with * two sign bits), we lose one bit of magnitude. * * The conversion requires shifting ext left one bit so that we can move the high bit of res into the * low bit of ext, and then set the sign bit of res to match the sign bit of ext. */ var sign = ext - (ext % PDP10.INT_LIMIT); ext = ((ext * 2) % PDP10.WORD_LIMIT) + Math.trunc(res / PDP10.INT_LIMIT); res = sign + (res % PDP10.INT_LIMIT); var signNew = ext - (ext % PDP10.INT_LIMIT); if (signNew != sign) { /* * I used to restore ext's original sign (ext = sign + (ext - signNew)), but the PDP-10's defined * behavior for multiplication overflow (ie, whenever both operands are 0o400000000000) is to set both * res and ext to 0o400000000000. * * To quote the original spec for the MUL instruction: * * If both operands are -2^35 set Overflow; the double length result stored is -2^70. */ res = ext; } if (fExternal) return res; if (res == PDP10.INT_LIMIT && ext == PDP10.INT_LIMIT) { this.regPS |= PDP10.PSFLAG.AROV; } this.regEX = res; return ext; }; /** * setAddFlags(dst, src, res) * * @this {CPUStatePDP10} * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @param {number} res (36-bit value) */ PDP10.setAddFlags = function(dst, src, res) { /* * Isolate the top two bits of dst, src, and res by "shifting" them into bits 0 and 1 of the * following variables. Note that shifting with division only works when the values are unsigned * (which they MUST be). */ Component.assert(dst >= 0 && src >= 0 && res >= 0); var dst01 = Math.trunc(dst / PDP10.TWO_POW34); var src01 = Math.trunc(src / PDP10.TWO_POW34); var res01 = Math.trunc(res / PDP10.TWO_POW34); /* * Transform bits 0 and 1 into carry flags, based on the following truth table: * * D S R C Carry? * - - - - ------ * 0 0 0 0 no * 0 0 1 0 no (there must have been a carry out of the preceding bit, but it was "absorbed") * 0 1 0 1 yes (there must have been a carry out of the preceding bit, but it was NOT "absorbed") * 0 1 1 0 no * 1 0 0 1 yes (same as the preceding "yes" case) * 1 0 1 0 no * 1 1 0 1 yes (since the addition of two ones must always produce a carry) * 1 1 1 1 yes (since the addition of two ones must always produce a carry) */ var bitsCarry = (dst01 ^ ((dst01 ^ src01) & (src01 ^ res01))); var fCarry0 = bitsCarry & 0b10; var fCarry1 = bitsCarry & 0b01; /* * Similarly, we transform bit 1 into an overflow flag, based on the following truth table; * note that X is (D ^ R) and Y is (S ^ R): * * D S R X Y O Overflow? * - - - - - - --------- * 0 0 0 0 0 0 no * 0 0 1 1 1 1 yes (adding two positive values yielded a negative value) * 0 1 0 0 1 0 no * 0 1 1 1 0 0 no * 1 0 0 1 0 0 no * 1 0 1 0 1 0 no * 1 1 0 1 1 1 yes (adding two negative values yielded a positive value) * 1 1 1 0 0 0 no */ var fOverflow = ((dst01 ^ res01) & (src01 ^ res01)) & 0b10; this.regPS |= (fCarry0? PDP10.PSFLAG.CRY0 : 0) | (fCarry1? PDP10.PSFLAG.CRY1 : 0) | (fOverflow? PDP10.PSFLAG.AROV : 0); }; /** * AND(dst, src) * * Performs the logical "and" (AND) of two 36-bit operands. * * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst & src) */ PDP10.AND = function(dst, src) { /* * Since dst and src are 36-bit values, we must AND the low 32 bits separately from the higher bits, * and then combine them with addition. Since all bits above 36 will be zero, and since 0 AND 0 is 0, * no special masking for the higher bits is required. * * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is * positive. * * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert, * because the divisions below would not yield correct results with negative inputs. */ Component.assert(dst >= 0 && src >= 0); return ((((dst / PDP10.TWO_POW32)|0) & ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst & src) >>> 0); }; /** * CLR(dst, src) * * Performs the logical "and" (AND) of a 36-bit operand and its complement. * * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst & ~src) */ PDP10.CLR = function(dst, src) { return PDP10.AND(dst, PDP10.NOT(src)); }; /** * CMP(dst, src) * * Performs the SIGNED comparison (CMP) of two 36-bit operands. * * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst - src) */ PDP10.CMP = function(dst, src) { return (dst < PDP10.INT_LIMIT? dst : dst - PDP10.WORD_LIMIT) - (src < PDP10.INT_LIMIT? src : src - PDP10.WORD_LIMIT); }; /** * EQV(dst, src) * * Performs the logical "equivalence" (EQV) of two 36-bit operands (ie, NOT XOR) * * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (~(dst ^ src)) */ PDP10.EQV = function(dst, src) { /* * Since dst and src are 36-bit values, we must EQV the low 32 bits separately from the higher bits, * and then combine them with addition. Since all bits above 36 will be zero, and since 0 EQV 0 is 1, * we must mask the higher 4 bits with 0o17. * * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is * positive. * * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert, * because the divisions below would not yield correct results with negative inputs. */ Component.assert(dst >= 0 && src >= 0); return ((~(((dst / PDP10.TWO_POW32)|0) ^ ((src / PDP10.TWO_POW32)|0)) & 0o17) * PDP10.TWO_POW32) + (~(dst ^ src) >>> 0); }; /** * IOR(dst, src) * * Performs the logical "inclusive-or" (OR) of two 36-bit operands. * * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst | src) */ PDP10.IOR = function(dst, src) { /* * Since dst and src are 36-bit values, we must OR the low 32 bits separately from the higher bits, * and then combine them with addition. Since all bits above 36 will be zero, and since 0 OR 0 is 0, * no special masking for the higher bits is required. * * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is * positive. * * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert, * because the divisions below would not yield correct results with negative inputs. */ Component.assert(dst >= 0 && src >= 0); return ((((dst / PDP10.TWO_POW32)|0) | ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst | src) >>> 0); }; /** * NOT(src) * * Performs the one's complement (NOT) of a 36-bit operand. * * @param {number} src (36-bit value) * @return {number} (~src) */ PDP10.NOT = function(src) { /* * Since src is a 36-bit value, we must NOT the low 32 bits separately from the higher bits, * and then combine them with addition. Since all bits above 36 will be zero, and since ~0 is 1, * we must mask the higher 4 bits with 0o17. * * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is * positive. * * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert, * because the divisions below would not yield correct results with negative inputs. */ Component.assert(src >= 0); return ((~((src / PDP10.TWO_POW32)|0) & 0o17) * PDP10.TWO_POW32) + (~src >>> 0); }; /** * SIGN(dst) * * Returns the signed form of the 36-bit operand; more efficient than doCMP(dst, 0). * * @param {number} dst (36-bit value) * @return {number} */ PDP10.SIGN = function(dst) { return (dst < PDP10.INT_LIMIT? dst : dst - PDP10.WORD_LIMIT); }; /** * XOR(dst, src) * * Performs the logical "exclusive-or" (XOR) of two 36-bit operands. * * @param {number} dst (36-bit value) * @param {number} src (36-bit value) * @return {number} (dst ^ src) */ PDP10.XOR = function(dst, src) { /* * Since dst and src are 36-bit values, we must XOR the low 32 bits separately from the higher bits, * and then combine them with addition. Since all bits above 36 will be zero, and since 0 XOR 0 is 0, * no special masking for the higher bits is required. * * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is * positive. * * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert, * because the divisions below would not yield correct results with negative inputs. */ Component.assert(dst >= 0 && src >= 0); return ((((dst / PDP10.TWO_POW32)|0) ^ ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst ^ src) >>> 0); }; /** * SWAP(src) * * Used by callers to "swap" the left and right half-words of a 36-bit operand. * * NOTE: Since HALF_MASK is an 18-bit value, it's safe to use "&" with HALF_MASK (equivalent to "%" with HALF_SHIFT). * * @param {number} src * @return {number} (updated src) */ PDP10.SWAP = function(src) { return ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT); }; /** * GETHL(op, dst, src) * * Used by callers to obtain HL (half-word left) with HR (half-word right) zeroed. * * @param {number} op * @param {number} dst (36-bit value whose 18-bit left half is either preserved or modified) * @param {number} src (18-bit value used to determine the sign extension, if any, for the left half of dst) * @return {number} (updated dst) */ PDP10.GETHL = function(op, dst, src) { switch(op & 0o600) { case 0o000: dst -= (dst & PDP10.HALF_MASK); break; case 0o200: dst = 0; break; case 0o400: dst = (PDP10.HALF_MASK * PDP10.HALF_SHIFT); break; case 0o600: dst = (src > PDP10.HINT_MASK? (PDP10.HALF_MASK * PDP10.HALF_SHIFT) : 0); break; } return dst; }; /** * SETHL(op, dst, src) * * Used by callers to obtain HL (half-word left) with HR (half-word right) preserved. * * @param {number} op * @param {number} dst (36-bit value whose 18-bit left half is either preserved or modified) * @param {number} src (18-bit value used to determine the sign extension, if any, for the left half of dst) * @return {number} (updated dst) */ PDP10.SETHL = function(op, dst, src) { if (op &= 0o600) { dst &= PDP10.HALF_MASK; switch(op) { case 0o400: dst += (PDP10.HALF_MASK * PDP10.HALF_SHIFT); break; case 0o600: dst += (src > PDP10.HINT_MASK? (PDP10.HALF_MASK * PDP10.HALF_SHIFT) : 0); break; } } return dst; }; /** * GETHR(op, dst, src) * * Used by callers to obtain HR (half-word right) with HL (half-word left) zeroed. * * @param {number} op * @param {number} dst (36-bit value whose 18-bit right half is either preserved or modified) * @param {number} src (36-bit value used to determine the sign extension, if any, for the right half of dst) * @return {number} (updated dst) */ PDP10.GETHR = function(op, dst, src) { switch(op & 0o600) { case 0o000: dst = (dst & PDP10.HALF_MASK); break; case 0o200: dst = 0; break; case 0o400: dst = PDP10.HALF_MASK; break; case 0o600: dst = (src > PDP10.INT_MASK? PDP10.HALF_MASK : 0); break; } return dst; }; /** * SETHR(op, dst, src) * * Used by callers to obtain HR (half-word right) with HL (half-word left) preserved. * * @param {number} op * @param {number} dst (36-bit value whose 18-bit right half is either preserved or modified) * @param {number} src (36-bit value used to determine the sign extension, if any, for the right half of dst) * @return {number} (updated dst) */ PDP10.SETHR = function(op, dst, src) { if (op &= 0o600) { dst -= (dst & PDP10.HALF_MASK); switch(op) { case 0o400: dst += PDP10.HALF_MASK; break; case 0o600: dst += (src > PDP10.INT_MASK? PDP10.HALF_MASK : 0); break; } } return dst; }; /** * ADDD(dDst, dSrc) * * Adds a double-length value (dSrc) to another (dDst). * * @param {Array.} dDst * @param {Array.} dSrc */ PDP10.ADDD = function(dDst, dSrc) { dDst[0] += dSrc[0]; dDst[1] += dSrc[1]; if (dDst[0] >= PDP10.WORD_LIMIT) { dDst[0] %= PDP10.WORD_LIMIT; dDst[1]++; } }; /** * CMPD(dDst, dSrc) * * Compares double-length values (dDst and dSrc) by computing dDst - dSrc. * * @param {Array.} dDst * @param {Array.} dSrc * @return {number} > 0 if dDst > dSrc, == 0 if dDst == dSrc, < 0 if dDst < dSrc */ PDP10.CMPD = function(dDst, dSrc) { var result = dDst[1] - dSrc[1]; if (!result) result = dDst[0] - dSrc[0]; return result; }; /** * INITD(dDst, lo, hi) * * Initializes a double-length value (dDst). * * @param {Array.} dDst * @param {number} lo * @param {number} hi */ PDP10.INITD = function(dDst, lo, hi) { dDst[0] = lo; dDst[1] = hi; }; /** * SHRD(dDst) * * Shifts a double-length value (dDst) right one bit. * * @param {Array.} dDst */ PDP10.SHRD = function(dDst) { if (dDst[1] % 2) { dDst[0] += PDP10.WORD_LIMIT; } dDst[0] = Math.trunc(dDst[0] / 2); dDst[1] = Math.trunc(dDst[1] / 2); }; /** * SUBD(dDst, dSrc) * * Subtracts a double-length value (dSrc) from another (dDst). * * @param {Array.} dDst * @param {Array.} dSrc */ PDP10.SUBD = function(dDst, dSrc) { dDst[0] -= dSrc[0]; dDst[1] -= dSrc[1]; if (dDst[0] < 0) { dDst[0] += PDP10.WORD_LIMIT; dDst[1]--; } }; /** * ZEROD(d) * * True if all bits in the double-length value (d) are zero, false otherwise. * * @param {Array.} d * @return {boolean} */ PDP10.ZEROD = function(d) { return !d[0] && !d[1]; }; /* * If we want the basic half-word operations to handle all the sub-operations; ie: * * None * Zero-extend * One-extend * Sign-extend * * then we need to alias all the sub-functions to the corresponding primary functions. */ PDP10.opHLLZ = PDP10.opHLL; PDP10.opHLLZI = PDP10.opHLLI; PDP10.opHLLZM = PDP10.opHLLM; PDP10.opHLLZS = PDP10.opHLLS; PDP10.opHLLO = PDP10.opHLL; PDP10.opHLLOI = PDP10.opHLLI; PDP10.opHLLOM = PDP10.opHLLM; PDP10.opHLLOS = PDP10.opHLLS; PDP10.opHLLE = PDP10.opHLL; PDP10.opHLLEI = PDP10.opHLLI; PDP10.opHLLEM = PDP10.opHLLM; PDP10.opHLLES = PDP10.opHLLS; PDP10.opHRLZ = PDP10.opHRL; PDP10.opHRLZI = PDP10.opHRLI; PDP10.opHRLZM = PDP10.opHRLM; PDP10.opHRLZS = PDP10.opHRLS; PDP10.opHRLO = PDP10.opHRL; PDP10.opHRLOI = PDP10.opHRLI; PDP10.opHRLOM = PDP10.opHRLM; PDP10.opHRLOS = PDP10.opHRLS; PDP10.opHRLE = PDP10.opHRL; PDP10.opHRLEI = PDP10.opHRLI; PDP10.opHRLEM = PDP10.opHRLM; PDP10.opHRLES = PDP10.opHRLS; PDP10.opHRRZ = PDP10.opHRR; PDP10.opHRRZI = PDP10.opHRRI; PDP10.opHRRZM = PDP10.opHRRM; PDP10.opHRRZS = PDP10.opHRRS; PDP10.opHRRO = PDP10.opHRR; PDP10.opHRROI = PDP10.opHRRI; PDP10.opHRROM = PDP10.opHRRM; PDP10.opHRROS = PDP10.opHRRS; PDP10.opHRRE = PDP10.opHRR; PDP10.opHRREI = PDP10.opHRRI; PDP10.opHRREM = PDP10.opHRRM; PDP10.opHRRES = PDP10.opHRRS; PDP10.opHLRZ = PDP10.opHLR; PDP10.opHLRZI = PDP10.opHLRI; PDP10.opHLRZM = PDP10.opHLRM; PDP10.opHLRZS = PDP10.opHLRS; PDP10.opHLRO = PDP10.opHLR; PDP10.opHLROI = PDP10.opHLRI; PDP10.opHLROM = PDP10.opHLRM; PDP10.opHLROS = PDP10.opHLRS; PDP10.opHLRE = PDP10.opHLR; PDP10.opHLREI = PDP10.opHLRI; PDP10.opHLREM = PDP10.opHLRM; PDP10.opHLRES = PDP10.opHLRS; PDP10.opSETZI = PDP10.opSETZ; PDP10.opSETOI = PDP10.opSETO; PDP10.opSETCAI = PDP10.opSETCA; PDP10.opSETA = PDP10.opNOP; PDP10.opSETAI = PDP10.opNOP; PDP10.opSETAM = PDP10.opMOVEM; PDP10.opSETAB = PDP10.opMOVEM; PDP10.opSETM = PDP10.opMOVE; PDP10.opSETMI = PDP10.opMOVEI; PDP10.opSETMM = PDP10.opNOPM; PDP10.opSETMB = PDP10.opMOVE; PDP10.opCAI = PDP10.opNOP; PDP10.opCAM = PDP10.opNOPM; PDP10.opJUMP = PDP10.opNOP; PDP10.opTRN = PDP10.opNOP; PDP10.opTLN = PDP10.opNOP; PDP10.opTDN = PDP10.opNOPM; PDP10.opTSN = PDP10.opNOPM; PDP10.aOpXXX_KA10 = [ PDP10.opUUO, // 0o000xxx PDP10.opUUO, // 0o001xxx PDP10.opUUO, // 0o002xxx PDP10.opUUO, // 0o003xxx PDP10.opUUO, // 0o004xxx PDP10.opUUO, // 0o005xxx PDP10.opUUO, // 0o006xxx PDP10.opUUO, // 0o007xxx PDP10.opUUO, // 0o010xxx PDP10.opUUO, // 0o011xxx PDP10.opUUO, // 0o012xxx PDP10.opUUO, // 0o013xxx PDP10.opUUO, // 0o014xxx PDP10.opUUO, // 0o015xxx PDP10.opUUO, // 0o016xxx PDP10.opUUO, // 0o017xxx PDP10.opUUO, // 0o020xxx PDP10.opUUO, // 0o021xxx PDP10.opUUO, // 0o022xxx PDP10.opUUO, // 0o023xxx PDP10.opUUO, // 0o024xxx PDP10.opUUO, // 0o025xxx PDP10.opUUO, // 0o026xxx PDP10.opUUO, // 0o027xxx PDP10.opUUO, // 0o030xxx PDP10.opUUO, // 0o031xxx PDP10.opUUO, // 0o032xxx PDP10.opUUO, // 0o033xxx PDP10.opUUO, // 0o034xxx PDP10.opUUO, // 0o035xxx PDP10.opUUO, // 0o036xxx PDP10.opUUO, // 0o037xxx PDP10.opUUO, // 0o040xxx PDP10.opUUO, // 0o041xxx PDP10.opUUO, // 0o042xxx PDP10.opUUO, // 0o043xxx PDP10.opUUO, // 0o044xxx PDP10.opUUO, // 0o045xxx PDP10.opUUO, // 0o046xxx PDP10.opUUO, // 0o047xxx PDP10.opUUO, // 0o050xxx PDP10.opUUO, // 0o051xxx PDP10.opUUO, // 0o052xxx PDP10.opUUO, // 0o053xxx PDP10.opUUO, // 0o054xxx PDP10.opUUO, // 0o055xxx PDP10.opUUO, // 0o056xxx PDP10.opUUO, // 0o057xxx PDP10.opUUO, // 0o060xxx PDP10.opUUO, // 0o061xxx PDP10.opUUO, // 0o062xxx PDP10.opUUO, // 0o063xxx PDP10.opUUO, // 0o064xxx PDP10.opUUO, // 0o065xxx PDP10.opUUO, // 0o066xxx PDP10.opUUO, // 0o067xxx PDP10.opUUO, // 0o070xxx PDP10.opUUO, // 0o071xxx PDP10.opUUO, // 0o072xxx PDP10.opUUO, // 0o073xxx PDP10.opUUO, // 0o074xxx PDP10.opUUO, // 0o075xxx PDP10.opUUO, // 0o076xxx PDP10.opUUO, // 0o077xxx PDP10.opUndefined, // 0o100xxx PDP10.opUndefined, // 0o101xxx PDP10.opUndefined, // 0o102xxx PDP10.opUndefined, // 0o103xxx PDP10.opUndefined, // 0o104xxx PDP10.opUndefined, // 0o105xxx PDP10.opUndefined, // 0o106xxx PDP10.opUndefined, // 0o107xxx PDP10.opUndefined, // 0o110xxx PDP10.opUndefined, // 0o111xxx PDP10.opUndefined, // 0o112xxx PDP10.opUndefined, // 0o113xxx PDP10.opUndefined, // 0o114xxx PDP10.opUndefined, // 0o115xxx PDP10.opUndefined, // 0o116xxx PDP10.opUndefined, // 0o117xxx PDP10.opUndefined, // 0o120xxx PDP10.opUndefined, // 0o121xxx PDP10.opUndefined, // 0o122xxx PDP10.opUndefined, // 0o123xxx PDP10.opUndefined, // 0o124xxx PDP10.opUndefined, // 0o125xxx PDP10.opUndefined, // 0o126xxx PDP10.opUndefined, // 0o127xxx PDP10.opUFA, // 0o130xxx PDP10.opDFN, // 0o131xxx PDP10.opFSC, // 0o132xxx PDP10.opIBP, // 0o133xxx PDP10.opILDB, // 0o134xxx PDP10.opLDB, // 0o135xxx PDP10.opIDPB, // 0o136xxx PDP10.opDPB, // 0o137xxx PDP10.opFAD, // 0o140xxx PDP10.opFADI, // 0o141xxx PDP10.opFADM, // 0o142xxx PDP10.opFADB, // 0o143xxx PDP10.opFADR, // 0o144xxx PDP10.opFADRI, // 0o145xxx PDP10.opFADRM, // 0o146xxx PDP10.opFADRB, // 0o147xxx PDP10.opFSB, // 0o150xxx PDP10.opFSBI, // 0o151xxx PDP10.opFSBM, // 0o152xxx PDP10.opFSBB, // 0o153xxx PDP10.opFSBR, // 0o154xxx PDP10.opFSBRI, // 0o155xxx PDP10.opFSBRM, // 0o156xxx PDP10.opFSBRB, // 0o157xxx PDP10.opFMP, // 0o160xxx PDP10.opFMPI, // 0o161xxx PDP10.opFMPM, // 0o162xxx PDP10.opFMPB, // 0o163xxx PDP10.opFMPR, // 0o164xxx PDP10.opFMPRI, // 0o165xxx PDP10.opFMPRM, // 0o166xxx PDP10.opFMPRB, // 0o167xxx PDP10.opFDV, // 0o170xxx PDP10.opFDVI, // 0o171xxx PDP10.opFDVM, // 0o172xxx PDP10.opFDVB, // 0o173xxx PDP10.opFDVR, // 0o174xxx PDP10.opFDVRI, // 0o175xxx PDP10.opFDVRM, // 0o176xxx PDP10.opFDVRB, // 0o177xxx PDP10.opMOVE, // 0o200xxx PDP10.opMOVEI, // 0o201xxx PDP10.opMOVEM, // 0o202xxx PDP10.opMOVES, // 0o203xxx PDP10.opMOVS, // 0o204xxx PDP10.opMOVSI, // 0o205xxx PDP10.opMOVSM, // 0o206xxx PDP10.opMOVSS, // 0o207xxx PDP10.opMOVN, // 0o210xxx PDP10.opMOVNI, // 0o211xxx PDP10.opMOVNM, // 0o212xxx PDP10.opMOVNS, // 0o213xxx PDP10.opMOVM, // 0o214xxx PDP10.opMOVMI, // 0o215xxx PDP10.opMOVMM, // 0o216xxx PDP10.opMOVMS, // 0o217xxx PDP10.opIMUL, // 0o220xxx PDP10.opIMULI, // 0o221xxx PDP10.opIMULM, // 0o222xxx PDP10.opIMULB, // 0o223xxx PDP10.opMUL, // 0o224xxx PDP10.opMULI, // 0o225xxx PDP10.opMULM, // 0o226xxx PDP10.opMULB, // 0o227xxx PDP10.opIDIV, // 0o230xxx PDP10.opIDIVI, // 0o231xxx PDP10.opIDIVM, // 0o232xxx PDP10.opIDIVB, // 0o233xxx PDP10.opDIV, // 0o234xxx PDP10.opDIVI, // 0o235xxx PDP10.opDIVM, // 0o236xxx PDP10.opDIVB, // 0o237xxx PDP10.opASH, // 0o240xxx PDP10.opROT, // 0o241xxx PDP10.opLSH, // 0o242xxx PDP10.opJFFO, // 0o243xxx PDP10.opASHC, // 0o244xxx PDP10.opROTC, // 0o245xxx PDP10.opLSHC, // 0o246xxx PDP10.opUndefined, // 0o247xxx PDP10.opEXCH, // 0o250xxx PDP10.opBLT, // 0o251xxx PDP10.opAOBJP, // 0o252xxx PDP10.opAOBJN, // 0o253xxx PDP10.opJRST, // 0o254xxx PDP10.opJFCL, // 0o255xxx PDP10.opXCT, // 0o256xxx PDP10.opUndefined, // 0o257xxx PDP10.opPUSHJ, // 0o260xxx PDP10.opPUSH, // 0o261xxx PDP10.opPOP, // 0o262xxx PDP10.opPOPJ, // 0o263xxx PDP10.opJSR, // 0o264xxx PDP10.opJSP, // 0o265xxx PDP10.opJSA, // 0o266xxx PDP10.opJRA, // 0o267xxx PDP10.opADD, // 0o270xxx PDP10.opADDI, // 0o271xxx PDP10.opADDM, // 0o272xxx PDP10.opADDB, // 0o273xxx PDP10.opSUB, // 0o274xxx PDP10.opSUBI, // 0o275xxx PDP10.opSUBM, // 0o276xxx PDP10.opSUBB, // 0o277xxx PDP10.opCAI, // 0o300xxx PDP10.opCAIL, // 0o301xxx PDP10.opCAIE, // 0o302xxx PDP10.opCAILE, // 0o303xxx PDP10.opCAIA, // 0o304xxx PDP10.opCAIGE, // 0o305xxx PDP10.opCAIN, // 0o306xxx PDP10.opCAIG, // 0o307xxx PDP10.opCAM, // 0o310xxx PDP10.opCAML, // 0o311xxx PDP10.opCAME, // 0o312xxx PDP10.opCAMLE, // 0o313xxx PDP10.opCAMA, // 0o314xxx PDP10.opCAMGE, // 0o315xxx PDP10.opCAMN, // 0o316xxx PDP10.opCAMG, // 0o317xxx PDP10.opJUMP, // 0o320xxx PDP10.opJUMPL, // 0o321xxx PDP10.opJUMPE, // 0o322xxx PDP10.opJUMPLE, // 0o323xxx PDP10.opJUMPA, // 0o324xxx PDP10.opJUMPGE, // 0o325xxx PDP10.opJUMPN, // 0o326xxx PDP10.opJUMPG, // 0o327xxx PDP10.opSKIP, // 0o330xxx PDP10.opSKIPL, // 0o331xxx PDP10.opSKIPE, // 0o332xxx PDP10.opSKIPLE, // 0o333xxx PDP10.opSKIPA, // 0o334xxx PDP10.opSKIPGE, // 0o335xxx PDP10.opSKIPN, // 0o336xxx PDP10.opSKIPG, // 0o337xxx PDP10.opAOJ, // 0o340xxx PDP10.opAOJL, // 0o341xxx PDP10.opAOJE, // 0o342xxx PDP10.opAOJLE, // 0o343xxx PDP10.opAOJA, // 0o344xxx PDP10.opAOJGE, // 0o345xxx PDP10.opAOJN, // 0o346xxx PDP10.opAOJG, // 0o347xxx PDP10.opAOS, // 0o350xxx PDP10.opAOSL, // 0o351xxx PDP10.opAOSE, // 0o352xxx PDP10.opAOSLE, // 0o353xxx PDP10.opAOSA, // 0o354xxx PDP10.opAOSGE, // 0o355xxx PDP10.opAOSN, // 0o356xxx PDP10.opAOSG, // 0o357xxx PDP10.opSOJ, // 0o360xxx PDP10.opSOJL, // 0o361xxx PDP10.opSOJE, // 0o362xxx PDP10.opSOJLE, // 0o363xxx PDP10.opSOJA, // 0o364xxx PDP10.opSOJGE, // 0o365xxx PDP10.opSOJN, // 0o366xxx PDP10.opSOJG, // 0o367xxx PDP10.opSOS, // 0o370xxx PDP10.opSOSL, // 0o371xxx PDP10.opSOSE, // 0o372xxx PDP10.opSOSLE, // 0o373xxx PDP10.opSOSA, // 0o374xxx PDP10.opSOSGE, // 0o375xxx PDP10.opSOSN, // 0o376xxx PDP10.opSOSG, // 0o377xxx PDP10.opSETZ, // 0o400xxx PDP10.opSETZI, // 0o401xxx PDP10.opSETZM, // 0o402xxx PDP10.opSETZB, // 0o403xxx PDP10.opAND, // 0o404xxx PDP10.opANDI, // 0o405xxx PDP10.opANDM, // 0o406xxx PDP10.opANDB, // 0o407xxx PDP10.opANDCA, // 0o410xxx PDP10.opANDCAI, // 0o411xxx PDP10.opANDCAM, // 0o412xxx PDP10.opANDCAB, // 0o413xxx PDP10.opSETM, // 0o414xxx PDP10.opSETMI, // 0o415xxx PDP10.opSETMM, // 0o416xxx PDP10.opSETMB, // 0o417xxx PDP10.opANDCM, // 0o420xxx PDP10.opANDCMI, // 0o421xxx PDP10.opANDCMM, // 0o422xxx PDP10.opANDCMB, // 0o423xxx PDP10.opSETA, // 0o424xxx PDP10.opSETAI, // 0o425xxx PDP10.opSETAM, // 0o426xxx PDP10.opSETAB, // 0o427xxx PDP10.opXOR, // 0o430xxx PDP10.opXORI, // 0o431xxx PDP10.opXORM, // 0o432xxx PDP10.opXORB, // 0o433xxx PDP10.opIOR, // 0o434xxx PDP10.opIORI, // 0o435xxx PDP10.opIORM, // 0o436xxx PDP10.opIORB, // 0o437xxx PDP10.opANDCB, // 0o440xxx PDP10.opANDCBI, // 0o441xxx PDP10.opANDCBM, // 0o442xxx PDP10.opANDCBB, // 0o443xxx PDP10.opEQV, // 0o444xxx PDP10.opEQVI, // 0o445xxx PDP10.opEQVM, // 0o446xxx PDP10.opEQVB, // 0o447xxx PDP10.opSETCA, // 0o450xxx PDP10.opSETCAI, // 0o451xxx PDP10.opSETCAM, // 0o452xxx PDP10.opSETCAB, // 0o453xxx PDP10.opORCA, // 0o454xxx PDP10.opORCAI, // 0o455xxx PDP10.opORCAM, // 0o456xxx PDP10.opORCAB, // 0o457xxx PDP10.opSETCM, // 0o460xxx PDP10.opSETCMI, // 0o461xxx PDP10.opSETCMM, // 0o462xxx PDP10.opSETCMB, // 0o463xxx PDP10.opORCM, // 0o464xxx PDP10.opORCMI, // 0o465xxx PDP10.opORCMM, // 0o466xxx PDP10.opORCMB, // 0o467xxx PDP10.opORCB, // 0o470xxx PDP10.opORCBI, // 0o471xxx PDP10.opORCBM, // 0o472xxx PDP10.opORCBB, // 0o473xxx PDP10.opSETO, // 0o474xxx PDP10.opSETOI, // 0o475xxx PDP10.opSETOM, // 0o476xxx PDP10.opSETOB, // 0o477xxx PDP10.opHLL, // 0o500xxx PDP10.opHLLI, // 0o501xxx PDP10.opHLLM, // 0o502xxx PDP10.opHLLS, // 0o503xxx PDP10.opHRL, // 0o504xxx PDP10.opHRLI, // 0o505xxx PDP10.opHRLM, // 0o506xxx PDP10.opHRLS, // 0o507xxx PDP10.opHLLZ, // 0o510xxx PDP10.opHLLZI, // 0o511xxx PDP10.opHLLZM, // 0o512xxx PDP10.opHLLZS, // 0o513xxx PDP10.opHRLZ, // 0o514xxx PDP10.opHRLZI, // 0o515xxx PDP10.opHRLZM, // 0o516xxx PDP10.opHRLZS, // 0o517xxx PDP10.opHLLO, // 0o520xxx PDP10.opHLLOI, // 0o521xxx PDP10.opHLLOM, // 0o522xxx PDP10.opHLLOS, // 0o523xxx PDP10.opHRLO, // 0o524xxx PDP10.opHRLOI, // 0o525xxx PDP10.opHRLOM, // 0o526xxx PDP10.opHRLOS, // 0o527xxx PDP10.opHLLE, // 0o530xxx PDP10.opHLLEI, // 0o531xxx PDP10.opHLLEM, // 0o532xxx PDP10.opHLLES, // 0o533xxx PDP10.opHRLE, // 0o534xxx PDP10.opHRLEI, // 0o535xxx PDP10.opHRLEM, // 0o536xxx PDP10.opHRLES, // 0o537xxx PDP10.opHRR, // 0o540xxx PDP10.opHRRI, // 0o541xxx PDP10.opHRRM, // 0o542xxx PDP10.opHRRS, // 0o543xxx PDP10.opHLR, // 0o544xxx PDP10.opHLRI, // 0o545xxx PDP10.opHLRM, // 0o546xxx PDP10.opHLRS, // 0o547xxx PDP10.opHRRZ, // 0o550xxx PDP10.opHRRZI, // 0o551xxx PDP10.opHRRZM, // 0o552xxx PDP10.opHRRZS, // 0o553xxx PDP10.opHLRZ, // 0o554xxx PDP10.opHLRZI, // 0o555xxx PDP10.opHLRZM, // 0o556xxx PDP10.opHLRZS, // 0o557xxx PDP10.opHRRO, // 0o560xxx PDP10.opHRROI, // 0o561xxx PDP10.opHRROM, // 0o562xxx PDP10.opHRROS, // 0o563xxx PDP10.opHLRO, // 0o564xxx PDP10.opHLROI, // 0o565xxx PDP10.opHLROM, // 0o566xxx PDP10.opHLROS, // 0o567xxx PDP10.opHRRE, // 0o570xxx PDP10.opHRREI, // 0o571xxx PDP10.opHRREM, // 0o572xxx PDP10.opHRRES, // 0o573xxx PDP10.opHLRE, // 0o574xxx PDP10.opHLREI, // 0o575xxx PDP10.opHLREM, // 0o576xxx PDP10.opHLRES, // 0o577xxx PDP10.opTRN, // 0o600xxx PDP10.opTLN, // 0o601xxx PDP10.opTRNE, // 0o602xxx PDP10.opTLNE, // 0o603xxx PDP10.opTRNA, // 0o604xxx PDP10.opTLNA, // 0o605xxx PDP10.opTRNN, // 0o606xxx PDP10.opTLNN, // 0o607xxx PDP10.opTDN, // 0o610xxx PDP10.opTSN, // 0o611xxx PDP10.opTDNE, // 0o612xxx PDP10.opTSNE, // 0o613xxx PDP10.opTDNA, // 0o614xxx PDP10.opTSNA, // 0o615xxx PDP10.opTDNN, // 0o616xxx PDP10.opTSNN, // 0o617xxx PDP10.opTRZ, // 0o620xxx PDP10.opTLZ, // 0o621xxx PDP10.opTRZE, // 0o622xxx PDP10.opTLZE, // 0o623xxx PDP10.opTRZA, // 0o624xxx PDP10.opTLZA, // 0o625xxx PDP10.opTRZN, // 0o626xxx PDP10.opTLZN, // 0o627xxx PDP10.opTDZ, // 0o630xxx PDP10.opTSZ, // 0o631xxx PDP10.opTDZE, // 0o632xxx PDP10.opTSZE, // 0o633xxx PDP10.opTDZA, // 0o634xxx PDP10.opTSZA, // 0o635xxx PDP10.opTDZN, // 0o636xxx PDP10.opTSZN, // 0o637xxx PDP10.opTRC, // 0o640xxx PDP10.opTLC, // 0o641xxx PDP10.opTRCE, // 0o642xxx PDP10.opTLCE, // 0o643xxx PDP10.opTRCA, // 0o644xxx PDP10.opTLCA, // 0o645xxx PDP10.opTRCN, // 0o646xxx PDP10.opTLCN, // 0o647xxx PDP10.opTDC, // 0o650xxx PDP10.opTSC, // 0o651xxx PDP10.opTDCE, // 0o652xxx PDP10.opTSCE, // 0o653xxx PDP10.opTDCA, // 0o654xxx PDP10.opTSCA, // 0o655xxx PDP10.opTDCN, // 0o656xxx PDP10.opTSCN, // 0o657xxx PDP10.opTRO, // 0o660xxx PDP10.opTLO, // 0o661xxx PDP10.opTROE, // 0o662xxx PDP10.opTLOE, // 0o663xxx PDP10.opTROA, // 0o664xxx PDP10.opTLOA, // 0o665xxx PDP10.opTRON, // 0o666xxx PDP10.opTLON, // 0o667xxx PDP10.opTDO, // 0o670xxx PDP10.opTSO, // 0o671xxx PDP10.opTDOE, // 0o672xxx PDP10.opTSOE, // 0o673xxx PDP10.opTDOA, // 0o674xxx PDP10.opTSOA, // 0o675xxx PDP10.opTDON, // 0o676xxx PDP10.opTSON, // 0o677xxx PDP10.opIO, // 0o700xxx PDP10.opIO, // 0o701xxx PDP10.opIO, // 0o702xxx PDP10.opIO, // 0o703xxx PDP10.opIO, // 0o704xxx PDP10.opIO, // 0o705xxx PDP10.opIO, // 0o706xxx PDP10.opIO, // 0o707xxx PDP10.opIO, // 0o710xxx PDP10.opIO, // 0o711xxx PDP10.opIO, // 0o712xxx PDP10.opIO, // 0o713xxx PDP10.opIO, // 0o714xxx PDP10.opIO, // 0o715xxx PDP10.opIO, // 0o716xxx PDP10.opIO, // 0o717xxx PDP10.opIO, // 0o720xxx PDP10.opIO, // 0o721xxx PDP10.opIO, // 0o722xxx PDP10.opIO, // 0o723xxx PDP10.opIO, // 0o724xxx PDP10.opIO, // 0o725xxx PDP10.opIO, // 0o726xxx PDP10.opIO, // 0o727xxx PDP10.opIO, // 0o730xxx PDP10.opIO, // 0o731xxx PDP10.opIO, // 0o732xxx PDP10.opIO, // 0o733xxx PDP10.opIO, // 0o734xxx PDP10.opIO, // 0o735xxx PDP10.opIO, // 0o736xxx PDP10.opIO, // 0o737xxx PDP10.opIO, // 0o740xxx PDP10.opIO, // 0o741xxx PDP10.opIO, // 0o742xxx PDP10.opIO, // 0o743xxx PDP10.opIO, // 0o744xxx PDP10.opIO, // 0o745xxx PDP10.opIO, // 0o746xxx PDP10.opIO, // 0o747xxx PDP10.opIO, // 0o750xxx PDP10.opIO, // 0o751xxx PDP10.opIO, // 0o752xxx PDP10.opIO, // 0o753xxx PDP10.opIO, // 0o754xxx PDP10.opIO, // 0o755xxx PDP10.opIO, // 0o756xxx PDP10.opIO, // 0o757xxx PDP10.opIO, // 0o760xxx PDP10.opIO, // 0o761xxx PDP10.opIO, // 0o762xxx PDP10.opIO, // 0o763xxx PDP10.opIO, // 0o764xxx PDP10.opIO, // 0o765xxx PDP10.opIO, // 0o766xxx PDP10.opIO, // 0o767xxx PDP10.opIO, // 0o770xxx PDP10.opIO, // 0o771xxx PDP10.opIO, // 0o772xxx PDP10.opIO, // 0o773xxx PDP10.opIO, // 0o774xxx PDP10.opIO, // 0o775xxx PDP10.opIO, // 0o776xxx PDP10.opIO // 0o777xxx ]; PDP10.aOpIO_KA10 = [ PDP10.opBLKI, // 0o70000x PDP10.opDATAI, // 0o70004x PDP10.opBLKO, // 0o70010x PDP10.opDATAO, // 0o70014x PDP10.opCONO, // 0o70020x PDP10.opCONI, // 0o70024x PDP10.opCONSZ, // 0o70030x PDP10.opCONSO // 0o70034x ];