Debuggers need to handle negative values a bit better

This commit is contained in:
Jeff 2017-03-08 16:48:25 -08:00 committed by Jeff Parsons
commit 70cd954974
7 changed files with 204 additions and 161 deletions

View file

@ -90,6 +90,7 @@ class DebuggerPDP10 extends Debugger {
*/
this.fInit = false;
this.fParens = true;
this.nBusWidth = 18; // default value, updated by initBus()
/*
* Most commands that require an address call parseAddr(), and if a dbgAddr parameter is supplied
@ -315,6 +316,7 @@ class DebuggerPDP10 extends Debugger {
this.cmp = cmp;
this.cpu = cpu;
this.panel = cmp.panel;
this.nBusWidth = bus.getWidth();
/*
* Re-initialize Debugger message support if necessary
@ -527,6 +529,7 @@ class DebuggerPDP10 extends Debugger {
addr = this.parseExpression(sAddr, fPrint);
}
if (addr != null) {
addr = this.validateWord(addr, this.nBusWidth);
this.setAddr(dbgAddr, addr, fPhysical, nBase);
}
return dbgAddr;
@ -549,6 +552,31 @@ class DebuggerPDP10 extends Debugger {
}
}
/**
* validateWord(w, bits)
*
* @this {DebuggerPDP10}
* @param {number} w
* @param {number} [bits]
* @return {number}
*/
validateWord(w, bits = 36)
{
/*
* Although it's expected that most callers will supply unsigned 36-bit values, we're nice about
* converting any signed values to their unsigned (two's complement) counterpart, provided they are
* within the acceptable range. Any values outside that range will be dealt with afterward.
*/
if (w < 0 && w >= -PDP10.MIN_NEG36) {
w += PDP10.WORD_LIMIT;
}
var value = Math.trunc(Math.abs(w)) % Math.pow(2, bits);
if (DEBUG && w !== value) {
this.println("validateWord(" + Str.toOct(w) + "): out of range, truncated to " + Str.toOct(value));
}
return value;
}
/**
* incAddr(dbgAddr, inc)
*
@ -2780,14 +2808,12 @@ class DebuggerPDP10 extends Debugger {
var dbgAddr = this.parseAddr(sAddr, this.dbgAddrData);
if (!dbgAddr) return;
for (var i = 2; i < asArgs.length; i++) {
var vNew = this.parseExpression(asArgs[i]);
if (vNew === undefined) {
this.println("unknown value: " + asArgs[i]);
break;
}
this.println("changing " + this.toStrAddr(dbgAddr) + " from " + this.toStrWord(fnGet.call(this, dbgAddr)) + " to " + this.toStrWord(vNew));
var w = this.parseExpression(asArgs[i]);
if (w === undefined) break;
w = this.validateWord(w);
this.println("changing " + this.toStrAddr(dbgAddr) + " from " + this.toStrWord(fnGet.call(this, dbgAddr)) + " to " + this.toStrWord(w));
//noinspection JSUnresolvedFunction
fnSet.call(this, dbgAddr, vNew, 1);
fnSet.call(this, dbgAddr, w, 1);
}
}
@ -3679,7 +3705,7 @@ class DebuggerPDP10 extends Debugger {
}
}
} catch(e) {
this.println("debugger error: " + (e.stack || e.message));
this.println("Debugger " + (e.stack || e.message));
result = false;
}
return result;

View file

@ -1357,7 +1357,7 @@ class Int36 {
}
var value = Math.trunc(Math.abs(num)) % Math.pow(2, bits);
if (DEBUG && num !== value) {
console.log("Int36.validate(" + Int36.octal(num) + " out of range, truncated to " + Int36.octal(value) + ")");
console.log("Int36.validate(" + Int36.octal(num) + "): out of range, truncated to " + Int36.octal(value));
}
return value;
}

View file

@ -44,10 +44,10 @@ class Str {
*/
static isValidInt(s, base)
{
if (!base || base == 10) return s.match(/^[0-9]+$/) !== null;
if (base == 16) return s.match(/^[0-9a-f]+$/i) !== null;
if (base == 8) return s.match(/^[0-7]+$/) !== null;
if (base == 2) return s.match(/^[01]+$/) !== null;
if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;
if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;
if (base == 8) return s.match(/^-?[0-7]+$/) !== null;
if (base == 2) return s.match(/^-?[01]+$/) !== null;
return false;
}
@ -165,9 +165,9 @@ class Str {
* values displayed differently.
*/
var s = "";
if (n == null || isNaN(n)) {
while (cch-- > 0) s = '?' + s;
} else {
if (isNaN(n)) {
n = null;
} else if (n != null) {
/*
* Callers that produced an input by dividing by a power of two rather than shifting (in order
* to access more than 32 bits) may produce a fractional result, which ordinarily we would simply
@ -175,6 +175,20 @@ class Str {
* this value as a sign-extension.
*/
if (n < 0 && n > -1) n = -1;
/*
* Negative values should be two's complemented according to the number of digits; for example,
* 12 octal digits implies an upper limit 8^12.
*/
if (n < 0) {
n += Math.pow(radix, cch);
}
if (n < 0 || n >= Math.pow(radix, cch)) {
n = null;
}
}
if (n == null) {
while (cch-- > 0) s = '?' + s;
} else {
while (cch-- > 0) {
var d = n % radix;
d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);
@ -266,7 +280,7 @@ class Str {
if (cch) {
if (cch > 12) cch = 12;
} else {
cch = (n & ~0xffffff)? 11 : ((n & ~0xffff)? 8 : 6);
cch = (n & ~0xffffff)? 12 : ((n & ~0xffff)? 8 : 6);
}
return Str.toBase(n, 8, cch, fPrefix? "0o" : "");
}