Fixed Debugger memory editing and register handling, tidied up some flag operations, and removed more now-unnecessary address checks in cpustate

This commit is contained in:
Jeff 2016-09-29 09:11:25 -07:00 committed by Jeff Parsons
commit 44a2ec9f03
9 changed files with 576 additions and 519 deletions

View file

@ -39,18 +39,19 @@ if (NODE) {
/*
* Decoding starts at the bottom of this file, in op1170(). The basic decoding approach is to
* dispatch on the top 4 bits of the opcode, and if further decoding is required, then dispatch on
* the next 4 bits, and so on (although some of the intermediate levels dispatch only on 2 bits).
* dispatch on the top 4 bits of the opcode, and if further decoding is required, the dispatched
* function will dispatch on the next 4 bits, and so on (although some of the intermediate levels
* dispatch only on 2 bits, which could also handled with a switch statement).
*
* Eventually, every opcode should end up either in an opXXX() function or opUndefined(). For
* opcodes that perform a simple read and/or write operation, the entire functionality is handled
* by the opXXX() function. For opcodes that perform a more extensive read/modify/write operation
* opcodes that perform a simple read and/or write operation, the entire operation is handled by
* the opXXX() function. For opcodes that perform a more extensive read/modify/write operation
* (also known as an update operation), those opXXX() functions usually rely on a corresponding
* fnXXX() helper function.
*
* For example, opADD() passes the helper function fnADD() to the appropriate update method. This
* allows the update method to perform the entire read/modify/write operation, because the modification
* is handled by the helper function.
* is performed internally via the helper function.
*/
/**
@ -94,7 +95,7 @@ PDP11.fnADDB = function(src, dst)
PDP11.fnASL = function(src, dst)
{
var result = dst << 1;
this.updateLogFlags(result);
this.updateShiftFlags(result);
return result & 0xffff;
};
@ -109,7 +110,7 @@ PDP11.fnASL = function(src, dst)
PDP11.fnASLB = function(src, dst)
{
var result = dst << 1;
this.updateLogFlags(result << 8);
this.updateShiftFlags(result << 8);
return result & 0xff;
};
@ -124,7 +125,7 @@ PDP11.fnASLB = function(src, dst)
PDP11.fnASR = function(src, dst)
{
var result = (dst & 0x8000) | (dst >> 1) | (dst << 16);
this.updateLogFlags(result);
this.updateShiftFlags(result);
return result & 0xffff;
};
@ -139,7 +140,7 @@ PDP11.fnASR = function(src, dst)
PDP11.fnASRB = function(src, dst)
{
var result = (dst & 0x800) | (dst >> 1) | (dst << 8);
this.updateLogFlags(result << 8);
this.updateShiftFlags(result << 8);
return result & 0xff;
};
@ -214,7 +215,7 @@ PDP11.fnBISB = function(src, dst)
PDP11.fnCOM = function(src, dst)
{
var result = ~dst | 0x10000;
this.updateNZCFlags(result);
this.updateAllFlags(result);
return result & 0xffff;
};
@ -229,7 +230,7 @@ PDP11.fnCOM = function(src, dst)
PDP11.fnCOMB = function(src, dst)
{
var result = ~dst | 0x100;
this.updateNZCFlags(result << 8);
this.updateAllFlags(result << 8);
return result & 0xff;
};
@ -307,7 +308,7 @@ PDP11.fnNEG = function(src, dst)
/*
* If the sign bit of both dst and result are set, the original value must have been 0x8000, triggering overflow.
*/
this.updateNZCFlags(result, result & dst & 0x8000);
this.updateAllFlags(result, result & dst & 0x8000);
return result & 0xffff;
};
@ -325,7 +326,7 @@ PDP11.fnNEGB = function(src, dst)
/*
* If the sign bit of both dst and result are set, the original value must have been 0x80, which triggers overflow.
*/
this.updateNZCFlags(result << 8, (result & dst & 0x80) << 8);
this.updateAllFlags(result << 8, (result & dst & 0x80) << 8);
return result & 0xff;
};
@ -340,7 +341,7 @@ PDP11.fnNEGB = function(src, dst)
PDP11.fnROL = function(src, dst)
{
var result = (dst << 1) | ((this.flagC >> 16) & 1);
this.updateLogFlags(result);
this.updateShiftFlags(result);
return result & 0xffff;
};
@ -355,7 +356,7 @@ PDP11.fnROL = function(src, dst)
PDP11.fnROLB = function(src, dst)
{
var result = (dst << 1) | ((this.flagC >> 16) & 1);
this.updateLogFlags(result << 8);
this.updateShiftFlags(result << 8);
return result & 0xff;
};
@ -370,7 +371,7 @@ PDP11.fnROLB = function(src, dst)
PDP11.fnROR = function(src, dst)
{
var result = (((this.flagC & 0x10000) | dst) >> 1) | (dst << 16);
this.updateLogFlags(result);
this.updateShiftFlags(result);
return result & 0xffff;
};
@ -385,7 +386,7 @@ PDP11.fnROR = function(src, dst)
PDP11.fnRORB = function(src, dst)
{
var result = ((((this.flagC & 0x10000) >> 8) | dst) >> 1) | (dst << 8);
this.updateLogFlags(result << 8);
this.updateShiftFlags(result << 8);
return result & 0xff;
};
@ -867,7 +868,7 @@ PDP11.opBVS = function(opCode)
*/
PDP11.opCLR = function(opCode)
{
this.updateNZCFlags(this.writeWordByMode(opCode, 0));
this.updateAllFlags(this.writeWordByMode(opCode, 0));
this.nStepCycles -= 1;
};
@ -879,7 +880,7 @@ PDP11.opCLR = function(opCode)
*/
PDP11.opCLRB = function(opCode)
{
this.updateNZCFlags(this.writeByteByMode(opCode, 0));
this.updateAllFlags(this.writeByteByMode(opCode, 0));
this.nStepCycles -= 1;
};
@ -1040,6 +1041,9 @@ PDP11.opDECB = function(opCode)
*/
PDP11.opDIV = function(opCode)
{
/*
* TODO: Review and determine if flag updates can be encapsulated in an updateDivFlags() function.
*/
var src = this.readWordByMode(opCode);
if (!src) {
this.flagN = 0; // NZVC
@ -1159,7 +1163,7 @@ PDP11.opJSR = function(opCode)
*/
PDP11.opMARK = function(opCode)
{
var addr = (this.regsGen[7] + ((opCode & 0x3F) << 1)) & 0xffff;
var addr = (this.regsGen[PDP11.REG.PC] + ((opCode & 0x3F) << 1)) & 0xffff;
var src = this.readWordFromVirtual(addr | 0x10000);
this.setPC(this.regsGen[5]);
this.setSP(addr + 2);
@ -1264,10 +1268,7 @@ PDP11.opMUL = function(opCode)
var result = ~~(src * dst);
this.regsGen[reg] = (result >> 16) & 0xffff;
this.regsGen[reg | 1] = result & 0xffff;
this.flagN = result >> 16;
this.flagZ = this.flagN | result;
this.flagV = 0;
this.flagC = (result < -32768 || result > 32767)? 0x10000 : 0;
this.updateMulFlags(result);
this.nStepCycles -= 1;
};
@ -1511,7 +1512,7 @@ PDP11.opSOB = function(opCode)
{
var reg = (opCode & PDP11.SRCMODE.REG) >> PDP11.SRCMODE.SHIFT;
if ((this.regsGen[reg] = ((this.regsGen[reg] - 1) & 0xffff))) {
this.setPC(this.regsGen[7] - ((opCode & 0x3F) << 1));
this.setPC(this.regsGen[PDP11.REG.PC] - ((opCode & 0x3F) << 1));
}
this.nStepCycles -= 1;
};
@ -1578,7 +1579,7 @@ PDP11.opTST = function(opCode)
{
var result = this.readWordByMode(opCode);
this.assert(!(result & ~0xffff)); // assert that C flag will be clear
this.updateNZCFlags(result);
this.updateAllFlags(result);
this.nStepCycles -= 1;
};
@ -1592,7 +1593,7 @@ PDP11.opTSTB = function(opCode)
{
var result = this.readByteByMode(opCode);
this.assert(!(result & ~0xff)); // assert that C flag will be clear
this.updateNZCFlags(result << 8);
this.updateAllFlags(result << 8);
this.nStepCycles -= 1;
};
@ -1643,45 +1644,45 @@ PDP11.op0Xnn_1170 = function(opCode)
};
/**
* op0Ann_1170(opCode)
* op0AXn_1170(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.op0Ann_1170 = function(opCode)
PDP11.op0AXn_1170 = function(opCode)
{
PDP11.aOps0AXn_1170[(opCode >> 6) & 0x3].call(this, opCode);
};
/**
* op0Bnn_1170(opCode)
* op0BXn_1170(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.op0Bnn_1170 = function(opCode)
PDP11.op0BXn_1170 = function(opCode)
{
PDP11.aOps0BXn_1170[(opCode >> 6) & 0x3].call(this, opCode);
};
/**
* op0Cnn_1170(opCode)
* op0CXn_1170(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.op0Cnn_1170 = function(opCode)
PDP11.op0CXn_1170 = function(opCode)
{
PDP11.aOps0CXn_1170[(opCode >> 6) & 0x3].call(this, opCode);
};
/**
* op0Dnn_1170(opCode)
* op0DXn_1170(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.op0Dnn_1170 = function(opCode)
PDP11.op0DXn_1170 = function(opCode)
{
PDP11.aOps0DXn_1170[(opCode >> 6) & 0x3].call(this, opCode);
};
@ -1848,14 +1849,42 @@ PDP11.aOps0Xnn_1170 = [
PDP11.opBLE, // 0x07nn
PDP11.opJSR, // 0x08nn
PDP11.opJSR, // 0x09nn
PDP11.op0Ann_1170, // 0x0Ann
PDP11.op0Bnn_1170, // 0x0Bnn
PDP11.op0Cnn_1170, // 0x0Cnn
PDP11.op0Dnn_1170, // 0x0Dnn
PDP11.op0AXn_1170, // 0x0Ann
PDP11.op0BXn_1170, // 0x0Bnn
PDP11.op0CXn_1170, // 0x0Cnn
PDP11.op0DXn_1170, // 0x0Dnn
PDP11.opUndefined, // 0x0Enn
PDP11.opUndefined // 0x0Fnn
];
PDP11.aOps0AXn_1170 = [
PDP11.opCLR, // 0x0A0n
PDP11.opCOM, // 0x0A4n
PDP11.opINC, // 0x0A8n
PDP11.opDEC // 0x0ACn
];
PDP11.aOps0BXn_1170 = [
PDP11.opNEG, // 0x0B0n
PDP11.opADC, // 0x0B4n
PDP11.opSBC, // 0x0B8n
PDP11.opTST // 0x0BCn
];
PDP11.aOps0CXn_1170 = [
PDP11.opROR, // 0x0C0n
PDP11.opROL, // 0x0C4n
PDP11.opASR, // 0x0C8n
PDP11.opASL // 0x0CCn
];
PDP11.aOps0DXn_1170 = [
PDP11.opMARK, // 0x0D0n
PDP11.opMFPI, // 0x0D4n
PDP11.opMTPI, // 0x0D8n
PDP11.opSXT // 0x0DCn
];
PDP11.aOps00Xn_1170 = [
PDP11.op000X_1170, // 0x000n
PDP11.opUndefined, // 0x001n
@ -1914,13 +1943,13 @@ PDP11.aOps00BX_1170 = [
];
PDP11.aOps000X_1170 = [
PDP11.opHALT, // 0x0000
PDP11.opWAIT, // 0x0001
PDP11.opRTI, // 0x0002
PDP11.opBPT, // 0x0003
PDP11.opIOT, // 0x0004
PDP11.opRESET, // 0x0005
PDP11.opRTT, // 0x0006
PDP11.opHALT, // 0x0000 000000
PDP11.opWAIT, // 0x0001 000001
PDP11.opRTI, // 0x0002 000002
PDP11.opBPT, // 0x0003 000003
PDP11.opIOT, // 0x0004 000004
PDP11.opRESET, // 0x0005 000005
PDP11.opRTT, // 0x0006 000006
PDP11.opUndefined, // 0x0007
PDP11.opUndefined, // 0x0008
PDP11.opUndefined, // 0x0009
@ -1970,34 +1999,6 @@ PDP11.aOps8Xnn_1170 = [
PDP11.opUndefined // 0x8Fnn
];
PDP11.aOps0AXn_1170 = [
PDP11.opCLR, // 0x0A0n
PDP11.opCOM, // 0x0A4n
PDP11.opINC, // 0x0A8n
PDP11.opDEC // 0x0ACn
];
PDP11.aOps0BXn_1170 = [
PDP11.opNEG, // 0x0B0n
PDP11.opADC, // 0x0B4n
PDP11.opSBC, // 0x0B8n
PDP11.opTST // 0x0BCn
];
PDP11.aOps0CXn_1170 = [
PDP11.opROR, // 0x0C0n
PDP11.opROL, // 0x0C4n
PDP11.opASR, // 0x0C8n
PDP11.opASL // 0x0CCn
];
PDP11.aOps0DXn_1170 = [
PDP11.opMARK, // 0x0D0n
PDP11.opMFPI, // 0x0D4n
PDP11.opMTPI, // 0x0D8n
PDP11.opSXT // 0x0DCn
];
PDP11.aOps8AXn_1170 = [
PDP11.opCLRB, // 0x8A0n
PDP11.opCOMB, // 0x8A4n

View file

@ -165,7 +165,6 @@ CPUStatePDP11.prototype.initRegs = function()
this.controlReg = [ // various control registers we don't really care about
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
];
this.regOp = -1; // current opcode
this.opFlags = 0;
this.cpuType = 70;
this.trapPSW = -1;
@ -504,6 +503,19 @@ CPUStatePDP11.prototype.getPC = function()
return this.regsGen[7];
};
/**
* getPCWord()
*
* @this {CPUStatePDP11}
* @return {number}
*/
CPUStatePDP11.prototype.getPCWord = function()
{
var data = this.readWordFromVirtual(this.regsGen[7]);
this.regsGen[7] = (this.regsGen[7] + 2) & 0xffff;
return data;
};
/**
* setPC()
*
@ -728,28 +740,10 @@ CPUStatePDP11.prototype.setPSW = function(newPSW)
this.regPSW = newPSW;
};
/**
* updateNZCFlags(result, overflow)
*
* NOTE: The V flag is simply zeroed, it is not "updated" based on the result;
* however, a specific overflow value may be provided (used by NEG, for example).
*
* @this {CPUStatePDP11}
* @param {number} result
* @param {number} [overflow]
*/
CPUStatePDP11.prototype.updateNZCFlags = function(result, overflow)
{
if (!(this.opFlags & PDP11.OPFLAG.SKIP_FLAGS)) {
this.flagN = this.flagZ = this.flagC = result;
this.flagV = overflow || 0;
}
};
/**
* updateNZFlags(result)
*
* NOTE: The V flag is simply zeroed, it is not "updated" based on the result.
* NOTE: The V flag is simply zeroed, and the C flag is unchanged.
*
* @this {CPUStatePDP11}
* @param {number} result
@ -762,6 +756,23 @@ CPUStatePDP11.prototype.updateNZFlags = function(result)
}
};
/**
* updateAllFlags(result, overflow)
*
* NOTE: The V flag is simply zeroed, unless a specific value is provided (eg, by NEG).
*
* @this {CPUStatePDP11}
* @param {number} result
* @param {number} [overflow]
*/
CPUStatePDP11.prototype.updateAllFlags = function(result, overflow)
{
if (!(this.opFlags & PDP11.OPFLAG.SKIP_FLAGS)) {
this.flagN = this.flagZ = this.flagC = result;
this.flagV = overflow || 0;
}
};
/**
* updateAddFlags(result, src, dst)
*
@ -815,12 +826,26 @@ CPUStatePDP11.prototype.updateIncFlags = function(result, dst)
};
/**
* updateLogFlags(result)
* updateMulFlags(result)
*
* @this {CPUStatePDP11}
* @param {number} result
*/
CPUStatePDP11.prototype.updateLogFlags = function(result)
CPUStatePDP11.prototype.updateMulFlags = function(result)
{
this.flagN = result >> 16;
this.flagZ = this.flagN | result;
this.flagV = 0;
this.flagC = (result < -32768 || result > 32767)? 0x10000 : 0;
};
/**
* updateShiftFlags(result)
*
* @this {CPUStatePDP11}
* @param {number} result
*/
CPUStatePDP11.prototype.updateShiftFlags = function(result)
{
if (!(this.opFlags & PDP11.OPFLAG.SKIP_FLAGS)) {
this.flagN = this.flagZ = this.flagC = result;
@ -913,7 +938,7 @@ CPUStatePDP11.prototype.trap = function(vector, reason)
if (DEBUG && this.dbg) {
if (this.messageEnabled(MessagesPDP11.TRAP)) {
this.printMessage("trap to vector " + this.dbg.toBase(vector, 0, true) + (reason? " (reason " + reason + ")" : ""), MessagesPDP11.TRAP, true);
this.printMessage("trap to vector " + this.dbg.toStrBase(vector, 0, true) + (reason? " (reason " + reason + ")" : ""), MessagesPDP11.TRAP, true);
}
}
@ -1319,9 +1344,7 @@ CPUStatePDP11.prototype.getVirtualByMode = function(addressMode, accessFlags)
stepSize = 2;
virtualAddress = this.regsGen[reg];
if (reg !== 7) virtualAddress |= addrDSpace;
if ((virtualAddress = this.readWordFromVirtual(virtualAddress)) < 0) {
return virtualAddress;
}
virtualAddress = this.readWordFromVirtual(virtualAddress);
// if (reg === 7) LOG_ADDRESS(virtualAddress); // @#n not operational
virtualAddress |= addrDSpace;
break;
@ -1345,44 +1368,25 @@ CPUStatePDP11.prototype.getVirtualByMode = function(addressMode, accessFlags)
stepSize = -2;
virtualAddress = (this.regsGen[reg] - 2) & 0xffff;
if (reg !== 7) virtualAddress |= addrDSpace;
if ((virtualAddress = this.readWordFromVirtual(virtualAddress)) < 0) {
return virtualAddress;
}
virtualAddress |= addrDSpace;
virtualAddress = this.readWordFromVirtual(virtualAddress) | addrDSpace;
break;
/*
* Mode 6: d(R)
*/
case 6:
if ((virtualAddress = this.readWordFromVirtual(this.regsGen[7])) < 0) {
return virtualAddress;
}
this.regsGen[7] = (this.regsGen[7] + 2) & 0xffff;
if (reg < 7) {
virtualAddress = (virtualAddress + this.regsGen[reg]) & 0xffff;
} else {
virtualAddress = (virtualAddress + this.regsGen[reg]) & 0xffff;
}
return virtualAddress | addrDSpace;
virtualAddress = this.getPCWord();
virtualAddress = ((virtualAddress + this.regsGen[reg]) & 0xffff) | addrDSpace;
return virtualAddress;
/*
* Mode 7: @d(R)
*/
case 7:
if ((virtualAddress = this.readWordFromVirtual(this.regsGen[7])) < 0) {
return virtualAddress;
}
this.regsGen[7] = (this.regsGen[7] + 2) & 0xffff;
if (reg < 7) {
virtualAddress = (virtualAddress + this.regsGen[reg]) & 0xffff;
} else {
virtualAddress = (virtualAddress + this.regsGen[reg]) & 0xffff;
}
if ((virtualAddress = this.readWordFromVirtual(virtualAddress | PDP11.ACCESS.DSPACE)) < 0) {
return virtualAddress;
}
return virtualAddress | addrDSpace;
virtualAddress = this.getPCWord();
virtualAddress = (virtualAddress + this.regsGen[reg]) & 0xffff;
virtualAddress = this.readWordFromVirtual(virtualAddress | PDP11.ACCESS.DSPACE) | addrDSpace;
return virtualAddress;
}
this.regsGen[reg] = (this.regsGen[reg] + stepSize) & 0xffff;
@ -1727,7 +1731,7 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
this.checkInterruptQueue();
}
if (!(this.regMMR0 & 0xe000)) {
if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {
this.regMMR1 = 0;
this.regMMR2 = this.regsGen[7];
}
@ -1738,22 +1742,7 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
*/
this.opFlags = this.regPSW & PDP11.PSW.TF;
/*
* TODO: Determine (later) if this.regOp is a useful (internal) register to maintain;
* perhaps it would alleviate lots of opCode parameter-passing. In the meantime, we use
* it to detect if our new decode() function has processed (ie, "consumed") the opcode,
* by setting it to -1. If it has, then we can skip the older opcode decode logic below.
*/
var opCode = this.regOp = this.readWordFromVirtual(this.regsGen[7]);
if (opCode >= 0) this.regsGen[7] = (this.regsGen[7] + 2) & 0xffff;
this.decode(opCode);
if (DEBUG && this.regOp < 0) {
this.regsGen[7] = (this.regsGen[7] - 2) & 0xffff;
this.println("unimplemented");
break;
}
this.decode(this.getPCWord());
} while (this.nStepCycles > 0);

View file

@ -777,7 +777,7 @@ if (DEBUGGER) {
*/
DebuggerPDP11.prototype.toStrOffset = function(off)
{
return this.toBase(off);
return this.toStrBase(off);
};
/**
@ -1036,9 +1036,82 @@ if (DEBUGGER) {
return false;
};
/**
* getRegIndex(sReg, off)
*
* @this {DebuggerPDP11}
* @param {string} sReg
* @param {number} [off] optional offset into sReg
* @return {number} register index, or -1 if not found
*/
DebuggerPDP11.prototype.getRegIndex = function(sReg, off)
{
var iReg = -1;
sReg = sReg.toUpperCase();
switch(sReg) {
case "SP":
iReg = 6;
break;
case "PC":
iReg = 7;
break;
default:
if (sReg.charAt(0) == "R") {
iReg = +sReg.charAt(1);
if (iReg < 0 || iReg > 7) iReg = -1;
}
break;
}
return iReg;
};
/**
* getRegName(iReg)
*
* @this {DebuggerPDP11}
* @param {number} iReg
* @return {string}
*/
DebuggerPDP11.prototype.getRegName = function(iReg)
{
return (iReg < 6? ("R" + iReg) : (iReg == 6? "SP" : "PC"));
};
/**
* getRegValue(iReg)
*
* Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt,
* 16-19 for cpu.regsAltStack, and 20 for regPSW.
*
* @this {DebuggerPDP11}
* @param {number} iReg
* @return {number|undefined}
*/
DebuggerPDP11.prototype.getRegValue = function(iReg)
{
var value;
if (iReg >= 0) {
if (iReg < 8) {
value = this.cpu.regsGen[iReg];
}
else if (iReg < 16) {
value = this.cpu.regsAlt[iReg-8];
}
else if (iReg < 20) {
value = this.cpu.regsAltStack[iReg-16];
}
else if (iReg == DebuggerPDP11.REG_PSW) {
value = this.cpu.getPSW();
}
}
return value;
};
/**
* replaceRegs(s)
*
* TODO: Implement or eliminate.
*
* @this {DebuggerPDP11}
* @param {string} s
* @return {string}
@ -1929,7 +2002,7 @@ if (DEBUGGER) {
var sLine = this.toStrAddr(dbgAddrOp) + ":";
if (dbgAddrOp.addr !== PDP11.ADDR_INVALID && dbgAddr.addr !== PDP11.ADDR_INVALID) {
do {
sOpcodes += ' ' + this.toBase(this.getWord(dbgAddrOp, 2));
sOpcodes += ' ' + this.toStrBase(this.getWord(dbgAddrOp, 2));
if (dbgAddrOp.addr == null) break;
} while (dbgAddrOp.addr != dbgAddr.addr);
}
@ -1973,20 +2046,20 @@ if (DEBUGGER) {
if (opTypeOther == DebuggerPDP11.OP_BRANCH) {
disp = ((opCode & 0xff) << 24) >> 23;
addr = (dbgAddr.addr + disp) & 0xffff;
sOperand = this.toBase(addr);
sOperand = this.toStrBase(addr);
}
else if (opTypeOther == DebuggerPDP11.OP_DSTOFF) {
disp = (opCode & 0x3f) << 1;
addr = (dbgAddr.addr - disp) & 0xffff;
sOperand = this.toBase(addr);
sOperand = this.toStrBase(addr);
}
else if (opTypeOther == DebuggerPDP11.OP_DSTNUM3) {
disp = (opCode & 0x7);
sOperand = this.toBase(disp, 1);
sOperand = this.toStrBase(disp, 1);
}
else if (opTypeOther == DebuggerPDP11.OP_DSTNUM6) {
disp = (opCode & 0x3f);
sOperand = this.toBase(disp, 1);
sOperand = this.toStrBase(disp, 1);
}
else {
/*
@ -2022,7 +2095,7 @@ if (DEBUGGER) {
* When using R7 (aka PC), POST-INCREMENT is known as IMMEDIATE
*/
wIndex = this.getWord(dbgAddr, 2);
sOperand = '#' + this.toBase(wIndex, 0, true);
sOperand = '#' + this.toStrBase(wIndex, 0, true);
}
break;
case PDP11.OPMODE.POSTINCD: // 0x3: POST-INCREMENT DEFERRED
@ -2033,7 +2106,7 @@ if (DEBUGGER) {
* When using R7 (aka PC), POST-INCREMENT DEFERRED is known as ABSOLUTE
*/
wIndex = this.getWord(dbgAddr, 2);
sOperand = "@#" + this.toBase(wIndex, 0, true);
sOperand = "@#" + this.toStrBase(wIndex, 0, true);
}
break;
case PDP11.OPMODE.PREDEC: // 0x4: PRE-DECREMENT
@ -2044,22 +2117,22 @@ if (DEBUGGER) {
break;
case PDP11.OPMODE.INDEX: // 0x6: INDEX
wIndex = this.getWord(dbgAddr, 2);
sOperand = this.toBase(wIndex, 0, true) + '(' + this.getRegName(reg) + ')';
sOperand = this.toStrBase(wIndex, 0, true) + '(' + this.getRegName(reg) + ')';
if (reg == 7) {
/*
* When using R7 (aka PC), INDEX is known as RELATIVE
*/
sOperand = [sOperand, this.toBase((wIndex + dbgAddr.addr) & 0xffff)];
sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];
}
break;
case PDP11.OPMODE.INDEXD: // 0x7: INDEX DEFERRED
wIndex = this.getWord(dbgAddr, 2);
sOperand = '@' + this.toBase(wIndex) + '(' + this.getRegName(reg) + ')';
sOperand = '@' + this.toStrBase(wIndex) + '(' + this.getRegName(reg) + ')';
if (reg == 7) {
/*
* When using R7 (aka PC), INDEX DEFERRED is known as RELATIVE DEFERRED
*/
sOperand = [sOperand, this.toBase((wIndex + dbgAddr.addr) & 0xffff)];
sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];
}
break;
default:
@ -2122,18 +2195,6 @@ if (DEBUGGER) {
return sFlag.charAt(0) + (b? '1' : '0') + ' ';
};
/**
* getRegName(iReg)
*
* @this {DebuggerPDP11}
* @param {number} iReg
* @return {string}
*/
DebuggerPDP11.prototype.getRegName = function(iReg)
{
return (iReg < 6? ("R" + iReg) : (iReg == 6? "SP" : "PC"));
};
/**
* getRegOutput(iReg)
*
@ -2148,16 +2209,16 @@ if (DEBUGGER) {
if (iReg < 8) {
sReg = this.getRegName(iReg);
sReg += '=' + this.toBase(cpu.regsGen[iReg]);
sReg += '=' + this.toStrBase(cpu.regsGen[iReg]);
}
else if (iReg < 13) {
sReg = "A" + (iReg - 8) + '=' + this.toBase(cpu.regsAlt[iReg - 8]);
sReg = "A" + (iReg - 8) + '=' + this.toStrBase(cpu.regsAlt[iReg - 8]);
}
else if (iReg >= 16 && iReg < 20) {
sReg = "S" + (iReg - 16) + '=' + this.toBase(cpu.regsAltStack[iReg - 16]);
sReg = "S" + (iReg - 16) + '=' + this.toStrBase(cpu.regsAltStack[iReg - 16]);
}
else if (iReg == DebuggerPDP11.REG_PSW) {
sReg = "PS=" + this.toBase(cpu.getPSW());
sReg = "PS=" + this.toStrBase(cpu.getPSW());
}
if (sReg) sReg += ' ';
return sReg;
@ -2762,29 +2823,32 @@ if (DEBUGGER) {
*/
DebuggerPDP11.prototype.doEdit = function(asArgs)
{
var size = 1;
var mask = 0xff;
var fnGet = this.getByte;
var fnSet = this.setByte;
if (asArgs[0] == "ew") {
var size, mask;
var fnGet, fnSet;
var sCmd = asArgs[0];
var sAddr = asArgs[1];
if (sCmd == "eb") {
size = 1;
mask = 0xff;
fnGet = this.getByte;
fnSet = this.setByte;
}
else if (sCmd == "e" || sCmd == "ew") {
size = 2;
mask = 0xffff;
fnGet = this.getWord;
fnSet = this.setWord;
} else {
sAddr = null;
}
var cch = size << 1;
var sAddr = asArgs[1];
if (sAddr == null) {
this.println("edit memory commands:");
this.println("\teb [a] [...] edit bytes at address a");
this.println("\tew [a] [...] edit words at address a");
return;
}
var dbgAddr = this.parseAddr(sAddr);
if (!dbgAddr) return;
for (var i = 2; i < asArgs.length; i++) {
var vNew = this.parseExpression(asArgs[i]);
if (vNew === undefined) {
@ -2795,7 +2859,7 @@ if (DEBUGGER) {
this.println("warning: " + str.toHex(vNew) + " exceeds " + size + "-byte value");
}
var vOld = fnGet.call(this, dbgAddr);
this.println("changing " + this.toStrAddr(dbgAddr) + " from " + str.toHex(vOld, cch, true) + " to " + str.toHex(vNew, cch, true));
this.println("changing " + this.toStrAddr(dbgAddr) + " from " + this.toStrBase(vOld, size) + " to " + this.toStrBase(vNew, size));
fnSet.call(this, dbgAddr, vNew, size);
}
};

View file

@ -281,7 +281,8 @@ var PDP11 = {
TRAP_MMU: 0x1000, // trap: MMU
ABORT_RO: 0x2000, // abort: read-only
ABORT_PL: 0x4000, // abort: page length
ABORT_NR: 0x8000 // abort: non-resident
ABORT_NR: 0x8000, // abort: non-resident
ABORT: 0xE000
},
MMR1: { // general purpose auto-inc/auto-dec register
REG1_NUM: 0x0007,

View file

@ -659,7 +659,7 @@ if (DEBUGGER) {
};
/**
* toBase(n, nBytes, fStripLeadingZeros)
* toStrBase(n, nBytes, fStripLeadingZeros)
*
* Use this instead of str.toHex() or str.toOct() to convert bytes/words to the Debugger's default base.
*
@ -669,7 +669,7 @@ if (DEBUGGER) {
* @param {boolean} [fStripLeadingZeros]
* @return {string}
*/
Debugger.prototype.toBase = function(n, nBytes, fStripLeadingZeros)
Debugger.prototype.toStrBase = function(n, nBytes, fStripLeadingZeros)
{
var s;
switch(this.nBase) {