Implemented branches and RTS

This commit is contained in:
Jeff 2016-09-26 11:27:32 -07:00 • committed by Jeff Parsons
commit 6af956b8f0
8 changed files with 1932 additions and 1922 deletions

File diff suppressed because one or more lines are too long

View file

@ -6091,11 +6091,16 @@ if (DEBUGGER) {
var data = 0, iByte = 0, i;
var sData = "", sChars = "";
sAddr = this.toHexAddr(dbgAddr);
for (i = 16; i > 0 && cb > 0; i--) {
/*
* It's just coincidence that we want to dump 8 bytes per line when using base 8 and 16 bytes
* per line when using base 16, because octal requires more digits.
*/
var nBytes = (size == 4? 16 : this.nBase);
for (i = nBytes; i > 0 && cb > 0; i--) {
var b = this.getByte(dbgAddr, 1);
data |= (b << (iByte++ << 3));
if (iByte == size) {
sData += str.toHex(data, size * 2);
sData += (this.nBase == 8? str.toOct(data, size * 3) : str.toHex(data, size * 2));
sData += (size == 1? (i == 9? '-' : ' ') : " ");
data = iByte = 0;
}

View file

@ -267,10 +267,7 @@ PDP11.opASRB = function(opCode)
*/
PDP11.opBCC = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getCF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -282,10 +279,7 @@ PDP11.opBCC = function(opCode)
*/
PDP11.opBCS = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (this.getCF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -369,10 +363,7 @@ PDP11.opBITB = function(opCode)
*/
PDP11.opBEQ = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (this.getZF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -384,10 +375,7 @@ PDP11.opBEQ = function(opCode)
*/
PDP11.opBGE = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getNF() == !this.getVF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -399,10 +387,7 @@ PDP11.opBGE = function(opCode)
*/
PDP11.opBGT = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getZF() && (!this.getNF() == !this.getVF())) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -414,10 +399,7 @@ PDP11.opBGT = function(opCode)
*/
PDP11.opBHI = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getCF() && !this.getZF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -429,10 +411,7 @@ PDP11.opBHI = function(opCode)
*/
PDP11.opBLE = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (this.getZF() || (!this.getNF() != !this.getVF())) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -444,10 +423,7 @@ PDP11.opBLE = function(opCode)
*/
PDP11.opBLOS = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (this.getCF() || this.getZF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -459,10 +435,7 @@ PDP11.opBLOS = function(opCode)
*/
PDP11.opBLT = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getNF() != !this.getVF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -474,10 +447,7 @@ PDP11.opBLT = function(opCode)
*/
PDP11.opBMI = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (this.getNF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -489,10 +459,7 @@ PDP11.opBMI = function(opCode)
*/
PDP11.opBNE = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getZF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -504,10 +471,7 @@ PDP11.opBNE = function(opCode)
*/
PDP11.opBPL = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getNF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -534,10 +498,7 @@ PDP11.opBPT = function(opCode)
*/
PDP11.opBR = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -549,10 +510,7 @@ PDP11.opBR = function(opCode)
*/
PDP11.opBVC = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (!this.getVF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -564,10 +522,7 @@ PDP11.opBVC = function(opCode)
*/
PDP11.opBVS = function(opCode)
{
/*
* TODO: Implement
*/
this.regOp = -1;
if (this.getVF()) this.regsGen[7] = this.branch(opCode);
this.nStepCycles -= 1;
};
@ -1154,6 +1109,22 @@ PDP11.opRTI = function(opCode)
this.nStepCycles -= 1;
};
/**
* opRTS(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.opRTS = function(opCode)
{
this.assert(!(opCode & 0x08));
var src = this.popWord();
var reg = opCode & PDP11.OPREG.MASK;
this.regsGen[PDP11.REG.PC] = this.regsGen[reg];
this.regsGen[reg] = src;
this.nStepCycles -= 1;
};
/**
* opRTT(opCode)
*
@ -1277,6 +1248,22 @@ PDP11.opSOB = function(opCode)
this.nStepCycles -= 1;
};
/**
* opSPL(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.opSPL = function(opCode)
{
this.assert(opCode & 0x08);
if (!(this.PSW & PDP11.PSW.CMODE)) {
this.PSW = (this.PSW & ~(PDP11.PSW.UNUSED | PDP11.PSW.PRI)) | ((opCode & 0x7) << PDP11.PSW.SHIFT.PRI);
this.priorityReview = 1;
}
this.nStepCycles -= 1;
};
/**
* opSUB(opCode)
*
@ -1467,6 +1454,17 @@ PDP11.op00Xn_1170 = function(opCode)
PDP11.aOps00Xn_1170[(opCode >> 4) & 0xf].call(this, opCode);
};
/**
* op008X_1170(opCode)
*
* @this {CPUStatePDP11}
* @param {number} opCode
*/
PDP11.op008X_1170 = function(opCode)
{
PDP11.aOps00AX_1170[opCode & 0xf].call(this, opCode);
};
/**
* op00AX_1170(opCode)
*
@ -1568,20 +1566,20 @@ PDP11.op8DXn_1170 = function(opCode)
PDP11.aOpsXnnn_1170 = [
PDP11.op0Xnn_1170, // 0x0nnn
PDP11.opMOV, // 0x1nnn MOV 01SSDD
PDP11.opCMP, // 0x2nnn CMP 02SSDD
PDP11.opBIT, // 0x3nnn BIT 03SSDD
PDP11.opBIC, // 0x4nnn BIC 04SSDD
PDP11.opBIS, // 0x5nnn BIS 05SSDD
PDP11.opADD, // 0x6nnn ADD 06SSDD
PDP11.opMOV, // 0x1nnn 01SSDD
PDP11.opCMP, // 0x2nnn 02SSDD
PDP11.opBIT, // 0x3nnn 03SSDD
PDP11.opBIC, // 0x4nnn 04SSDD
PDP11.opBIS, // 0x5nnn 05SSDD
PDP11.opADD, // 0x6nnn 06SSDD
PDP11.op7Xnn_1170, // 0x7nnn
PDP11.op8Xnn_1170, // 0x8nnn
PDP11.opMOVB, // 0x9nnn MOVB 11SSDD
PDP11.opCMPB, // 0xAnnn CMPB 12SSDD
PDP11.opBITB, // 0xBnnn BITB 13SSDD
PDP11.opBICB, // 0xCnnn BICB 14SSDD
PDP11.opBISB, // 0xDnnn BISB 15SSDD
PDP11.opSUB, // 0xEnnn SUB 16SSDD
PDP11.opMOVB, // 0x9nnn 11SSDD
PDP11.opCMPB, // 0xAnnn 12SSDD
PDP11.opBITB, // 0xBnnn 13SSDD
PDP11.opBICB, // 0xCnnn 14SSDD
PDP11.opBISB, // 0xDnnn 15SSDD
PDP11.opSUB, // 0xEnnn 16SSDD
PDP11.opUndefined // 0xFnnn
];
@ -1613,10 +1611,10 @@ PDP11.aOps00Xn_1170 = [
PDP11.opUndefined, // 0x005n
PDP11.opUndefined, // 0x006n
PDP11.opUndefined, // 0x007n
PDP11.opUndefined, // 0x008n
PDP11.opUndefined, // 0x009n
PDP11.op00AX_1170, // 0x00An
PDP11.op00BX_1170, // 0x00Bn
PDP11.opRTS, // 0x008n 00020R (technically, bit 3 should also be CLR for the RTS opCode)
PDP11.opSPL, // 0x009n 00023N (technically, bit 3 should also be SET for the SPL opCode)
PDP11.op00AX_1170, // 0x00An 000240-000257
PDP11.op00BX_1170, // 0x00Bn 000260-000277
PDP11.opUndefined, // 0x00Cn
PDP11.opUndefined, // 0x00Dn
PDP11.opUndefined, // 0x00En
@ -1624,7 +1622,7 @@ PDP11.aOps00Xn_1170 = [
];
PDP11.aOps00AX_1170 = [
PDP11.opNOP, // 0x00A0
PDP11.opNOP, // 0x00A0 000240
PDP11.opCLC, // 0x00A1
PDP11.opCLV, // 0x00A2
PDP11.opCLx, // 0x00A3
@ -1639,11 +1637,11 @@ PDP11.aOps00AX_1170 = [
PDP11.opCLx, // 0x00AC
PDP11.opCLx, // 0x00AD
PDP11.opCLx, // 0x00AE
PDP11.opCLx // 0x00AF
PDP11.opCLx // 0x00AF 000257
];
PDP11.aOps00BX_1170 = [
PDP11.opNOP, // 0x00B0
PDP11.opNOP, // 0x00B0 000260
PDP11.opSEC, // 0x00B1
PDP11.opSEV, // 0x00B2
PDP11.opSEx, // 0x00B3
@ -1658,7 +1656,7 @@ PDP11.aOps00BX_1170 = [
PDP11.opSEx, // 0x00BC
PDP11.opSEx, // 0x00BD
PDP11.opSEx, // 0x00BE
PDP11.opSEx // 0x00BF
PDP11.opSEx // 0x00BF 000277
];
PDP11.aOps000X_1170 = [

View file

@ -1469,21 +1469,15 @@ CPUStatePDP11.prototype.writeByteByMode = function(addressMode, data, writeFlags
};
/**
* branch(PC, instruction)
* branch(opCode)
*
* @this {CPUStatePDP11}
* @param {number} PC
* @param {number} instruction
* @return {number}
* @param {number} opCode
* @return {number} (PC +/- the word delta specified in the opCode)
*/
CPUStatePDP11.prototype.branch = function(PC, instruction)
CPUStatePDP11.prototype.branch = function(opCode)
{
if (instruction & 0x80) { /*0200*/
instruction |= 0xff00;
} else {
instruction &= 0xff;
}
return ((instruction << 1) + PC) & 0xffff;
return (this.regsGen[PDP11.REG.PC] + ((opCode << 24) >> 23)) & 0xffff;
};
/**
@ -1972,70 +1966,70 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
// switch (opCode & 0xFF00) /*0177400*/ { // Program control instructions & traps
// case 0x100: /*0000400*/ // BR
// //LOG_INSTRUCTION(opCode, 4, "BR");
// this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// this.regsGen[7] = this.branch(opCode);
// break;
// case 0x200: /*0001000*/ // BNE
// //LOG_INSTRUCTION(opCode, 4, "BNE");
// if (this.flagZ & 0xffff) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if (this.flagZ & 0xffff) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x300: /*0001400*/ // BEQ
// //LOG_INSTRUCTION(opCode, 4, "BEQ");
// if (!(this.flagZ & 0xffff)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if (!(this.flagZ & 0xffff)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x400: /*0002000*/ // BGE
// //LOG_INSTRUCTION(opCode, 4, "BGE");
// if ((this.flagN & 0x8000) ===
// (this.flagV & 0x8000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// (this.flagV & 0x8000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x500: /*0002400*/ // BLT
// //LOG_INSTRUCTION(opCode, 4, "BLT");
// if ((this.flagN & 0x8000) !==
// (this.flagV & 0x8000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// (this.flagV & 0x8000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x600: /*0003000*/ // BGT
// //LOG_INSTRUCTION(opCode, 4, "BGT");
// if ((this.flagZ & 0xffff) && ((this.flagN & 0x8000) ===
// (this.flagV & 0x8000))) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// (this.flagV & 0x8000))) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x700: /*0003400*/ // BLE
// //LOG_INSTRUCTION(opCode, 4, "BLE");
// if (!(this.flagZ & 0xffff) || ((this.flagN & 0x8000) !==
// (this.flagV & 0x8000))) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// (this.flagV & 0x8000))) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8000: /*0100000*/ // BPL
// //LOG_INSTRUCTION(opCode, 4, "BPL");
// if (!(this.flagN & 0x8000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if (!(this.flagN & 0x8000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8200: /*0101000*/ // BHI
// //LOG_INSTRUCTION(opCode, 4, "BHI");
// if (!(this.flagC & 0x10000) &&
// (this.flagZ & 0xffff)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// (this.flagZ & 0xffff)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8100: /*0100400*/ // BMI
// //LOG_INSTRUCTION(opCode, 4, "BMI");
// if ((this.flagN & 0x8000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if ((this.flagN & 0x8000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8300: /*0101400*/ // BLOS
// //LOG_INSTRUCTION(opCode, 4, "BLOS");
// if ((this.flagC & 0x10000) ||
// !(this.flagZ & 0xffff)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// !(this.flagZ & 0xffff)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8400: /*0102000*/ // BVC
// //LOG_INSTRUCTION(opCode, 4, "BVC");
// if (!(this.flagV & 0x8000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if (!(this.flagV & 0x8000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8500: /*0102400*/ // BVS
// //LOG_INSTRUCTION(opCode, 4, "BVS");
// if ((this.flagV & 0x8000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if ((this.flagV & 0x8000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8600: /*0103000*/ // BCC
// //LOG_INSTRUCTION(opCode, 4, "BCC");
// if (!(this.flagC &
// 0x10000)) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// 0x10000)) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8700: /*0103400*/ // BCS
// //LOG_INSTRUCTION(opCode, 4, "BCS");
// if (this.flagC & 0x10000) this.regsGen[7] = this.branch(this.regsGen[7], opCode);
// if (this.flagC & 0x10000) this.regsGen[7] = this.branch(opCode);
// break;
// case 0x8800: /*0104000*/ // EMT 104000 -> 104377
// //LOG_INSTRUCTION(opCode, 7, "EMT");

View file

@ -2728,11 +2728,16 @@ if (DEBUGGER) {
var data = 0, iByte = 0, i;
var sData = "", sChars = "";
sAddr = this.toStrAddr(dbgAddr);
for (i = 16; i > 0 && cb > 0; i--) {
/*
* It's just coincidence that we want to dump 8 bytes per line when using base 8 and 16 bytes
* per line when using base 16, because octal requires more digits.
*/
var nBytes = (size == 4? 16 : this.nBase);
for (i = nBytes; i > 0 && cb > 0; i--) {
var b = this.getByte(dbgAddr, 1);
data |= (b << (iByte++ << 3));
if (iByte == size) {
sData += str.toHex(data, size * 2);
sData += (this.nBase == 8? str.toOct(data, size * 3) : str.toHex(data, size * 2));
sData += (size == 1? (i == 9? '-' : ' ') : " ");
data = iByte = 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long