Fixed the PDP-10 BLT instruction

This commit is contained in:
Jeff 2017-04-05 11:32:16 -07:00 committed by Jeff Parsons
commit d4c12c8c7a
10 changed files with 121 additions and 109 deletions

View file

@ -2155,8 +2155,7 @@ PDP10.opEXCH = function(op, ac)
* is the final location being loaded. Furthermore, the program cannot assume that AC is the same after the BLT
* as it was before.
*
* TODO: Determine the logic behind SIMH's bizarre treatment of the AC register when it's part of the memory
* being transferred.
* TODO: Determine the logic behind SIMH's treatment of the AC register when it's part of the memory being transferred.
*
* @this {CPUStatePDP10}
* @param {number} op
@ -2164,23 +2163,31 @@ PDP10.opEXCH = function(op, ac)
*/
PDP10.opBLT = function(op, ac)
{
var fDone = false;
var fDone = false, fUpdate = false;
var addrDst = this.readWord(ac);
var addrSrc = (addrDst / PDP10.HALF_SHIFT)|0;
addrDst &= PDP10.HALF_MASK;
while (!fDone) {
this.writeWord(addrDst, this.readWord(addrSrc));
if (addrDst == this.regEA) fDone = true;
addrSrc = (addrSrc + 1) & PDP10.HALF_MASK;
addrDst = (addrDst + 1) & PDP10.HALF_MASK;
if (!this.isRunning()) {
/*
* NOTE: The PDP-10 specs (especially the KA10 Reference Manual) are not very clear on the exit criteria:
* the transfer stops once AC left >= E, not AC left == E. They are also not very clear on whether the addresses
* are incremented before or after the exit criteria is checked; however, the KA10 "DAKAM" diagnostic seems
* pretty adamant that, at least after a one-word BLT operation, the addresses should NOT be incremented.
*/
if (!(fDone = (addrDst >= this.regEA))) {
addrSrc = (addrSrc + 1) & PDP10.HALF_MASK;
addrDst = (addrDst + 1) & PDP10.HALF_MASK;
fUpdate = true;
}
if (fDone || !this.isRunning()) {
/*
* Since the CPU isn't currently running, the CPU is presumably being stepped, so we'll treat that the
* same as the "priority interrupt" condition described above, update the accumulator, rewind the PC, and leave.
* If the CPU isn't currently running, the CPU is presumably being stepped, so we'll treat that the
* same as the "priority interrupt" condition described above, update the addresses, rewind the PC, and leave.
*/
this.writeWord(ac, addrSrc * PDP10.HALF_SHIFT + addrDst);
if (fUpdate) this.writeWord(ac, addrSrc * PDP10.HALF_SHIFT + addrDst);
if (!fDone) this.advancePC(-1);
fDone = true;
break;
}
}
};

View file

@ -1611,7 +1611,7 @@ class Macro10 {
{
name = name.toUpperCase().substr(0, 6);
if ((nType & Macro10.SYMTYPE.LABEL) && this.tblSymbols[name] !== undefined) {
this.error("label '" + name + "' redefined");
this.error("redefined label '" + name + "'");
return;
}
var sUndefined = undefined;
@ -1619,9 +1619,12 @@ class Macro10 {
var aUndefined = [];
var v = this.parseExpression(value, aUndefined);
if (v === undefined) {
this.error("symbol error (" + value + ")");
this.error("invalid symbol '" + name + "': " + value);
return;
}
if (aUndefined.length > 1) {
this.error("too many undefined symbols in '" + name + "': " + aUndefined.join());
}
value = v;
sUndefined = aUndefined[0];
}

View file

@ -1075,11 +1075,13 @@ class Debugger extends Component
if (aUndefined) {
aUndefined.push(sUndefined);
} else {
var valueUndefined = this.parseExpression(sUndefined, false);
var valueUndefined = this.parseExpression(sUndefined, fQuiet);
if (valueUndefined !== undefined) {
value += valueUndefined;
} else {
this.println(sValue + " = " + this.toStrBase(value) + " + (" + sUndefined + ")");
if (!fQuiet) {
this.println("undefined " + (sName || "value") + ": " + sValue + " (" + sUndefined + ")");
}
value = undefined;
}
}
@ -1095,7 +1097,7 @@ class Debugger extends Component
value = this.truncate(this.parseUnary(value, nUnary));
} else {
if (!fQuiet) {
this.println("invalid " + (sName? sName : "value") + ": " + sValue);
this.println("invalid " + (sName || "value") + ": " + sValue);
}
}
} else {