Implemented INC/DEC opcodes
This commit is contained in:
parent
b2294e2293
commit
e322c5f912
3 changed files with 133 additions and 50 deletions
|
|
@ -38,22 +38,22 @@ if (NODE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fnADD(dst, src)
|
* fnADD(src, dst)
|
||||||
*
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} src
|
* @param {number} src
|
||||||
* @param {number} dst
|
* @param {number} dst
|
||||||
* @return {number} (src + dst)
|
* @return {number} (dst + src)
|
||||||
*/
|
*/
|
||||||
PDP11.fnADD = function(src, dst)
|
PDP11.fnADD = function(src, dst)
|
||||||
{
|
{
|
||||||
var result = src + dst;
|
var result = dst + src;
|
||||||
this.updateAddFlags(result, src, dst);
|
this.updateAddFlags(result, src, dst);
|
||||||
return result & 0xffff;
|
return result & 0xffff;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fnBIC(dst, src)
|
* fnBIC(src, dst)
|
||||||
*
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} src
|
* @param {number} src
|
||||||
|
|
@ -62,13 +62,13 @@ PDP11.fnADD = function(src, dst)
|
||||||
*/
|
*/
|
||||||
PDP11.fnBIC = function(src, dst)
|
PDP11.fnBIC = function(src, dst)
|
||||||
{
|
{
|
||||||
var result = ~src & dst;
|
var result = dst & ~src;
|
||||||
this.updateNZFlags(result);
|
this.updateNZFlags(result);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fnBICB(dst, src)
|
* fnBICB(src, dst)
|
||||||
*
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} src
|
* @param {number} src
|
||||||
|
|
@ -77,43 +77,73 @@ PDP11.fnBIC = function(src, dst)
|
||||||
*/
|
*/
|
||||||
PDP11.fnBICB = function(src, dst)
|
PDP11.fnBICB = function(src, dst)
|
||||||
{
|
{
|
||||||
var result = ~src & dst;
|
var result = dst & ~src;
|
||||||
this.updateNZFlags(result << 8);
|
this.updateNZFlags(result << 8);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fnBIS(dst, src)
|
* fnBIS(src, dst)
|
||||||
*
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} src
|
* @param {number} src
|
||||||
* @param {number} dst
|
* @param {number} dst
|
||||||
* @return {number} (src | dst)
|
* @return {number} (dst | src)
|
||||||
*/
|
*/
|
||||||
PDP11.fnBIS = function(src, dst)
|
PDP11.fnBIS = function(src, dst)
|
||||||
{
|
{
|
||||||
var result = src | dst;
|
var result = dst | src;
|
||||||
this.updateNZFlags(result);
|
this.updateNZFlags(result);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fnBISB(dst, src)
|
* fnBISB(src, dst)
|
||||||
*
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} src
|
* @param {number} src
|
||||||
* @param {number} dst
|
* @param {number} dst
|
||||||
* @return {number} (src | dst)
|
* @return {number} (dst | src)
|
||||||
*/
|
*/
|
||||||
PDP11.fnBISB = function(src, dst)
|
PDP11.fnBISB = function(src, dst)
|
||||||
{
|
{
|
||||||
var result = src | dst;
|
var result = dst | src;
|
||||||
this.updateNZFlags(result << 8);
|
this.updateNZFlags(result << 8);
|
||||||
return result;
|
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}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} src
|
* @param {number} src
|
||||||
|
|
@ -689,10 +719,7 @@ PDP11.opCOMB = function(opCode)
|
||||||
*/
|
*/
|
||||||
PDP11.opDEC = function(opCode)
|
PDP11.opDEC = function(opCode)
|
||||||
{
|
{
|
||||||
/*
|
this.updateWordByMode(opCode, 1, PDP11.fnDEC);
|
||||||
* TODO: Implement
|
|
||||||
*/
|
|
||||||
this.regOp = -1;
|
|
||||||
this.nStepCycles -= 1;
|
this.nStepCycles -= 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -764,10 +791,7 @@ PDP11.opHALT = function(opCode)
|
||||||
*/
|
*/
|
||||||
PDP11.opINC = function(opCode)
|
PDP11.opINC = function(opCode)
|
||||||
{
|
{
|
||||||
/*
|
this.updateWordByMode(opCode, 1, PDP11.fnINC);
|
||||||
* TODO: Implement
|
|
||||||
*/
|
|
||||||
this.regOp = -1;
|
|
||||||
this.nStepCycles -= 1;
|
this.nStepCycles -= 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -512,7 +512,7 @@ CPUStatePDP11.prototype.getPC = function()
|
||||||
*/
|
*/
|
||||||
CPUStatePDP11.prototype.setPC = function(addr)
|
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];
|
return this.regsGen[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setSP()
|
||||||
|
*
|
||||||
|
* @this {CPUStatePDP11}
|
||||||
|
* @param {number} addr
|
||||||
|
*/
|
||||||
|
CPUStatePDP11.prototype.setSP = function(addr)
|
||||||
|
{
|
||||||
|
this.regsGen[6] = addr & 0xffff;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* requestHALT()
|
* requestHALT()
|
||||||
*
|
*
|
||||||
|
|
@ -702,6 +713,8 @@ CPUStatePDP11.prototype.setPSW = function(newPSW)
|
||||||
/**
|
/**
|
||||||
* updateNZCFlags(result)
|
* updateNZCFlags(result)
|
||||||
*
|
*
|
||||||
|
* NOTE: The V flag is simply zeroed, it is not "updated" based on the result.
|
||||||
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} result
|
* @param {number} result
|
||||||
*/
|
*/
|
||||||
|
|
@ -716,6 +729,8 @@ CPUStatePDP11.prototype.updateNZCFlags = function(result)
|
||||||
/**
|
/**
|
||||||
* updateNZFlags(result)
|
* updateNZFlags(result)
|
||||||
*
|
*
|
||||||
|
* NOTE: The V flag is simply zeroed, it is not "updated" based on the result.
|
||||||
|
*
|
||||||
* @this {CPUStatePDP11}
|
* @this {CPUStatePDP11}
|
||||||
* @param {number} result
|
* @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)
|
* updateSubFlags(result, src, dst)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -3140,38 +3140,44 @@ if (DEBUGGER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fValid = false;
|
|
||||||
var w = this.parseExpression(sValue);
|
var w = this.parseExpression(sValue);
|
||||||
|
if (w === undefined) return;
|
||||||
|
|
||||||
if (w !== undefined) {
|
var sRegMatch = sReg.toUpperCase();
|
||||||
fValid = true;
|
switch (sRegMatch) {
|
||||||
var sRegMatch = sReg.toUpperCase();
|
case "SP":
|
||||||
switch (sRegMatch) {
|
case "R6":
|
||||||
case "PC":
|
cpu.setSP(w);
|
||||||
cpu.setPC(w);
|
break;
|
||||||
this.dbgAddrNextCode = this.newAddr(cpu.getPC());
|
case "PC":
|
||||||
break;
|
case "R7":
|
||||||
case "NF":
|
cpu.setPC(w);
|
||||||
if (w) cpu.setNF(); else cpu.clearNF();
|
this.dbgAddrNextCode = this.newAddr(cpu.getPC());
|
||||||
break;
|
break;
|
||||||
case "ZF":
|
case "N":
|
||||||
if (w) cpu.setZF(); else cpu.clearZF();
|
if (w) cpu.setNF(); else cpu.clearNF();
|
||||||
break;
|
break;
|
||||||
case "VF":
|
case "Z":
|
||||||
if (w) cpu.setVF(); else cpu.clearVF();
|
if (w) cpu.setZF(); else cpu.clearZF();
|
||||||
break;
|
break;
|
||||||
case "CF":
|
case "V":
|
||||||
if (w) cpu.setCF(); else cpu.clearCF();
|
if (w) cpu.setVF(); else cpu.clearVF();
|
||||||
break;
|
break;
|
||||||
default:
|
case "C":
|
||||||
this.println("unknown register: " + sReg);
|
if (w) cpu.setCF(); else cpu.clearCF();
|
||||||
return;
|
break;
|
||||||
|
default:
|
||||||
|
if (sRegMatch.charAt(0) == 'R') {
|
||||||
|
var iReg = +sRegMatch.charAt(1);
|
||||||
|
if (iReg >= 0 && iReg < 6) {
|
||||||
|
cpu.regsGen[iReg] = w & 0xffff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
this.println("unknown register: " + sReg);
|
||||||
if (!fValid) {
|
|
||||||
this.println("invalid value: " + sValue);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.updateCPU();
|
cpu.updateCPU();
|
||||||
this.println("updated registers:");
|
this.println("updated registers:");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue