Assorted PDP-11 debugger changes
This commit is contained in:
parent
6984a97512
commit
1df54a338f
21 changed files with 499 additions and 276 deletions
|
|
@ -38,7 +38,7 @@ try {
|
|||
var asLines = sText.split('\n');
|
||||
for (var iLine = 0; iLine < asLines.length; iLine++) {
|
||||
var sLine = asLines[iLine];
|
||||
var match, re = /([^0-9a-z_-])(0[0-7]+)([^0-9a-z_])/gi;
|
||||
var match, re = /(^|[^0-9a-z_-]*)(0[0-7]+)([^0-9a-z_,]*|$)/gi;
|
||||
var iComment = sLine.indexOf("//");
|
||||
while (match = re.exec(sLine)) {
|
||||
if (iComment >= 0 && match.index > iComment) break;
|
||||
|
|
@ -47,7 +47,7 @@ try {
|
|||
console.log("found negative octal value (" + match[2] + "), skipping");
|
||||
continue;
|
||||
}
|
||||
var sReplace = match[1] + "0x" + n.toString(16).toUpperCase() + match[3] + " /*" + match[2] + "*/";
|
||||
var sReplace = match[1] + "0x" + ("0000" + n.toString(16).toUpperCase()).substr(-4) + match[3] + " /*" + match[2] + "*/";
|
||||
sLine = sLine.substr(0, match.index) + sReplace + sLine.substr(match.index + match[0].length);
|
||||
re.lastIndex = match.index + sReplace.length;
|
||||
asLines[iLine] = sLine;
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ BusPDP11.prototype.addMemory = function(addr, size, type)
|
|||
}
|
||||
|
||||
if (sizeLeft <= 0) {
|
||||
this.status(Math.floor(size / 1024) + "Kb " + MemoryPDP11.TYPE.NAMES[type] + " at " + str.toHexWord(addr));
|
||||
this.status(Math.floor(size / 1024) + "Kb " + MemoryPDP11.TYPE.NAMES[type] + " at " + str.toHexLong(addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ if (NODE) {
|
|||
* The CPUStatePDP11 class uses the following (parmsCPU) properties:
|
||||
*
|
||||
* model: a number (eg, 1170) that should match one of the PDP11.MODEL_* values
|
||||
* resetAddr: reset address (default is 0)
|
||||
*
|
||||
* This extends the CPU class and passes any remaining parmsCPU properties to the CPU class
|
||||
* constructor, along with a default speed (cycles per second) based on the specified (or default)
|
||||
|
|
@ -62,6 +63,7 @@ if (NODE) {
|
|||
function CPUStatePDP11(parmsCPU)
|
||||
{
|
||||
this.model = +parmsCPU['model'] || PDP11.MODEL_1170;
|
||||
this.resetAddr = parmsCPU['resetAddr'] || 0;
|
||||
|
||||
var nCyclesDefault = 0;
|
||||
switch(this.model) {
|
||||
|
|
@ -125,11 +127,45 @@ CPUStatePDP11.prototype.reset = function()
|
|||
*/
|
||||
CPUStatePDP11.prototype.initRegs = function()
|
||||
{
|
||||
// BEGIN pdp11.js:40:82
|
||||
/*
|
||||
* Instead of having separate flagC, flagZ and flagN variables, I would prefer to have only one: flagsCZN.
|
||||
* The C and N flags don't conflict; they are always bits 16 and 15 of the last 16-bit arithmetic result (or
|
||||
* bits 8 and 7 of the last 8-bit arithmetic result). The Z flag is a "bit" more complicated, because it's a
|
||||
* representation of bits 15-0 (or 7-0), which overlap the N flag bit. That overlap is fine after any given
|
||||
* arithmetic operation, because of the four possible N and Z combinations:
|
||||
*
|
||||
* N Z
|
||||
* - -
|
||||
* 0 0 Positive non-zero number
|
||||
* 0 1 Zero
|
||||
* 1 0 Negative non-zero number
|
||||
* 1 1 INVALID
|
||||
*
|
||||
* the fourth combination is an impossibility (the world of floating point numbers, with their NaNs, positive
|
||||
* and negative zeros, infinities, etc, is another story, which doesn't concern us here).
|
||||
*
|
||||
* The problem is that some intervening NON-arithmetic instruction (eg, SEN or SEZ) could be executed that sets
|
||||
* either N or Z independently, resulting in BOTH flags being set.
|
||||
*
|
||||
* One way to support that combination would be to define Z as the result of all non-sign bits. However,
|
||||
* that means that, after any arithmetic operation, we would have to propagate the sign bit of the result to
|
||||
* one or more other bits in flagsCZN; eg:
|
||||
*
|
||||
* flagsCZN = result | ((result & 0x8000) >> 1)
|
||||
* or:
|
||||
* flagsCZN = result | ((result & 0xffff)? 1 : 0)
|
||||
*
|
||||
* It's worth noting that all that extra work is actually required for only ONE 16-bit value: -32768 or 0x8000
|
||||
* (and ONE 8-bit value: -128 or 0x80), because all other negative numbers already have 1 or more lower bits set.
|
||||
*
|
||||
* A simpler approach would be to leave flagN independent, and only combine flagC and flagZ (into flagCZ).
|
||||
* Alternatively, we could combine flagC and flagN and leave flagZ independent; the choice is arbitrary. -JP
|
||||
*/
|
||||
this.flagC = 0x10000; // PSW C bit
|
||||
this.flagN = 0x8000; // PSW N bit
|
||||
this.flagV = 0x8000; // PSW V bit
|
||||
this.flagZ = 0xffff; // ~ PSW Z bit
|
||||
this.flagN = 0x8000; // PSW N bit
|
||||
|
||||
this.PSW = 0xf; // PSW other bits
|
||||
this.regsGen = [ // General R0 - R7
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
|
@ -137,7 +173,7 @@ CPUStatePDP11.prototype.initRegs = function()
|
|||
this.regsAlt = [ // Alternate R0 - R5
|
||||
0, 0, 0, 0, 0, 0
|
||||
];
|
||||
this.regsAltStack = [ // Alternate R6 (kernel, super, illegal, user)
|
||||
this.regsAltStack = [ // Alternate R6 stack pointers (kernel, super, illegal, user)
|
||||
0, 0, 0, 0
|
||||
];
|
||||
this.memory = []; // Main memory (words)
|
||||
|
|
@ -177,7 +213,6 @@ CPUStatePDP11.prototype.initRegs = function()
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
];
|
||||
this.debugPC = -1;
|
||||
// END pdp11.js:40:82
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -187,6 +222,7 @@ CPUStatePDP11.prototype.initRegs = function()
|
|||
*/
|
||||
CPUStatePDP11.prototype.resetRegs = function()
|
||||
{
|
||||
this.setPC(this.resetAddr);
|
||||
this.stackLimit = 0xff;
|
||||
this.CPU_Error = 0;
|
||||
this.interruptQueue = [];
|
||||
|
|
@ -660,14 +696,15 @@ CPUStatePDP11.prototype.panic = function(reason)
|
|||
/**
|
||||
* trap(vector, reason)
|
||||
*
|
||||
* trap() handles all the trap/abort functions. It reads the trap vector from kernel
|
||||
* trap() handles all the trap/abort functions. It reads the trap vector from kernel
|
||||
* D space, changes mode to reflect the new PSW and PC, and then pushes the old PSW and
|
||||
* PC onto the new mode stack. trap() returns a -1 which is passed up through function
|
||||
* PC onto the new mode stack. trap() returns a -1 which is passed up through function
|
||||
* calls to indicate that a trap/abort has occurred (suspend instruction processing).
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} vector
|
||||
* @param {number} reason
|
||||
* @return {number}
|
||||
*/
|
||||
CPUStatePDP11.prototype.trap = function(vector, reason)
|
||||
{
|
||||
|
|
@ -1320,7 +1357,6 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
|
|||
nDebugState = 1;
|
||||
}
|
||||
|
||||
// BEGIN pdp11.js:886:1936
|
||||
var instruction,
|
||||
src,
|
||||
dst,
|
||||
|
|
@ -2401,7 +2437,6 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
|
|||
}
|
||||
this.trapMask = 0;
|
||||
}
|
||||
// END pdp11.js:886:1936
|
||||
} while (this.nStepCycles > 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,28 +260,19 @@ if (DEBUGGER) {
|
|||
DebuggerPDP11.REG_PC = 7; // aka R7
|
||||
DebuggerPDP11.REG_PSW = 20;
|
||||
|
||||
DebuggerPDP11.MODE_REG = 0x0; // REGISTER (register is operand)
|
||||
DebuggerPDP11.MODE_REGD = 0x1; // REGISTER DEFERRED (register is address of operand)
|
||||
DebuggerPDP11.MODE_POSTINC = 0x2; // POST-INCREMENT (register is address of operand, register incremented)
|
||||
DebuggerPDP11.MODE_POSTINCD = 0x3; // POST-INCREMENT DEFERRED (register is address of address of operand, register incremented)
|
||||
DebuggerPDP11.MODE_PREDEC = 0x4; // PRE-DECREMENT (register decremented, register is address of operand)
|
||||
DebuggerPDP11.MODE_PREDECD = 0x5; // PRE-DECREMENT DEFERRED (register decremented, register is address of address of operand)
|
||||
DebuggerPDP11.MODE_INDEX = 0x6; // INDEX (register + next word is address of operand)
|
||||
DebuggerPDP11.MODE_INDEXD = 0x7; // INDEX DEFERRED (register + next word is address of address of operand)
|
||||
|
||||
/*
|
||||
* Operand descriptor masks; anything that's not covered by TYPE_SRC or TYPE_DST must be a TYPE_OTHER value.
|
||||
*/
|
||||
DebuggerPDP11.TYPE_DSTREG = 0x0007;
|
||||
DebuggerPDP11.TYPE_DSTMOD = 0x0038;
|
||||
DebuggerPDP11.TYPE_DST = (DebuggerPDP11.TYPE_DSTMOD | DebuggerPDP11.TYPE_DSTREG);
|
||||
DebuggerPDP11.TYPE_DSTMODE = 0x0038;
|
||||
DebuggerPDP11.TYPE_DST = (DebuggerPDP11.TYPE_DSTMODE | DebuggerPDP11.TYPE_DSTREG);
|
||||
DebuggerPDP11.TYPE_SRCREG = 0x01C0;
|
||||
DebuggerPDP11.TYPE_SRCMOD = 0x0E00;
|
||||
DebuggerPDP11.TYPE_SRC = (DebuggerPDP11.TYPE_SRCMOD | DebuggerPDP11.TYPE_SRCREG);
|
||||
DebuggerPDP11.TYPE_SRCMODE = 0x0E00;
|
||||
DebuggerPDP11.TYPE_SRC = (DebuggerPDP11.TYPE_SRCMODE | DebuggerPDP11.TYPE_SRCREG);
|
||||
DebuggerPDP11.TYPE_BRANCH = 0x1000;
|
||||
DebuggerPDP11.TYPE_DSTOFF = 0x2000;
|
||||
DebuggerPDP11.TYPE_DSTNUM3 = 0x3000; // DST 3-bit number (ie, just the DSTREG field)
|
||||
DebuggerPDP11.TYPE_DSTNUM6 = 0x6000; // DST 6-bit number (ie, both the DSTREG and DSTMOD fields)
|
||||
DebuggerPDP11.TYPE_DSTNUM6 = 0x6000; // DST 6-bit number (ie, both the DSTREG and DSTMODE fields)
|
||||
DebuggerPDP11.TYPE_OTHER = 0xF000;
|
||||
|
||||
/*
|
||||
|
|
@ -791,27 +782,27 @@ if (DEBUGGER) {
|
|||
};
|
||||
|
||||
/**
|
||||
* toHexOffset(off)
|
||||
* toStrOffset(off)
|
||||
*
|
||||
* @this {DebuggerPDP11}
|
||||
* @param {number|null|undefined} [off]
|
||||
* @return {string} the hex representation of off
|
||||
*/
|
||||
DebuggerPDP11.prototype.toHexOffset = function(off)
|
||||
DebuggerPDP11.prototype.toStrOffset = function(off)
|
||||
{
|
||||
return str.toHex(off, 4);
|
||||
return this.toStrBase(off);
|
||||
};
|
||||
|
||||
/**
|
||||
* toHexAddr(dbgAddr)
|
||||
* toStrAddr(dbgAddr)
|
||||
*
|
||||
* @this {DebuggerPDP11}
|
||||
* @param {DbgAddrPDP11} dbgAddr
|
||||
* @return {string} the hex representation of the address
|
||||
*/
|
||||
DebuggerPDP11.prototype.toHexAddr = function(dbgAddr)
|
||||
DebuggerPDP11.prototype.toStrAddr = function(dbgAddr)
|
||||
{
|
||||
return this.toHexOffset(dbgAddr.addr);
|
||||
return this.toStrOffset(dbgAddr.addr);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -871,7 +862,7 @@ if (DEBUGGER) {
|
|||
typePrev = block.type;
|
||||
var sType = MemoryPDP11.TYPE.NAMES[typePrev];
|
||||
if (block) {
|
||||
this.println(str.toHex(block.id) + " %" + str.toHex(i << this.bus.nBlockShift) + " %%" + str.toHex(block.addr) + " " + str.toHexWord(block.used) + " " + str.toHexWord(block.size) + " " + sType);
|
||||
this.println(str.toHex(block.id, 8) + " %" + str.toHex(i << this.bus.nBlockShift, 8) + " %%" + str.toHex(block.addr, 8) + " " + str.toHexWord(block.used) + " " + str.toHexWord(block.size) + " " + sType);
|
||||
}
|
||||
if (typePrev != MemoryPDP11.TYPE.NONE) typePrev = -1;
|
||||
cPrev = 0;
|
||||
|
|
@ -1080,7 +1071,7 @@ if (DEBUGGER) {
|
|||
DebuggerPDP11.prototype.message = function(sMessage, fAddress)
|
||||
{
|
||||
if (fAddress) {
|
||||
sMessage += " at " + this.toHexAddr(this.newAddr(this.cpu.getPC()));
|
||||
sMessage += " at " + this.toStrAddr(this.newAddr(this.cpu.getPC()));
|
||||
}
|
||||
|
||||
if (this.bitsMessage & MessagesPDP11.BUFFER) {
|
||||
|
|
@ -1657,7 +1648,7 @@ if (DEBUGGER) {
|
|||
if (aBreak != this.aBreakExec) {
|
||||
var addr = this.getAddr(dbgAddr);
|
||||
if (addr === PDP11.ADDR_INVALID) {
|
||||
this.println("invalid address: " + this.toHexAddr(dbgAddr));
|
||||
this.println("invalid address: " + this.toStrAddr(dbgAddr));
|
||||
fSuccess = false;
|
||||
} else {
|
||||
this.bus.addMemBreak(addr, aBreak == this.aBreakWrite);
|
||||
|
|
@ -1751,7 +1742,7 @@ if (DEBUGGER) {
|
|||
DebuggerPDP11.prototype.printBreakpoint = function(aBreak, i, sAction)
|
||||
{
|
||||
var dbgAddr = aBreak[i];
|
||||
this.println(aBreak[0] + ' ' + this.toHexAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' "' + dbgAddr.sCmd + '"') : '')));
|
||||
this.println(aBreak[0] + ' ' + this.toStrAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' "' + dbgAddr.sCmd + '"') : '')));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1929,16 +1920,16 @@ if (DEBUGGER) {
|
|||
sOperands += (sOperand || "???");
|
||||
}
|
||||
|
||||
var sBytes = "";
|
||||
var sLine = this.toHexAddr(dbgAddrOp) + ": ";
|
||||
var sOpcodes = "";
|
||||
var sLine = this.toStrAddr(dbgAddrOp) + ": ";
|
||||
if (dbgAddrOp.addr !== PDP11.ADDR_INVALID && dbgAddr.addr !== PDP11.ADDR_INVALID) {
|
||||
do {
|
||||
sBytes += str.toHex(this.getByte(dbgAddrOp, 1), 2);
|
||||
sOpcodes += this.toStrBase(this.getWord(dbgAddrOp, true));
|
||||
if (dbgAddrOp.addr == null) break;
|
||||
} while (dbgAddrOp.addr != dbgAddr.addr);
|
||||
}
|
||||
|
||||
sLine += str.pad(sBytes, 10);
|
||||
sLine += str.pad(sOpcodes, 10);
|
||||
sLine += str.pad(sOpName, 7);
|
||||
if (sOperands) sLine += ' ' + sOperands;
|
||||
|
||||
|
|
@ -2008,14 +1999,14 @@ if (DEBUGGER) {
|
|||
* Note that opcodes that specify only REG bits in the type mask (ie, no MOD bits)
|
||||
* will automatically default to MODE_REG below.
|
||||
*/
|
||||
switch(mode & DebuggerPDP11.TYPE_DSTMOD) {
|
||||
case DebuggerPDP11.MODE_REG: // 0x0: REGISTER
|
||||
switch(mode & DebuggerPDP11.TYPE_DSTMODE) {
|
||||
case PDP11.OPMODE.REG: // 0x0: REGISTER
|
||||
sOperand = "R" + reg;
|
||||
break;
|
||||
case DebuggerPDP11.MODE_REGD: // 0x1: REGISTER DEFERRED
|
||||
case PDP11.OPMODE.REGD: // 0x1: REGISTER DEFERRED
|
||||
sOperand = "@R" + reg;
|
||||
break;
|
||||
case DebuggerPDP11.MODE_POSTINC: // 0x2: POST-INCREMENT
|
||||
case PDP11.OPMODE.POSTINC: // 0x2: POST-INCREMENT
|
||||
if (reg < 7) {
|
||||
sOperand = "(R" + reg + ")+";
|
||||
} else {
|
||||
|
|
@ -2026,7 +2017,7 @@ if (DEBUGGER) {
|
|||
sOperand = "#" + str.toHexWord(wIndex);
|
||||
}
|
||||
break;
|
||||
case DebuggerPDP11.MODE_POSTINCD: // 0x3: POST-INCREMENT DEFERRED
|
||||
case PDP11.OPMODE.POSTINCD: // 0x3: POST-INCREMENT DEFERRED
|
||||
if (reg < 7) {
|
||||
sOperand = "@(R" + reg + ")+";
|
||||
} else {
|
||||
|
|
@ -2037,20 +2028,20 @@ if (DEBUGGER) {
|
|||
sOperand = "@#" + str.toHexWord(wIndex);
|
||||
}
|
||||
break;
|
||||
case DebuggerPDP11.MODE_PREDEC: // 0x4: PRE-DECREMENT
|
||||
case PDP11.OPMODE.PREDEC: // 0x4: PRE-DECREMENT
|
||||
sOperand = "-(R" + reg + ")";
|
||||
break;
|
||||
case DebuggerPDP11.MODE_PREDECD: // 0x5: PRE-DECREMENT DEFERRED
|
||||
case PDP11.OPMODE.PREDECD: // 0x5: PRE-DECREMENT DEFERRED
|
||||
sOperand = "@-R(" + reg + ")";
|
||||
break;
|
||||
case DebuggerPDP11.MODE_INDEX: // 0x6: INDEX
|
||||
case PDP11.OPMODE.INDEX: // 0x6: INDEX
|
||||
wIndex = this.getWord(dbgAddr, true);
|
||||
/*
|
||||
* When using R7 (aka PC), INDEX is known as RELATIVE
|
||||
*/
|
||||
sOperand = str.toHexWord(wIndex) + (reg < 7? "(R" + reg + ")" : "(PC)");
|
||||
break;
|
||||
case DebuggerPDP11.MODE_INDEXD: // 0x7: INDEX DEFERRED
|
||||
case PDP11.OPMODE.INDEXD: // 0x7: INDEX DEFERRED
|
||||
wIndex = this.getWord(dbgAddr, true);
|
||||
/*
|
||||
* When using R7 (aka PC), INDEX DEFERRED is known as RELATIVE DEFERRED
|
||||
|
|
@ -2125,16 +2116,16 @@ if (DEBUGGER) {
|
|||
|
||||
if (iReg < 8) {
|
||||
sReg = (iReg < 6? ("R" + iReg) : (iReg == 6? "SP" : "PC"));
|
||||
sReg += '=' + str.toHex(cpu.regsGen[iReg], 4);
|
||||
sReg += '=' + this.toStrBase(cpu.regsGen[iReg]);
|
||||
}
|
||||
else if (iReg < 13) {
|
||||
sReg = "A" + (iReg - 8) + '=' + str.toHex(cpu.regsAlt[iReg - 8], 4);
|
||||
sReg = "A" + (iReg - 8) + '=' + this.toStrBase(cpu.regsAlt[iReg - 8]);
|
||||
}
|
||||
else if (iReg >= 16 && iReg < 20) {
|
||||
sReg = "S" + (iReg - 16) + '=' + str.toHex(cpu.regsAltStack[iReg - 16], 4);
|
||||
sReg = "S" + (iReg - 16) + '=' + this.toStrBase(cpu.regsAltStack[iReg - 16]);
|
||||
}
|
||||
else if (iReg == DebuggerPDP11.REG_PSW) {
|
||||
sReg = "PS=" + str.toHex(cpu.getPSW(), 4);
|
||||
sReg = "PS=" + this.toStrBase(cpu.getPSW());
|
||||
}
|
||||
if (sReg) sReg += ' ';
|
||||
return sReg;
|
||||
|
|
@ -2299,7 +2290,7 @@ if (DEBUGGER) {
|
|||
if (offSymbol === undefined) continue;
|
||||
var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];
|
||||
if (sSymbolOrig) sSymbol = sSymbolOrig;
|
||||
this.println(this.toHexOffset(offSymbol) + ' ' + sSymbol);
|
||||
this.println(this.toStrOffset(offSymbol) + ' ' + sSymbol);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2461,7 +2452,7 @@ if (DEBUGGER) {
|
|||
|
||||
this.dbgAddrAssemble = dbgAddr;
|
||||
if (asArgs[2] === undefined) {
|
||||
this.println("begin assemble at " + this.toHexAddr(dbgAddr));
|
||||
this.println("begin assemble at " + this.toStrAddr(dbgAddr));
|
||||
this.fAssemble = true;
|
||||
this.cpu.updateCPU();
|
||||
return;
|
||||
|
|
@ -2561,7 +2552,7 @@ if (DEBUGGER) {
|
|||
return;
|
||||
if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))
|
||||
return;
|
||||
this.println("breakpoint missing: " + this.toHexAddr(dbgAddr));
|
||||
this.println("breakpoint missing: " + this.toStrAddr(dbgAddr));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2706,7 +2697,7 @@ if (DEBUGGER) {
|
|||
while (cLines-- && cb > 0) {
|
||||
var data = 0, iByte = 0, i;
|
||||
var sData = "", sChars = "";
|
||||
sAddr = this.toHexAddr(dbgAddr);
|
||||
sAddr = this.toStrAddr(dbgAddr);
|
||||
for (i = 16; i > 0 && cb > 0; i--) {
|
||||
var b = this.getByte(dbgAddr, 1);
|
||||
data |= (b << (iByte++ << 3));
|
||||
|
|
@ -2767,7 +2758,7 @@ if (DEBUGGER) {
|
|||
this.println("warning: " + str.toHex(vNew) + " exceeds " + size + "-byte value");
|
||||
}
|
||||
var vOld = fnGet.call(this, dbgAddr);
|
||||
this.println("changing " + this.toHexAddr(dbgAddr) + " from " + str.toHex(vOld, cch, true) + " to " + str.toHex(vNew, cch, true));
|
||||
this.println("changing " + this.toStrAddr(dbgAddr) + " from " + str.toHex(vOld, cch, true) + " to " + str.toHex(vNew, cch, true));
|
||||
fnSet.call(this, dbgAddr, vNew, size);
|
||||
}
|
||||
};
|
||||
|
|
@ -2896,7 +2887,7 @@ if (DEBUGGER) {
|
|||
sDelta = "";
|
||||
nDelta = dbgAddr.addr - aSymbol[1];
|
||||
if (nDelta) sDelta = " + " + str.toHexWord(nDelta);
|
||||
s = aSymbol[0] + " (" + this.toHexOffset(aSymbol[1]) + ')' + sDelta;
|
||||
s = aSymbol[0] + " (" + this.toStrOffset(aSymbol[1]) + ')' + sDelta;
|
||||
if (fPrint) this.println(s);
|
||||
sSymbol = s;
|
||||
}
|
||||
|
|
@ -2904,7 +2895,7 @@ if (DEBUGGER) {
|
|||
sDelta = "";
|
||||
nDelta = aSymbol[5] - dbgAddr.addr;
|
||||
if (nDelta) sDelta = " - " + str.toHexWord(nDelta);
|
||||
s = aSymbol[4] + " (" + this.toHexOffset(aSymbol[5]) + ')' + sDelta;
|
||||
s = aSymbol[4] + " (" + this.toStrOffset(aSymbol[5]) + ')' + sDelta;
|
||||
if (fPrint) this.println(s);
|
||||
if (!sSymbol) sSymbol = s;
|
||||
}
|
||||
|
|
@ -3015,6 +3006,18 @@ if (DEBUGGER) {
|
|||
DebuggerPDP11.prototype.doOptions = function(asArgs)
|
||||
{
|
||||
switch (asArgs[1]) {
|
||||
case "base":
|
||||
if (asArgs[2]) {
|
||||
var nBase = +asArgs[2];
|
||||
if (nBase == 8 || nBase == 10 || nBase == 16) {
|
||||
this.nBase = nBase;
|
||||
} else {
|
||||
this.println("invalid base: " + nBase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.println("default base: " + this.nBase);
|
||||
break;
|
||||
case "cs":
|
||||
var nCycles;
|
||||
if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion
|
||||
|
|
@ -3049,6 +3052,7 @@ if (DEBUGGER) {
|
|||
|
||||
case "?":
|
||||
this.println("debugger options:");
|
||||
this.println("\tbase #\t\tset default base to #");
|
||||
this.println("\tcs int #\tset checksum cycle interval to #");
|
||||
this.println("\tcs start #\tset checksum cycle start count to #");
|
||||
this.println("\tcs stop #\tset checksum cycle stop count to #");
|
||||
|
|
@ -3139,7 +3143,7 @@ if (DEBUGGER) {
|
|||
|
||||
if (fInstruction) {
|
||||
this.dbgAddrNextCode = this.newAddr(cpu.getPC());
|
||||
this.doUnassemble(this.toHexAddr(this.dbgAddrNextCode));
|
||||
this.doUnassemble(this.toStrAddr(this.dbgAddrNextCode));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -3300,7 +3304,7 @@ if (DEBUGGER) {
|
|||
var nFrames = 10, cFrames = 0;
|
||||
var dbgAddrCall = this.newAddr();
|
||||
var dbgAddrStack = this.newAddr(this.cpu.getSP());
|
||||
this.println("stack trace for " + this.toHexAddr(dbgAddrStack));
|
||||
this.println("stack trace for " + this.toStrAddr(dbgAddrStack));
|
||||
|
||||
while (cFrames < nFrames) {
|
||||
var sCall = null, sCallPrev = null, cTests = 256;
|
||||
|
|
@ -3326,7 +3330,7 @@ if (DEBUGGER) {
|
|||
var a = sCall.match(/[0-9A-F]+$/);
|
||||
if (a) sSymbol = this.doList(a[0]);
|
||||
}
|
||||
sCall = str.pad(sCall, 50) + " ;" + (sSymbol || "stack=" + this.toHexAddr(dbgAddrStack)); // + " return=" + this.toHexAddr(dbgAddrCall));
|
||||
sCall = str.pad(sCall, 50) + " ;" + (sSymbol || "stack=" + this.toStrAddr(dbgAddrStack)); // + " return=" + this.toStrAddr(dbgAddrCall));
|
||||
this.println(sCall);
|
||||
sCallPrev = sCall;
|
||||
cFrames++;
|
||||
|
|
@ -3489,7 +3493,7 @@ if (DEBUGGER) {
|
|||
try {
|
||||
if (!sCmd.length || sCmd == "end") {
|
||||
if (this.fAssemble) {
|
||||
this.println("ended assemble at " + this.toHexAddr(this.dbgAddrAssemble));
|
||||
this.println("ended assemble at " + this.toStrAddr(this.dbgAddrAssemble));
|
||||
this.dbgAddrNextCode = this.dbgAddrAssemble;
|
||||
this.fAssemble = false;
|
||||
}
|
||||
|
|
@ -3514,7 +3518,7 @@ if (DEBUGGER) {
|
|||
if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {
|
||||
|
||||
if (this.fAssemble) {
|
||||
sCmd = "a " + this.toHexAddr(this.dbgAddrAssemble) + ' ' + sCmd;
|
||||
sCmd = "a " + this.toStrAddr(this.dbgAddrAssemble) + ' ' + sCmd;
|
||||
}
|
||||
|
||||
var asArgs = this.shiftArgs(sCmd.replace(/ +/g, ' ').split(' '));
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ var PDP11 = {
|
|||
*/
|
||||
ADDR_INVALID: -1,
|
||||
/*
|
||||
* Processor Modes
|
||||
* Processor modes
|
||||
*/
|
||||
MODE: {
|
||||
KERNEL: 0x0,
|
||||
|
|
@ -163,6 +163,19 @@ var PDP11 = {
|
|||
INTR: 0x00ff, // mask for 8 bits, representing interrupt levels 0-7
|
||||
HALT: 0x0100 // halt requested; see opHLT()
|
||||
},
|
||||
/*
|
||||
* Opcode modes
|
||||
*/
|
||||
OPMODE: {
|
||||
REG: 0x0, // REGISTER (register is operand)
|
||||
REGD: 0x1, // REGISTER DEFERRED (register is address of operand)
|
||||
POSTINC: 0x2, // POST-INCREMENT (register is address of operand, register incremented)
|
||||
POSTINCD: 0x3, // POST-INCREMENT DEFERRED (register is address of address of operand, register incremented)
|
||||
PREDEC: 0x4, // PRE-DECREMENT (register decremented, register is address of operand)
|
||||
PREDECD: 0x5, // PRE-DECREMENT DEFERRED (register decremented, register is address of address of operand)
|
||||
INDEX: 0x6, // INDEX (register + next word is address of operand)
|
||||
INDEXD: 0x7 // INDEX DEFERRED (register + next word is address of address of operand)
|
||||
},
|
||||
/*
|
||||
* Opcode definitions
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -204,28 +204,39 @@ ROMPDP11.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
|||
|
||||
Component.addMachineResource(this.idMachine, sURL, sROMData);
|
||||
|
||||
var i;
|
||||
if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") {
|
||||
try {
|
||||
/*
|
||||
* The most likely source of any exception will be here: parsing the JSON-encoded ROM data.
|
||||
* The most likely source of any exception will be here: parsing the JSON-encoded ROM.
|
||||
*/
|
||||
var a, ib;
|
||||
var rom = eval("(" + sROMData + ")");
|
||||
var ab = rom['bytes'];
|
||||
var adw = rom['data'];
|
||||
|
||||
if (ab) {
|
||||
this.abROM = ab;
|
||||
if (a = rom['bytes']) {
|
||||
this.abROM = a;
|
||||
}
|
||||
else if (adw) {
|
||||
else if (a = rom['words']) {
|
||||
/*
|
||||
* Convert all the DWORDs into BYTEs, so that subsequent code only has to deal with abROM.
|
||||
* Convert all WORDs into BYTEs, so that subsequent code only has to deal with abROM.
|
||||
*/
|
||||
this.abROM = new Array(adw.length * 4);
|
||||
for (var idw = 0, ib = 0; idw < adw.length; idw++) {
|
||||
this.abROM[ib++] = adw[idw] & 0xff;
|
||||
this.abROM[ib++] = (adw[idw] >> 8) & 0xff;
|
||||
this.abROM[ib++] = (adw[idw] >> 16) & 0xff;
|
||||
this.abROM[ib++] = (adw[idw] >> 24) & 0xff;
|
||||
this.abROM = new Array(a.length * 2);
|
||||
for (i = 0, ib = 0; i < a.length; i++) {
|
||||
this.abROM[ib++] = a[i] & 0xff;
|
||||
this.abROM[ib++] = (a[i] >> 8) & 0xff;
|
||||
this.assert(!(a[i] & ~0xffff));
|
||||
}
|
||||
}
|
||||
else if (a = rom['data']) {
|
||||
/*
|
||||
* Convert all DWORDs into BYTEs, so that subsequent code only has to deal with abROM.
|
||||
*/
|
||||
this.abROM = new Array(a.length * 4);
|
||||
for (i = 0, ib = 0; i < a.length; i++) {
|
||||
this.abROM[ib++] = a[i] & 0xff;
|
||||
this.abROM[ib++] = (a[i] >> 8) & 0xff;
|
||||
this.abROM[ib++] = (a[i] >> 16) & 0xff;
|
||||
this.abROM[ib++] = (a[i] >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -255,7 +266,7 @@ ROMPDP11.prototype.doneLoad = function(sURL, sROMData, nErrorCode)
|
|||
var sHexData = sROMData.replace(/\n/gm, " ").replace(/ +$/, "");
|
||||
var asHexData = sHexData.split(" ");
|
||||
this.abROM = new Array(asHexData.length);
|
||||
for (var i = 0; i < asHexData.length; i++) {
|
||||
for (i = 0; i < asHexData.length; i++) {
|
||||
this.abROM[i] = str.parseInt(asHexData[i], 16);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue