Fixed ASRB and RORB instructions, added a new dump command ("ds"), and fixed timer function initialization
This commit is contained in:
parent
9fe3ba6e09
commit
eb6bf8a5a5
9 changed files with 434 additions and 408 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue