Added logic (untested) for ASH
This commit is contained in:
parent
20c24053b9
commit
5d48383363
4 changed files with 424 additions and 302 deletions
|
|
@ -998,7 +998,7 @@ PDP10.opMOVN = function(op, acc)
|
|||
PDP10.opMOVNI = function(op, acc)
|
||||
{
|
||||
/*
|
||||
* We perform an in-line two's complement of regEA, since negate() updates the flags, and the documentation
|
||||
* We perform an in-line twos complement of regEA, since negate() updates the flags, and the documentation
|
||||
* above claims that this operation 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 -- and apparently this instruction treats zero differently from MOVN.
|
||||
*
|
||||
|
|
@ -1356,7 +1356,40 @@ PDP10.opDIVB = function(op, acc)
|
|||
};
|
||||
|
||||
/**
|
||||
* opASH(0o240000)
|
||||
* opASH(0o240000): Artithmetic Shift
|
||||
*
|
||||
* From the DEC PDP-10 System Reference Manual (May 1968), p. 2-31:
|
||||
*
|
||||
* Arithmetic Shifting
|
||||
*
|
||||
* These two instructions 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 28 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
|
||||
|
|
@ -1364,7 +1397,62 @@ PDP10.opDIVB = function(op, acc)
|
|||
*/
|
||||
PDP10.opASH = function(op, acc)
|
||||
{
|
||||
this.opUndefined(op);
|
||||
/*
|
||||
* Convert the unsigned 18-bit value in regEA to a signed 8-bit value (+/-255).
|
||||
*/
|
||||
var s = (this.regEA << 14) >> 24;
|
||||
if (s) {
|
||||
var w = this.readWord(acc), bitsShifted;
|
||||
/*
|
||||
* Convert the unsigned word (w) to a signed value (i), for convenience.
|
||||
*/
|
||||
var i = w > PDP10.MAX_POS36? -(PDP10.WORD_LIMIT - w) : w;
|
||||
if (s > 0) {
|
||||
if (s >= 35) {
|
||||
i = (i < 0? PDP10.INT_LIMIT : 0);
|
||||
bitsShifted = PDP10.INT_MASK;
|
||||
} else {
|
||||
i = (i * Math.pow(2, s)) % PDP10.INT_LIMIT;
|
||||
/*
|
||||
* bitsShifted 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 bitsShifted values that would correspond to shifting 1-7 bits left:
|
||||
*
|
||||
* shifts bitsShifted 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)
|
||||
*/
|
||||
bitsShifted = PDP10.INT_LIMIT - Math.pow(2, 35-s);
|
||||
}
|
||||
if (w <= PDP10.MAX_POS36) {
|
||||
/*
|
||||
* 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 bitsShifted to it could NOT
|
||||
* produce a value > MAX_POS36.
|
||||
*/
|
||||
if (w + bitsShifted > PDP10.MAX_POS36) this.fOverflow = true;
|
||||
} 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 bitsShifted from it could NOT
|
||||
* produce a value <= MAX_POS36.
|
||||
*/
|
||||
if (w - bitsShifted <= PDP10.MAX_POS36) this.fOverflow = true;
|
||||
}
|
||||
} else {
|
||||
if (s <= -35) {
|
||||
i = (i < 0? -1 : 0);
|
||||
} else {
|
||||
i = Math.trunc(i / Math.pow(2, -s));
|
||||
}
|
||||
}
|
||||
w = (i < 0? i + PDP10.WORD_LIMIT: i);
|
||||
this.writeWord(acc, w);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1399,7 +1487,26 @@ PDP10.opROT = function(op, acc)
|
|||
/**
|
||||
* opLSH(0o242000): Logical Shift
|
||||
*
|
||||
* From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25:
|
||||
* 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
|
||||
|
|
@ -1447,7 +1554,19 @@ PDP10.opJFFO = function(op, acc)
|
|||
};
|
||||
|
||||
/**
|
||||
* opASHC(0o244000)
|
||||
* 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
|
||||
|
|
@ -1504,7 +1623,7 @@ PDP10.opROTC = function(op, acc)
|
|||
* 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);
|
||||
* 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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -104,10 +104,12 @@ var PDP10 = {
|
|||
ADDR_LIMIT: Math.pow(2, 18),
|
||||
ADDR_MASK: Math.pow(2, 18) - 1,
|
||||
WORD_INVALID: -1,
|
||||
WORD_LIMIT: Math.pow(2, 36),
|
||||
WORD_MASK: Math.pow(2, 36) - 1,
|
||||
HALF_SHIFT: Math.pow(2, 18),
|
||||
HALF_MASK: Math.pow(2, 18) - 1,
|
||||
INT_LIMIT: Math.pow(2, 35), // signed word (magnitude) limit
|
||||
INT_MASK: Math.pow(2, 35) - 1, // signed word (magnitude) mask
|
||||
WORD_LIMIT: Math.pow(2, 36), // unsigned word limit
|
||||
WORD_MASK: Math.pow(2, 36) - 1, // unsigned word mask
|
||||
HALF_SHIFT: Math.pow(2, 18), // unsigned half-word shift
|
||||
HALF_MASK: Math.pow(2, 18) - 1, // unsigned half-word mask
|
||||
|
||||
/*
|
||||
* 18-bit and 36-bit largest positive (and smallest negative) values; however, since we store all
|
||||
|
|
|
|||
Loading…
Reference in a new issue