From 6bd24c534790c83f456948b40b346f7532e79d94 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 5 Apr 2017 12:38:36 -0700 Subject: [PATCH] Fixed how index operands are assembled into PDP-10 instructions, which was an unexpectedly convoluted process (they are NOT masked to 4 bits, shifted left 18 bits, and OR'ed into the opcode; instead, they are computed as a 36-bit value whose left and right 18-bit halves are swapped and then ADDED to the opcode, which means that an instruction encoded with indexing may not end up using indexing at all, depending on where all those bits fall) --- modules/pdp10/lib/debugger.js | 26 +++++++++++++++++++++----- versions/pdpjs/1.34.3/pdp10-dbg.js | 4 ++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/modules/pdp10/lib/debugger.js b/modules/pdp10/lib/debugger.js index 737946e29..16a33eca1 100644 --- a/modules/pdp10/lib/debugger.js +++ b/modules/pdp10/lib/debugger.js @@ -1786,11 +1786,27 @@ class DebuggerPDP10 extends Debugger { opCode = -1; break; } - if (operand < 0 || operand > PDP10.OPCODE.X_MASK) { - operand &= PDP10.OPCODE.X_MASK; - if (MAXDEBUG) this.println("index (" + sOperand + ") truncated to " + this.toStrBase(operand)); - } - opCode += operand << PDP10.OPCODE.X_SHIFT; + /* + * Here's a fun tidbit from the April 1978 MACRO-10 manual, p. 4-5: + * + * NOTE: To assemble the index, MACRO places the index register address in a fullword of storage, + * swaps its halfwords, and then adds the swapped word to the instruction word. + * + * Which means that an instruction like this (where AC is zero): + * + * 8839 037653 205 00 0 00 400000 MOVSI AC,(1B<^O>) ;INITIALIZE AC + * + * produces an instruction that does NOT use indexing at all, even though it is coded as such. So my + * simplistic masking of the index operand with PDP10.OPCODE.X_MASK, while logical, was completely wrong: + * + * if (operand < 0 || operand > PDP10.OPCODE.X_MASK) { + * operand &= PDP10.OPCODE.X_MASK; + * if (MAXDEBUG) this.println("index (" + sOperand + ") truncated to " + this.toStrBase(operand)); + * } + * opCode += operand << PDP10.OPCODE.X_SHIFT; + */ + operand = PDP10.SWAP(this.truncate(operand, 36, true)); + opCode += operand; } sOperand = match[2]; diff --git a/versions/pdpjs/1.34.3/pdp10-dbg.js b/versions/pdpjs/1.34.3/pdp10-dbg.js index b2fc07501..386640c43 100644 --- a/versions/pdpjs/1.34.3/pdp10-dbg.js +++ b/versions/pdpjs/1.34.3/pdp10-dbg.js @@ -204,8 +204,8 @@ function xd(a,b,c){var d=-1;c||(d=a.v.f(b),2756==d>>23&&a.v.oa==b&&(b=ud(a.v,1)) function Jf(a,b,c,d){var e=Y(b.B),f=a.Na(b,1),g,h,k,l=0,p=f/Zb|0,q;for(q in Kf)if(g=Kf[q][p&q]){h=+q;p>>=6;switch(h){case 32512:k=Lf;l=p&3;break;case 32256:k=Mf;l=p&7;break;case 29248:k=Nf,l=(p&48)>>2|(p&6)>>1}break}k=k&&k[l]||"";"S"==k&&g>Of&&(k="B");k=Pf[g||0]+k;if(g){if(28700==h)h=f/$b&127,l=L(a,h,-1);else for(h=f>>23&15,l=L(a,h,-1),p=0;l&&p>18&15)&&(k+="("+L(a,f, -1)+")")}else k=Da(k,8)+qf(a,f);f=k;g="";h=L(a,e.B,18)+":";if(-1!==e.B&&-1!==b.B){do if(k=a.Na(e,1),g+=" "+qf(a,k),null==e.B)break;while(e.B!=b.B)}h+=Da(g,16)+f;c&&(h=Da(h,48)+";"+(c||""),h=a.v.A.Ua?h+("cycles="+hd(a.v).toString()+" cs="+n(a.v.Ha)):h+(null!=d?"="+d.toString():""));return h} function Rf(a,b,c,d,e){var f=-1,g,h;if(b){for(var k=b.toUpperCase(),l=0;lOf&&(J="B");if(k==Pf[h]+J){f=29248!=g?F:(F&3)<<1|(F&12)<<2;f=(D|f<<6)*Zb;break}}if(0<=f)break}if(0<=f)break}!(0>f)||c&&c.match(/^[0-9A-Z$%.?]/i)|| -(c=b+c,b="",f=0)}else c&&(f=g=0);if(0<=f&&c)for(k=c.split(","),2h||15h||127h||15h||262143f&&!e&&a.u("unknown instruction: "+b+" "+c);return f}function ef(a){var b,c;a.i=["bp"];if(a.N)for(b=1;b>>d.i],!1)}a.N=["br"];if(a.K)for(b=1;b>>d.i],!0);a.K=["bw"];a.xa=0;a.pa=0} +(c=b+c,b="",f=0)}else c&&(f=g=0);if(0<=f&&c)for(k=c.split(","),2h||127h||15h||262143f&&!e&&a.u("unknown instruction: "+b+" "+c);return f}function ef(a){var b,c;a.i=["bp"];if(a.N)for(b=1;b>>d.i],!1)}a.N=["br"];if(a.K)for(b=1;b>>d.i],!0);a.K=["bw"];a.xa=0;a.pa=0} m.Ra=function(a,b,c){var d=!0;c||Sf(this,a,b,!1,!0);if(a!=this.i){var e=hf(b);if(-1===e)this.u("invalid address: "+L(this,b.B,18)),d=!1;else{var f=this.G;f.b[e>>>f.i].Ra(e&16383,a==this.K)}}d&&(a.push(b),c?b.qa=!0:(Tf(this,a,a.length-1,"set"),ff(this)));return d};function Sf(a,b,c,d,e){var f=!1;c=hf(c);for(var g=1;g>>d.i],b==a.K));h.qa||ff(a);break}}return f} function Uf(a,b){for(var c=1;c