Debuggers need to handle negative values a bit better
This commit is contained in:
parent
e9d2b0ec25
commit
70cd954974
7 changed files with 204 additions and 161 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" : "");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue