Fixed ASRB and RORB instructions, added a new dump command ("ds"), and fixed timer function initialization

This commit is contained in:
Jeff 2016-11-10 06:10:54 -08:00 committed by Jeff Parsons
commit eb6bf8a5a5
9 changed files with 434 additions and 408 deletions

View file

@ -959,9 +959,12 @@ CPUPDP11.prototype.setTimer = function(iTimer, ms, fReset)
* We must now confront the following problem: if the CPU is currently executing a burst of cycles,
* the number of cycles it has executed in that burst so far must NOT be charged against the cycle
* timeout we're about to set. The simplest way to resolve that is to immediately call endBurst()
* and bias the above cycle timeout by the number of cycles that the burst executed.
* and bias the cycle timeout by the number of cycles that the burst executed.
*/
this.aTimers[iTimer][0] = nCycles + this.endBurst();
if (this.flags.running) {
nCycles += this.endBurst();
}
this.aTimers[iTimer][0] = nCycles;
}
}
return nCycles;
@ -992,6 +995,7 @@ CPUPDP11.prototype.getBurstCycles = function(nCycles)
{
for (var i = this.aTimers.length - 1; i >= 0; i--) {
var timer = this.aTimers[i];
this.assert(!isNaN(timer[0]));
if (timer[0] < 0) continue;
if (nCycles > timer[0]) {
nCycles = timer[0];
@ -1014,6 +1018,7 @@ CPUPDP11.prototype.updateTimers = function(nCycles)
{
for (var i = this.aTimers.length - 1; i >= 0; i--) {
var timer = this.aTimers[i];
this.assert(!isNaN(timer[0]));
if (timer[0] < 0) continue;
timer[0] -= nCycles;
if (timer[0] <= 0) {

View file

@ -140,7 +140,7 @@ PDP11.fnASR = function(src, dst)
*/
PDP11.fnASRB = function(src, dst)
{
var result = (dst & 0x800) | (dst >> 1) | (dst << 8);
var result = (dst & 0x80) | (dst >> 1) | (dst << 8);
this.updateShiftFlags(result << 8);
return result & 0xff;
};

View file

@ -2016,7 +2016,7 @@ CPUStatePDP11.prototype.updateDstByte = function(opCode, src, fnOp)
var reg = this.dstReg = opCode & PDP11.OPREG.MASK;
var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;
if (!mode) {
this.regsGen[reg] = (this.regsGen[reg] & 0xff00) | fnOp.call(this, src, this.regsGen[reg]);
this.regsGen[reg] = (this.regsGen[reg] & 0xff00) | fnOp.call(this, src, this.regsGen[reg] & 0xff);
} else {
var addr = this.dstAddr = this.getAddr(mode, reg, PDP11.ACCESS.UPDATE_BYTE);
this.writeByteToPhysical(addr, fnOp.call(this, src, this.readByteFromPhysical(addr)));

View file

@ -2946,8 +2946,13 @@ if (DEBUGGER) {
if (!dbgAddr) return;
var len = 0; // 0 is not a default; it triggers the appropriate default below
var fRange = false;
var fJSON = (sCmd == "ds");
if (sLen) {
fRange = true;
if (sLen.charAt(0) == 'l') {
fRange = false;
sLen = sLen.substr(1) || sBytes;
}
len = this.parseValue(sLen) >>> 0; // negative lengths not allowed
@ -2959,8 +2964,9 @@ if (DEBUGGER) {
* since this is primarily a word-oriented machine.
*/
var size = (sCmd == "dd"? 4 : (sCmd == "db"? 1 : 2));
var nBytes = (size * len) || 128;
var nLines = ((nBytes + 15) >> 4) || 1;
var nBytes = (fRange? (len - dbgAddr.addr) : (size * len)) || 128;
var nBytesPerLine = fJSON? 16 : this.nBase;
var nLines = (((nBytes + nBytesPerLine - 1) / nBytesPerLine)|0) || 1;
var sDump = "";
while (nLines-- && nBytes > 0) {
@ -2977,20 +2983,29 @@ if (DEBUGGER) {
*/
var i, n;
var data = 0, shift = 0;
for (i = this.nBase; i > 0 && nBytes > 0; i -= n, nBytes -= n) {
for (i = nBytesPerLine; i > 0 && nBytes > 0; i -= n, nBytes -= n) {
n = 1;
var v = size == 1? this.getByte(dbgAddr, n) : this.getWord(dbgAddr, (n = 2));
data |= (v << (shift << 3));
shift += n;
if (shift == size) {
sData += this.toStrBase(data, size);
sData += (size == 1? (i == 9? '-' : ' ') : " ");
if (fJSON) {
if (sData) sData += ",";
sData += "0x"+ str.toHex(data, size * 2);
} else {
sData += this.toStrBase(data, size);
sData += (size == 1? (i == 9? '-' : ' ') : " ");
}
data = shift = 0;
}
sChars += (v >= 32 && v < 128? String.fromCharCode(v) : '.');
}
if (sDump) sDump += '\n';
sDump += sAddr + " " + sData + ((i == 0)? (' ' + sChars) : "");
if (sDump) sDump += "\n";
if (fJSON) {
sDump += sData + ",";
} else {
sDump += sAddr + " " + sData + ((i == 0)? (' ' + sChars) : "");
}
}
if (sDump) this.println(sDump);

View file

@ -42,7 +42,8 @@ var MessagesPDP11 = {
DEVICE: 0x00000200,
KEYBOARD: 0x00010000,
KEYS: 0x00020000,
DISK: 0x00200000,
PAPER: 0x00100000,
DISK: 0x00400000,
SERIAL: 0x00800000,
SPEAKER: 0x02000000,
COMPUTER: 0x04000000,
@ -76,6 +77,7 @@ MessagesPDP11.CATEGORIES = {
"device": MessagesPDP11.DEVICE,
"keyboard": MessagesPDP11.KEYBOARD, // "kbd" is also allowed as shorthand for "keyboard"; see doMessages()
"key": MessagesPDP11.KEYS, // using "key" instead of "keys", since the latter is a method on JavasScript objects
"paper": MessagesPDP11.PAPER,
"disk": MessagesPDP11.DISK,
"serial": MessagesPDP11.SERIAL,
"speaker": MessagesPDP11.SPEAKER,

View file

@ -33,13 +33,14 @@
"use strict";
if (NODE) {
var str = require("../../shared/lib/strlib");
var web = require("../../shared/lib/weblib");
var DumpAPI = require("../../shared/lib/dumpapi");
var Component = require("../../shared/lib/component");
var State = require("../../shared/lib/state");
var PDP11 = require("./defines");
var MemoryPDP11 = require("./memory");
var str = require("../../shared/lib/strlib");
var web = require("../../shared/lib/weblib");
var DumpAPI = require("../../shared/lib/dumpapi");
var Component = require("../../shared/lib/component");
var State = require("../../shared/lib/state");
var PDP11 = require("./defines");
var MemoryPDP11 = require("./memory");
var MessagesPDP11 = require("./messages");
}
/**
@ -254,8 +255,8 @@ RAMPDP11.prototype.reset = function()
/**
* loadImage(aBytes, addrLoad, addrExec, addrInit, fReset)
*
* If the array contains an image in the "Absolute Format," load it as specified by
* the format; otherwise, load it as-is using the address(es) supplied.
* If the array contains a PAPER tape image in the "Absolute Format," load it as specified
* by the format; otherwise, load it as-is using the address(es) supplied.
*
* @this {RAMPDP11}
* @param {Array|Uint8Array} aBytes
@ -339,7 +340,9 @@ RAMPDP11.prototype.loadImage = function(aBytes, addrLoad, addrExec, addrInit, fR
} else {
if (addrExec == null) addrExec = addr;
}
if (addrExec != null) this.printMessage("starting address: " + str.toHexWord(addrExec), MessagesPDP11.PAPER);
} else {
this.printMessage("loading " + str.toHexWord(cbData) + " bytes at " + str.toHexWord(addr) + "-" + str.toHexWord(addr + cbData - 1), MessagesPDP11.PAPER);
while (cbData--) {
this.cpu.setByteDirect(addr++, aBytes[offData++] & 0xff);
}
@ -361,9 +364,9 @@ RAMPDP11.prototype.loadImage = function(aBytes, addrLoad, addrExec, addrInit, fR
* Set the start address to whatever the caller provided, or failing that, whatever start
* address was specified inside the image.
*
* For example, the diagnostic "MAINDEC-11-D0AA-PB" doesn't include a start address inside
* the image, but because we know that the directions for that diagnostic say to "Start and
* Restart at 200", we have manually inserted an "exec":128 in the JSON containing the image.
* For example, the diagnostic "MAINDEC-11-D0AA-PB" doesn't include a start address inside the
* image, but we know that the directions for that diagnostic say to "Start and Restart at 200",
* so we have manually inserted an "exec":128 in the JSON containing the image.
*/
if (addrExec != null) this.cpu.setReset(addrExec, fReset);
}