Fixed/simplified opASH() a bit; it wasn't preserving the sign bit in all cases, and converting the input from unsigned to signed and back again was more confusing than helpful

This commit is contained in:
Jeff 2017-03-30 14:49:49 -07:00 committed by Jeff Parsons
commit 3f06667597
3 changed files with 49 additions and 29 deletions

View file

@ -1668,17 +1668,13 @@ PDP10.opASH = function(op, ac)
*/
var s = ((this.regEA << 14) >> 14) % 256;
if (s) {
var w = this.readWord(ac), bits;
/*
* Convert the unsigned word (w) to a signed value (i), for convenience.
*/
var i = w > PDP10.INT_MASK? -(PDP10.WORD_LIMIT - w) : w;
var v , bits;
var w = this.readWord(ac);
if (s > 0) {
if (s >= 35) {
i = (i < 0? PDP10.INT_LIMIT : 0);
bits = PDP10.INT_MASK;
} else {
i = (i * Math.pow(2, s)) % PDP10.INT_LIMIT;
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
@ -1694,30 +1690,38 @@ PDP10.opASH = function(op, ac)
*/
bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s);
}
if (w <= PDP10.INT_MASK) {
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;
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_MASK) this.regPS |= PDP10.PSFLAG.AROV;
if (w - bits < PDP10.INT_LIMIT) {
this.regPS |= PDP10.PSFLAG.AROV;
}
}
} else {
if (s <= -35) {
i = (i < 0? -1 : 0);
v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_MASK;
} else {
i = Math.trunc(i / Math.pow(2, -s));
v = Math.trunc(w / Math.pow(2, -s));
if (w > PDP10.INT_MASK) {
bits = PDP10.WORD_LIMIT - Math.pow(2, 36 + s);
v += bits;
}
}
}
w = (i < 0? i + PDP10.WORD_LIMIT: i);
this.writeWord(ac, w);
this.assert(v >= 0 && v < PDP10.WORD_LIMIT);
this.writeWord(ac, v);
}
};
@ -1900,14 +1904,18 @@ PDP10.opASHC = function(op, ac)
* 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;
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;
if (wRight - bits <= PDP10.INT_MASK) {
this.regPS |= PDP10.PSFLAG.AROV;
}
}
}
wRight = 0;
@ -1931,14 +1939,18 @@ PDP10.opASHC = function(op, ac)
* 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;
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;
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.
*/
@ -2349,7 +2361,9 @@ 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;
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);
@ -2393,7 +2407,9 @@ PDP10.opPUSH = function(op, ac)
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;
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.
@ -2433,7 +2449,9 @@ PDP10.opPOP = function(op, ac)
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;
if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) {
this.regPS |= PDP10.PSFLAG.PDOV;
}
this.writeWord(ac, p);
};
@ -2459,7 +2477,9 @@ PDP10.opPOPJ = function(op, 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;
if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) {
this.regPS |= PDP10.PSFLAG.PDOV;
}
this.writeWord(ac, p);
this.setPC(pc & PDP10.ADDR_MASK);
};

View file

@ -121,8 +121,8 @@ function(a){this.w(a)},function(a){this.w(a)},function(a){this.w(a)},function(a)
xe.call(this,this.b))},function(a,b){this.g(this.b,xe.call(this,this.f(b)))},function(a,b){a=xe.call(this,this.f(this.b));this.g(this.b,a);b&&this.g(b,a)},function(a,b){this.g(b,pe.call(this,this.f(this.b)))},function(a,b){this.g(b,this.b)},function(a,b){this.g(this.b,pe.call(this,this.f(b)))},function(a,b){a=pe.call(this,this.f(this.b));this.g(this.b,a);b&&this.g(b,a)},function(a,b){this.g(b,we.call(this,this.f(b),this.f(this.b),!0))},function(a,b){this.g(b,we.call(this,this.f(b),this.b,!0))},function(a,
b){this.g(this.b,we.call(this,this.f(b),this.f(this.b),!0))},function(a,b){this.g(this.b,this.g(b,we.call(this,this.f(b),this.f(this.b),!0)))},function(a,b){this.g(b,we.call(this,this.f(b),this.f(this.b)));this.g(b+1&15,this.F)},function(a,b){this.g(b,we.call(this,this.f(b),this.b));this.g(b+1&15,this.F)},function(a,b){this.g(this.b,we.call(this,this.f(b),this.f(this.b)))},function(a,b){this.g(this.b,this.g(b,we.call(this,this.f(b),this.f(this.b))));this.g(b+1&15,this.F)},function(a,b){a=re.call(this,
this.f(b),0,this.f(this.b));0>a||(this.g(b,a),this.g(b+1&15,this.F))},function(a,b){a=re.call(this,this.f(b),0,this.b);0>a||(this.g(b,a),this.g(b+1&15,this.F))},function(a,b){a=re.call(this,this.f(b),0,this.f(this.b));0>a||this.g(this.b,a)},function(a,b){a=re.call(this,this.f(b),0,this.f(this.b));0>a||this.g(this.b,a)},function(a,b){a=this.f(b);var c=this.f(b+1&15),c=re.call(this,c,a,this.f(this.b));0>c||(this.g(b,c),this.g(b+1&15,this.F))},function(a,b){a=this.f(b);var c=this.f(b+1&15),c=re.call(this,
c,a,this.b);0>c||(this.g(b,c),this.g(b+1&15,this.F))},function(a,b){a=this.f(b);b=this.f(b+1&15);b=re.call(this,b,a,this.f(this.b));0>b||this.g(this.b,b)},function(a,b){a=this.f(b);var c=this.f(b+1&15),c=re.call(this,c,a,this.f(this.b));0>c||(this.g(b,this.g(this.b,c)),this.g(b+1&15,this.F))},function(a,b){var c=(this.b<<14>>14)%256;if(c){a=this.f(b);var d=a>z?-(C-a):a;0<c?(35<=c?(d=0>d?A:0,c=z):(d=d*Math.pow(2,c)%A,c=A-Math.pow(2,35-c)),a<=z?a+c>z&&(this.j|=131072):a-c<=z&&(this.j|=131072)):d=-35>=
c?0>d?-1:0:Math.trunc(d/Math.pow(2,-c));a=0>d?d+C:d;this.g(b,a)}},function(a,b){if(a=(this.b<<14>>14)%36){var c=this.f(b);0>a&&(a=36+a);c=c*Math.pow(2,a)%C+Math.trunc(c/Math.pow(2,36-a));this.g(b,c)}},function(a,b){if(a=(this.b<<14>>14)%256){var c=this.f(b),c=0<a?36<=a?0:c*Math.pow(2,a)%C:-36>=a?0:Math.trunc(c/Math.pow(2,-a));this.g(b,c)}},function(a,b){a=0;var c=this.f(b);if(c){for(;c<A;)a++,c*=2;G(this,this.b)}this.g(b+1&15,a)},function(a,b){if(a=(this.b<<14>>14)%256){var c,d=this.f(b),e=this.f(b+
c,a,this.b);0>c||(this.g(b,c),this.g(b+1&15,this.F))},function(a,b){a=this.f(b);b=this.f(b+1&15);b=re.call(this,b,a,this.f(this.b));0>b||this.g(this.b,b)},function(a,b){a=this.f(b);var c=this.f(b+1&15),c=re.call(this,c,a,this.f(this.b));0>c||(this.g(b,this.g(this.b,c)),this.g(b+1&15,this.F))},function(a,b){if(a=(this.b<<14>>14)%256){var c,d,e=this.f(b);0<a?(d=z,c=e<A?0:A,35>a&&(c+=e*Math.pow(2,a)%A,d=A-Math.pow(2,35-a)),e<A?e+d>z&&(this.j|=131072):e-d<A&&(this.j|=131072)):-35>=a?c=e<A?0:z:(c=Math.trunc(e/
Math.pow(2,-a)),e>z&&(d=C-Math.pow(2,36+a),c+=d));this.g(b,c)}},function(a,b){if(a=(this.b<<14>>14)%36){var c=this.f(b);0>a&&(a=36+a);c=c*Math.pow(2,a)%C+Math.trunc(c/Math.pow(2,36-a));this.g(b,c)}},function(a,b){if(a=(this.b<<14>>14)%256){var c=this.f(b),c=0<a?36<=a?0:c*Math.pow(2,a)%C:-36>=a?0:Math.trunc(c/Math.pow(2,-a));this.g(b,c)}},function(a,b){a=0;var c=this.f(b);if(c){for(;c<A;)a++,c*=2;G(this,this.b)}this.g(b+1&15,a)},function(a,b){if(a=(this.b<<14>>14)%256){var c,d=this.f(b),e=this.f(b+
1&15);if(0<a){var f=d;if(36<=a){if(0<d&&d<A||d>z&&d<B)this.j|=131072;if(71<=a){if(0<e&&e<A||e>z&&e<B)this.j|=131072;d=0}else d=e*Math.pow(2,a-35)%A,c=A-Math.pow(2,70-a),f<=z?e+c>z&&(this.j|=131072):e-c<=z&&(this.j|=131072);e=0;f>z&&(d+=A,e+=A)}else d=d*Math.pow(2,a)%A+Math.trunc(e%A/Math.pow(2,35-a)),e=e*Math.pow(2,a)%A,c=A-Math.pow(2,35-a),f<=z?f+c>z&&(this.j|=131072):(f-c<=z&&(this.j|=131072),d+=A,e+=A)}else-36>=a?(e=-72>=a?d>z?B:0:Math.trunc(d%A/Math.pow(2,-a-35)),d<=z?d=0:(d=B,e+=A)):(c=d>z?C-
Math.pow(2,36+a):0,e=Math.trunc(e%A/Math.pow(2,-a))+d%A*Math.pow(2,35+a)%A,d=Math.trunc(d/Math.pow(2,-a))+c,d>z&&(e+=A));this.g(b,d);this.g(b+1&15,e)}},function(a,b){if(a=(this.b<<14>>14)%72){var c=this.f(b),d=this.f(b+1&15),e=c;0>a&&(a=72+a);36>a?(c=c*Math.pow(2,a)%C+Math.trunc(d/Math.pow(2,36-a)),d=d*Math.pow(2,a)%C+Math.trunc(e/Math.pow(2,36-a))):(c=d*Math.pow(2,a-36)%C+Math.trunc(c/Math.pow(2,72-a)),d=e*Math.pow(2,a-36)%C+Math.trunc(d/Math.pow(2,72-a)));this.g(b,c);this.g(b+1&15,d)}},function(a,
b){if(a=(this.b<<14>>14)%256){var c=this.f(b),d=this.f(b+1&15);0<a?36<=a?(c=72<=a?0:d*Math.pow(2,a-36)%C,d=0):(c=c*Math.pow(2,a)%C+Math.trunc(d/Math.pow(2,36-a)),d=d*Math.pow(2,a)%C):-36>=a?(d=-72>=a?0:Math.trunc(c/Math.pow(2,-a-36)),c=0):(d=Math.trunc(d/Math.pow(2,-a))+c*Math.pow(2,36+a)%C,c=Math.trunc(c/Math.pow(2,-a)));this.g(b,c);this.g(b+1&15,d)}},L,function(a,b){a=this.f(b);this.g(b,this.f(this.b));this.g(this.b,a)},function(a,b){a=!1;for(var c=this.f(b),d=c/y|0,c=c&x;!a;)this.g(c,this.f(d)),

View file

@ -113,8 +113,8 @@ function(a){this.i(a)},function(a){this.i(a)},function(a){this.i(a)},function(a)
Vc.call(this,this.a))},function(a,b){this.c(this.a,Vc.call(this,this.b(b)))},function(a,b){a=Vc.call(this,this.b(this.a));this.c(this.a,a);b&&this.c(b,a)},function(a,b){this.c(b,Oc.call(this,this.b(this.a)))},function(a,b){this.c(b,this.a)},function(a,b){this.c(this.a,Oc.call(this,this.b(b)))},function(a,b){a=Oc.call(this,this.b(this.a));this.c(this.a,a);b&&this.c(b,a)},function(a,b){this.c(b,Uc.call(this,this.b(b),this.b(this.a),!0))},function(a,b){this.c(b,Uc.call(this,this.b(b),this.a,!0))},function(a,
b){this.c(this.a,Uc.call(this,this.b(b),this.b(this.a),!0))},function(a,b){this.c(this.a,this.c(b,Uc.call(this,this.b(b),this.b(this.a),!0)))},function(a,b){this.c(b,Uc.call(this,this.b(b),this.b(this.a)));this.c(b+1&15,this.o)},function(a,b){this.c(b,Uc.call(this,this.b(b),this.a));this.c(b+1&15,this.o)},function(a,b){this.c(this.a,Uc.call(this,this.b(b),this.b(this.a)))},function(a,b){this.c(this.a,this.c(b,Uc.call(this,this.b(b),this.b(this.a))));this.c(b+1&15,this.o)},function(a,b){a=S.call(this,
this.b(b),0,this.b(this.a));0>a||(this.c(b,a),this.c(b+1&15,this.o))},function(a,b){a=S.call(this,this.b(b),0,this.a);0>a||(this.c(b,a),this.c(b+1&15,this.o))},function(a,b){a=S.call(this,this.b(b),0,this.b(this.a));0>a||this.c(this.a,a)},function(a,b){a=S.call(this,this.b(b),0,this.b(this.a));0>a||this.c(this.a,a)},function(a,b){a=this.b(b);var c=this.b(b+1&15),c=S.call(this,c,a,this.b(this.a));0>c||(this.c(b,c),this.c(b+1&15,this.o))},function(a,b){a=this.b(b);var c=this.b(b+1&15),c=S.call(this,
c,a,this.a);0>c||(this.c(b,c),this.c(b+1&15,this.o))},function(a,b){a=this.b(b);b=this.b(b+1&15);b=S.call(this,b,a,this.b(this.a));0>b||this.c(this.a,b)},function(a,b){a=this.b(b);var c=this.b(b+1&15),c=S.call(this,c,a,this.b(this.a));0>c||(this.c(b,this.c(this.a,c)),this.c(b+1&15,this.o))},function(a,b){var c=(this.a<<14>>14)%256;if(c){a=this.b(b);var d=a>F?-(J-a):a;0<c?(35<=c?(d=0>d?G:0,c=F):(d=d*Math.pow(2,c)%G,c=G-Math.pow(2,35-c)),a<=F?a+c>F&&(this.g|=131072):a-c<=F&&(this.g|=131072)):d=-35>=
c?0>d?-1:0:Math.trunc(d/Math.pow(2,-c));a=0>d?d+J:d;this.c(b,a)}},function(a,b){if(a=(this.a<<14>>14)%36){var c=this.b(b);0>a&&(a=36+a);c=c*Math.pow(2,a)%J+Math.trunc(c/Math.pow(2,36-a));this.c(b,c)}},function(a,b){if(a=(this.a<<14>>14)%256){var c=this.b(b),c=0<a?36<=a?0:c*Math.pow(2,a)%J:-36>=a?0:Math.trunc(c/Math.pow(2,-a));this.c(b,c)}},function(a,b){a=0;var c=this.b(b);if(c){for(;c<G;)a++,c*=2;M(this,this.a)}this.c(b+1&15,a)},function(a,b){if(a=(this.a<<14>>14)%256){var c,d=this.b(b),e=this.b(b+
c,a,this.a);0>c||(this.c(b,c),this.c(b+1&15,this.o))},function(a,b){a=this.b(b);b=this.b(b+1&15);b=S.call(this,b,a,this.b(this.a));0>b||this.c(this.a,b)},function(a,b){a=this.b(b);var c=this.b(b+1&15),c=S.call(this,c,a,this.b(this.a));0>c||(this.c(b,this.c(this.a,c)),this.c(b+1&15,this.o))},function(a,b){if(a=(this.a<<14>>14)%256){var c,d,e=this.b(b);0<a?(d=F,c=e<G?0:G,35>a&&(c+=e*Math.pow(2,a)%G,d=G-Math.pow(2,35-a)),e<G?e+d>F&&(this.g|=131072):e-d<G&&(this.g|=131072)):-35>=a?c=e<G?0:F:(c=Math.trunc(e/
Math.pow(2,-a)),e>F&&(d=J-Math.pow(2,36+a),c+=d));this.c(b,c)}},function(a,b){if(a=(this.a<<14>>14)%36){var c=this.b(b);0>a&&(a=36+a);c=c*Math.pow(2,a)%J+Math.trunc(c/Math.pow(2,36-a));this.c(b,c)}},function(a,b){if(a=(this.a<<14>>14)%256){var c=this.b(b),c=0<a?36<=a?0:c*Math.pow(2,a)%J:-36>=a?0:Math.trunc(c/Math.pow(2,-a));this.c(b,c)}},function(a,b){a=0;var c=this.b(b);if(c){for(;c<G;)a++,c*=2;M(this,this.a)}this.c(b+1&15,a)},function(a,b){if(a=(this.a<<14>>14)%256){var c,d=this.b(b),e=this.b(b+
1&15);if(0<a){var f=d;if(36<=a){if(0<d&&d<G||d>F&&d<I)this.g|=131072;if(71<=a){if(0<e&&e<G||e>F&&e<I)this.g|=131072;d=0}else d=e*Math.pow(2,a-35)%G,c=G-Math.pow(2,70-a),f<=F?e+c>F&&(this.g|=131072):e-c<=F&&(this.g|=131072);e=0;f>F&&(d+=G,e+=G)}else d=d*Math.pow(2,a)%G+Math.trunc(e%G/Math.pow(2,35-a)),e=e*Math.pow(2,a)%G,c=G-Math.pow(2,35-a),f<=F?f+c>F&&(this.g|=131072):(f-c<=F&&(this.g|=131072),d+=G,e+=G)}else-36>=a?(e=-72>=a?d>F?I:0:Math.trunc(d%G/Math.pow(2,-a-35)),d<=F?d=0:(d=I,e+=G)):(c=d>F?J-
Math.pow(2,36+a):0,e=Math.trunc(e%G/Math.pow(2,-a))+d%G*Math.pow(2,35+a)%G,d=Math.trunc(d/Math.pow(2,-a))+c,d>F&&(e+=G));this.c(b,d);this.c(b+1&15,e)}},function(a,b){if(a=(this.a<<14>>14)%72){var c=this.b(b),d=this.b(b+1&15),e=c;0>a&&(a=72+a);36>a?(c=c*Math.pow(2,a)%J+Math.trunc(d/Math.pow(2,36-a)),d=d*Math.pow(2,a)%J+Math.trunc(e/Math.pow(2,36-a))):(c=d*Math.pow(2,a-36)%J+Math.trunc(c/Math.pow(2,72-a)),d=e*Math.pow(2,a-36)%J+Math.trunc(d/Math.pow(2,72-a)));this.c(b,c);this.c(b+1&15,d)}},function(a,
b){if(a=(this.a<<14>>14)%256){var c=this.b(b),d=this.b(b+1&15);0<a?36<=a?(c=72<=a?0:d*Math.pow(2,a-36)%J,d=0):(c=c*Math.pow(2,a)%J+Math.trunc(d/Math.pow(2,36-a)),d=d*Math.pow(2,a)%J):-36>=a?(d=-72>=a?0:Math.trunc(c/Math.pow(2,-a-36)),c=0):(d=Math.trunc(d/Math.pow(2,-a))+c*Math.pow(2,36+a)%J,c=Math.trunc(c/Math.pow(2,-a)));this.c(b,c);this.c(b+1&15,d)}},O,function(a,b){a=this.b(b);this.c(b,this.b(this.a));this.c(this.a,a)},function(a,b){a=!1;for(var c=this.b(b),d=c/E|0,c=c&C;!a;)this.c(c,this.b(d)),