Fixed read/write breakpoints for instructions that snapshot the cycle count, and improved the disassembly of PC-relative operands
This commit is contained in:
parent
3db1439b40
commit
22e24697fe
5 changed files with 286 additions and 263 deletions
|
|
@ -530,7 +530,7 @@ CPUPDP11.prototype.addCycles = function(nCycles, fEndStep)
|
|||
{
|
||||
this.nTotalCycles += nCycles;
|
||||
if (fEndStep) {
|
||||
this.nBurstCycles = this.nStepCycles = 0;
|
||||
this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -643,7 +643,7 @@ CPUPDP11.prototype.resetCycles = function()
|
|||
{
|
||||
this.mhz = 0;
|
||||
this.nYieldsSinceStatusUpdate = 0;
|
||||
this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;
|
||||
this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;
|
||||
this.resetChecksum();
|
||||
this.setSpeed(1);
|
||||
};
|
||||
|
|
@ -1019,7 +1019,13 @@ CPUPDP11.prototype.updateTimers = function(nCycles)
|
|||
CPUPDP11.prototype.endBurst = function(fReset)
|
||||
{
|
||||
var nCycles = this.nBurstCycles -= this.nStepCycles;
|
||||
this.nStepCycles = 0;
|
||||
/*
|
||||
* In addition to zeroing nStepCycles, it's important that we also zero nSnapCycles, because if a CPU
|
||||
* burst is being ended after nStepCycles has been "snapped" (because a certain opcode has an unusual timing
|
||||
* calculation that must be based on a "snapped" cycle count rather the opcode's starting cycle count), we
|
||||
* could inadvertently undo the endBurst() if the original "snapped" value was used to update nStepCycles.
|
||||
*/
|
||||
this.nStepCycles = this.nSnapCycles = 0;
|
||||
if (fReset) this.nBurstCycles = 0;
|
||||
return nCycles;
|
||||
};
|
||||
|
|
@ -1190,7 +1196,6 @@ CPUPDP11.prototype.yieldCPU = function()
|
|||
{
|
||||
this.endBurst(); // this will break us out of stepCPU()
|
||||
this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()
|
||||
// if (DEBUG) this.nSnapCycles = this.nBurstCycles;
|
||||
/*
|
||||
* The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks
|
||||
* odd for those messages to show CPU state changes if the Control Panel, Video display, etc, does not,
|
||||
|
|
|
|||
|
|
@ -1191,9 +1191,9 @@ PDP11.opJMP = function(opCode)
|
|||
* Since JMP and JSR opcodes have their own unique timings for the various dst modes, we must snapshot
|
||||
* nStepCycles before decoding the mode, and then use that to update nStepCycles.
|
||||
*/
|
||||
var nSnapCycles = this.nStepCycles;
|
||||
this.nSnapCycles = this.nStepCycles;
|
||||
this.setPC(this.readDstAddr(opCode));
|
||||
this.nStepCycles = nSnapCycles - PDP11.JMP_CYCLES[this.dstMode];
|
||||
this.nStepCycles = this.nSnapCycles - PDP11.JMP_CYCLES[this.dstMode];
|
||||
};
|
||||
|
||||
PDP11.JSR_CYCLES = [
|
||||
|
|
@ -1212,7 +1212,7 @@ PDP11.opJSR = function(opCode)
|
|||
* Since JMP and JSR opcodes have their own unique timings for the various dst modes, we must snapshot
|
||||
* nStepCycles before decoding the mode, and then use that to update nStepCycles.
|
||||
*/
|
||||
var nSnapCycles = this.nStepCycles;
|
||||
this.nSnapCycles = this.nStepCycles;
|
||||
/*
|
||||
* TODO: Determine whether or not the SRCMODE operand (regsGen[reg]) should be snapped BEFORE or AFTER we
|
||||
* decode the DSTMODE operand. Doing it AFTER seems a bit risky.
|
||||
|
|
@ -1222,7 +1222,7 @@ PDP11.opJSR = function(opCode)
|
|||
this.pushWord(this.regsGen[reg]);
|
||||
this.regsGen[reg] = this.getPC();
|
||||
this.setPC(addr);
|
||||
this.nStepCycles = nSnapCycles - PDP11.JSR_CYCLES[this.dstMode];
|
||||
this.nStepCycles = this.nSnapCycles - PDP11.JSR_CYCLES[this.dstMode];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1287,9 +1287,9 @@ PDP11.opMOV = function(opCode)
|
|||
* nStepCycles after decoding the src mode, and then use that to update nStepCycles.
|
||||
*/
|
||||
var data = this.readSrcWord(opCode);
|
||||
var nSnapCycles = this.nStepCycles;
|
||||
this.nSnapCycles = this.nStepCycles;
|
||||
this.updateNZVFlags(this.writeDstWord(opCode, data));
|
||||
this.nStepCycles = nSnapCycles - PDP11.MOV_CYCLES[(this.srcMode? 8 : 0) + this.dstMode] + (this.dstReg == 7 && !this.dstMode? 2 : 0);
|
||||
this.nStepCycles = this.nSnapCycles - PDP11.MOV_CYCLES[(this.srcMode? 8 : 0) + this.dstMode] + (this.dstReg == 7 && !this.dstMode? 2 : 0);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1322,10 +1322,10 @@ PDP11.opMTPD = function(opCode)
|
|||
* nStepCycles before decoding the mode, and then use that to update nStepCycles.
|
||||
*/
|
||||
var data = this.popWord();
|
||||
var nSnapCycles = this.nStepCycles;
|
||||
this.nSnapCycles = this.nStepCycles;
|
||||
this.writeWordToPrevSpace(opCode, PDP11.ACCESS.DSPACE, data);
|
||||
this.updateNZVFlags(data);
|
||||
this.nStepCycles = nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];
|
||||
this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1341,10 +1341,10 @@ PDP11.opMTPI = function(opCode)
|
|||
* nStepCycles before decoding the mode, and then use that to update nStepCycles.
|
||||
*/
|
||||
var data = this.popWord();
|
||||
var nSnapCycles = this.nStepCycles;
|
||||
this.nSnapCycles = this.nStepCycles;
|
||||
this.writeWordToPrevSpace(opCode, PDP11.ACCESS.ISPACE, data);
|
||||
this.updateNZVFlags(data);
|
||||
this.nStepCycles = nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];
|
||||
this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1497,7 +1497,7 @@ PDP11.opRTS = function(opCode)
|
|||
var src = this.popWord();
|
||||
var reg = opCode & PDP11.OPREG.MASK;
|
||||
/*
|
||||
* When the popular "RTS PC" form is used, we might as well eliminate the useless setting of PC to itself.
|
||||
* When the popular "RTS PC" form is used, we might as well eliminate the useless setting of PC to
|
||||
*/
|
||||
if (reg == PDP11.REG.PC) {
|
||||
this.setPC(src);
|
||||
|
|
|
|||
|
|
@ -2091,7 +2091,8 @@ if (DEBUGGER) {
|
|||
|
||||
/*
|
||||
* If getOperand() returns an Array rather than a string, then the first element is the original
|
||||
* operand, and the second element contains an alternate representation of the operand (eg, target address).
|
||||
* operand, and the second element contains an alternate representation of the operand (eg, target address,
|
||||
* memory contents, etc).
|
||||
*/
|
||||
if (typeof sOperand != "string") {
|
||||
sTarget = sOperand[1];
|
||||
|
|
@ -2134,6 +2135,10 @@ if (DEBUGGER) {
|
|||
* If getOperand() returns an Array rather than a string, then the first element is the original
|
||||
* operand, and the second element is a comment containing an alternate representation of the operand.
|
||||
*
|
||||
* TODO: For PC-relative addresses, we now return the effective address directly, rather than as the
|
||||
* second element of an Array; however, I still envision using Array return values to include current
|
||||
* memory operands, so support for such values is being left in place.
|
||||
*
|
||||
* @this {DebuggerPDP11}
|
||||
* @param {number} opCode
|
||||
* @param {number} opType
|
||||
|
|
@ -2229,9 +2234,20 @@ if (DEBUGGER) {
|
|||
sOperand = this.toStrBase(wIndex, 0, true) + '(' + this.getRegName(reg) + ')';
|
||||
if (reg == 7) {
|
||||
/*
|
||||
* When using R7 (aka PC), INDEX is known as RELATIVE
|
||||
* When using R7 (aka PC), INDEX is known as RELATIVE. However, instead of displaying
|
||||
* such an instruction like this:
|
||||
*
|
||||
* 016156: 010167 001300 MOV R1,1300(PC) ; @017462
|
||||
*
|
||||
* with the effective address display to the far right, let's display it like this instead:
|
||||
*
|
||||
* 016156: 010167 001300 MOV R1,017462
|
||||
*
|
||||
* because you can still clearly see PC-relative offset (eg, 001300) as part of the disassembly.
|
||||
*
|
||||
* sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];
|
||||
*/
|
||||
sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];
|
||||
sOperand = this.toStrBase((wIndex + dbgAddr.addr) & 0xffff);
|
||||
}
|
||||
break;
|
||||
case PDP11.OPMODE.INDEXD: // 0x7: INDEX DEFERRED
|
||||
|
|
@ -2239,9 +2255,12 @@ if (DEBUGGER) {
|
|||
sOperand = '@' + this.toStrBase(wIndex) + '(' + this.getRegName(reg) + ')';
|
||||
if (reg == 7) {
|
||||
/*
|
||||
* When using R7 (aka PC), INDEX DEFERRED is known as RELATIVE DEFERRED
|
||||
* When using R7 (aka PC), INDEX DEFERRED is known as RELATIVE DEFERRED. And for the same
|
||||
* reasons articulated above, we now display the effective address inline.
|
||||
*
|
||||
* sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];
|
||||
*/
|
||||
sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];
|
||||
sOperand = '@' + this.toStrBase((wIndex + dbgAddr.addr) & 0xffff);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in a new issue