From e322c5f91256c7a6c07f7e05326d84cd23fc9d4a Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 27 Sep 2016 09:28:52 -0700 Subject: [PATCH] Implemented INC/DEC opcodes --- modules/pdp11/lib/cpuops.js | 68 +++++++++++++++++++++++------------ modules/pdp11/lib/cpustate.js | 55 +++++++++++++++++++++++++++- modules/pdp11/lib/debugger.js | 60 +++++++++++++++++-------------- 3 files changed, 133 insertions(+), 50 deletions(-) diff --git a/modules/pdp11/lib/cpuops.js b/modules/pdp11/lib/cpuops.js index 855508202..879c7e4ec 100644 --- a/modules/pdp11/lib/cpuops.js +++ b/modules/pdp11/lib/cpuops.js @@ -38,22 +38,22 @@ if (NODE) { } /** - * fnADD(dst, src) + * fnADD(src, dst) * * @this {CPUStatePDP11} * @param {number} src * @param {number} dst - * @return {number} (src + dst) + * @return {number} (dst + src) */ PDP11.fnADD = function(src, dst) { - var result = src + dst; + var result = dst + src; this.updateAddFlags(result, src, dst); return result & 0xffff; }; /** - * fnBIC(dst, src) + * fnBIC(src, dst) * * @this {CPUStatePDP11} * @param {number} src @@ -62,13 +62,13 @@ PDP11.fnADD = function(src, dst) */ PDP11.fnBIC = function(src, dst) { - var result = ~src & dst; + var result = dst & ~src; this.updateNZFlags(result); return result; }; /** - * fnBICB(dst, src) + * fnBICB(src, dst) * * @this {CPUStatePDP11} * @param {number} src @@ -77,43 +77,73 @@ PDP11.fnBIC = function(src, dst) */ PDP11.fnBICB = function(src, dst) { - var result = ~src & dst; + var result = dst & ~src; this.updateNZFlags(result << 8); return result; }; /** - * fnBIS(dst, src) + * fnBIS(src, dst) * * @this {CPUStatePDP11} * @param {number} src * @param {number} dst - * @return {number} (src | dst) + * @return {number} (dst | src) */ PDP11.fnBIS = function(src, dst) { - var result = src | dst; + var result = dst | src; this.updateNZFlags(result); return result; }; /** - * fnBISB(dst, src) + * fnBISB(src, dst) * * @this {CPUStatePDP11} * @param {number} src * @param {number} dst - * @return {number} (src | dst) + * @return {number} (dst | src) */ PDP11.fnBISB = function(src, dst) { - var result = src | dst; + var result = dst | src; this.updateNZFlags(result << 8); return result; }; /** - * fnSUB(dst, src) + * fnDEC(src, dst) + * + * @this {CPUStatePDP11} + * @param {number} src (ie, 1) + * @param {number} dst + * @return {number} (dst - src) + */ +PDP11.fnDEC = function(src, dst) +{ + var result = dst - src; + this.updateDecFlags(result, src, dst); + return result & 0xffff; +}; + +/** + * fnINC(src, dst) + * + * @this {CPUStatePDP11} + * @param {number} src (ie, 1) + * @param {number} dst + * @return {number} (dst + src) + */ +PDP11.fnINC = function(src, dst) +{ + var result = dst + src; + this.updateIncFlags(result, src, dst); + return result & 0xffff; +}; + +/** + * fnSUB(src, dst) * * @this {CPUStatePDP11} * @param {number} src @@ -689,10 +719,7 @@ PDP11.opCOMB = function(opCode) */ PDP11.opDEC = function(opCode) { - /* - * TODO: Implement - */ - this.regOp = -1; + this.updateWordByMode(opCode, 1, PDP11.fnDEC); this.nStepCycles -= 1; }; @@ -764,10 +791,7 @@ PDP11.opHALT = function(opCode) */ PDP11.opINC = function(opCode) { - /* - * TODO: Implement - */ - this.regOp = -1; + this.updateWordByMode(opCode, 1, PDP11.fnINC); this.nStepCycles -= 1; }; diff --git a/modules/pdp11/lib/cpustate.js b/modules/pdp11/lib/cpustate.js index a194c852e..d9e8f03d1 100644 --- a/modules/pdp11/lib/cpustate.js +++ b/modules/pdp11/lib/cpustate.js @@ -512,7 +512,7 @@ CPUStatePDP11.prototype.getPC = function() */ CPUStatePDP11.prototype.setPC = function(addr) { - this.regsGen[7] = addr; + this.regsGen[7] = addr & 0xffff; }; /** @@ -526,6 +526,17 @@ CPUStatePDP11.prototype.getSP = function() return this.regsGen[6]; }; +/** + * setSP() + * + * @this {CPUStatePDP11} + * @param {number} addr + */ +CPUStatePDP11.prototype.setSP = function(addr) +{ + this.regsGen[6] = addr & 0xffff; +}; + /** * requestHALT() * @@ -702,6 +713,8 @@ CPUStatePDP11.prototype.setPSW = function(newPSW) /** * updateNZCFlags(result) * + * NOTE: The V flag is simply zeroed, it is not "updated" based on the result. + * * @this {CPUStatePDP11} * @param {number} result */ @@ -716,6 +729,8 @@ CPUStatePDP11.prototype.updateNZCFlags = function(result) /** * updateNZFlags(result) * + * NOTE: The V flag is simply zeroed, it is not "updated" based on the result. + * * @this {CPUStatePDP11} * @param {number} result */ @@ -743,6 +758,44 @@ CPUStatePDP11.prototype.updateAddFlags = function(result, src, dst) } }; +/** + * updateIncFlags(result, src, dst) + * + * NOTE: We could have used updateAddFlags() if not for the fact that the C flag must be preserved. + * + * @this {CPUStatePDP11} + * @param {number} result (dst + src) + * @param {number} src (ie, 1) + * @param {number} dst + */ +CPUStatePDP11.prototype.updateIncFlags = function(result, src, dst) +{ + if (!(this.opFlags & PDP11.OPFLAG.SKIP_FLAGS)) { + this.flagN = this.flagZ = result; + // Because src is always 1 (with a zero sign bit), it can be optimized out of this calculation + this.flagV = (/* src ^ */ result) & (dst ^ result); + } +}; + +/** + * updateDecFlags(result, src, dst) + * + * NOTE: We could have used updateSubFlags() if not for the fact that the C flag must be preserved. + * + * @this {CPUStatePDP11} + * @param {number} result (dst - src) + * @param {number} src (ie, 1) + * @param {number} dst + */ +CPUStatePDP11.prototype.updateDecFlags = function(result, src, dst) +{ + if (!(this.opFlags & PDP11.OPFLAG.SKIP_FLAGS)) { + this.flagN = this.flagZ = result; + // Because src is always 1 (with a zero sign bit), it can be optimized out of this calculation + this.flagV = (/* src ^ */ dst) & (dst ^ result); + } +}; + /** * updateSubFlags(result, src, dst) * diff --git a/modules/pdp11/lib/debugger.js b/modules/pdp11/lib/debugger.js index 550829a18..09846399f 100644 --- a/modules/pdp11/lib/debugger.js +++ b/modules/pdp11/lib/debugger.js @@ -3140,38 +3140,44 @@ if (DEBUGGER) { return; } - var fValid = false; var w = this.parseExpression(sValue); + if (w === undefined) return; - if (w !== undefined) { - fValid = true; - var sRegMatch = sReg.toUpperCase(); - switch (sRegMatch) { - case "PC": - cpu.setPC(w); - this.dbgAddrNextCode = this.newAddr(cpu.getPC()); - break; - case "NF": - if (w) cpu.setNF(); else cpu.clearNF(); - break; - case "ZF": - if (w) cpu.setZF(); else cpu.clearZF(); - break; - case "VF": - if (w) cpu.setVF(); else cpu.clearVF(); - break; - case "CF": - if (w) cpu.setCF(); else cpu.clearCF(); - break; - default: - this.println("unknown register: " + sReg); - return; + var sRegMatch = sReg.toUpperCase(); + switch (sRegMatch) { + case "SP": + case "R6": + cpu.setSP(w); + break; + case "PC": + case "R7": + cpu.setPC(w); + this.dbgAddrNextCode = this.newAddr(cpu.getPC()); + break; + case "N": + if (w) cpu.setNF(); else cpu.clearNF(); + break; + case "Z": + if (w) cpu.setZF(); else cpu.clearZF(); + break; + case "V": + if (w) cpu.setVF(); else cpu.clearVF(); + break; + case "C": + if (w) cpu.setCF(); else cpu.clearCF(); + break; + default: + if (sRegMatch.charAt(0) == 'R') { + var iReg = +sRegMatch.charAt(1); + if (iReg >= 0 && iReg < 6) { + cpu.regsGen[iReg] = w & 0xffff; + break; + } } - } - if (!fValid) { - this.println("invalid value: " + sValue); + this.println("unknown register: " + sReg); return; } + cpu.updateCPU(); this.println("updated registers:"); }