Added the ability to install external ROMs (eg, M9312 ROM images) into the IOPAGE

This commit is contained in:
Jeff 2016-11-05 12:01:56 -07:00 committed by Jeff Parsons
commit c67176eab0
25 changed files with 1143 additions and 346 deletions

View file

@ -252,7 +252,7 @@ FileDump.prototype.loadFile = function(sFile, iStart, nSkip, done)
var encoding = null;
var sExt = str.getExtension(sFile);
if (sExt == DumpAPI.FORMAT.JSON || sExt == DumpAPI.FORMAT.HEX || sExt == "lst") {
if (sExt == DumpAPI.FORMAT.JSON || sExt == DumpAPI.FORMAT.HEX || sExt == "lst" || sExt == "txt") {
encoding = "utf8";
}
var options = {encoding: encoding};
@ -343,7 +343,7 @@ FileDump.prototype.setData = function(buf, iStart, nSkip, sExt)
var b, i, j, s;
if (typeof buf == "string") {
var ab = [];
if (sExt == "lst") {
if (sExt == "lst" || sExt == "txt") {
ab = this.parseListing(buf);
}
else if (buf.indexOf('{') >= 0) {
@ -488,7 +488,7 @@ FileDump.prototype.dumpBuffer = function(sKey, buf, len, cbItem, offDump, nWidth
* correct load (and exec) addresses. For now, we're simply inferring that the first address parsed
* in parseListing() is both the load and exec address.
*/
var sAddr = str.toHexWord(this.addrLoad) + (nBase == 8? " /*" + str.toOct(this.addrLoad, 6) + "*/" : "");
var sAddr = str.toHexWord(this.addrLoad) + (nBase == 8? "/*" + str.toOct(this.addrLoad, 6) + "*/" : "");
sDump += this.dumpLine(2, '"load":' + sAddr + ',"exec":' + sAddr + ',');
}
sDump += this.dumpLine(2, (sKey? '"' + sKey + '":' : "") + this.sJSONWhitespace + chOpen);
@ -520,7 +520,7 @@ FileDump.prototype.dumpBuffer = function(sKey, buf, len, cbItem, offDump, nWidth
if (cbItem > 2) {
sLine += v;
} else {
sLine += str.toHexWord(v) + (nBase == 8? " /*" + str.toOct(v & 0xffff, 6) + "*/" : "");
sLine += str.toHexWord(v) + (nBase == 8? "/*" + str.toOct(v & 0xffff, 6) + "*/" : "");
}
}
else {

View file

@ -665,7 +665,7 @@ BusPDP11.prototype.addMemory = function(addr, size, type, controller)
if (type == MemoryPDP11.TYPE.RAM && !this.cbRAM) {
this.cbRAM += size;
}
this.status(str.toDec(size / 1024) + "Kb " + MemoryPDP11.TYPE_NAMES[type] + " at " + str.toOct(addr));
this.status((size >> 10) + "Kb " + MemoryPDP11.TYPE_NAMES[type] + " at " + str.toOct(addr));
return true;
}
@ -1270,24 +1270,26 @@ BusPDP11.prototype.getMemorySize = function(type)
* @param {function(number,number)|null|undefined} fnWriteByte
* @param {function(number)|null|undefined} fnReadWord
* @param {function(number,number)|null|undefined} fnWriteWord
* @param {string} [sName]
* @param {number} [msgCategory]
* @param {string} [sName]
* @return {boolean} (true if entire range successfully registered, false if any conflicts)
*/
BusPDP11.prototype.addIOHandlers = function(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, sName, msgCategory)
BusPDP11.prototype.addIOHandlers = function(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, msgCategory, sName)
{
for (var addr = start; addr <= end; addr += 2) {
var off = addr & BusPDP11.IOPAGE_MASK;
if (this.aIOHandlers[off] !== undefined) {
Component.warning("I/O address already registered: " + str.toHexLong(addr));
continue;
return false;
}
this.aIOHandlers[off] = [fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, sName || "unknown", msgCategory, false];
if (MAXDEBUG) this.log("addIOHandlers(" + str.toHexLong(addr) + ")");
}
return true;
};
/**
* addIOTable(component, table, msgCategory)
* addIOTable(component, table, msgCategory, sName)
*
* Add I/O notification handlers from the specified table (a batch version of addIOHandlers).
*
@ -1295,8 +1297,10 @@ BusPDP11.prototype.addIOHandlers = function(start, end, fnReadByte, fnWriteByte,
* @param {Component} component
* @param {Object} table
* @param {number} [msgCategory] (default is BUS)
* @param {string} [sName]
* @return {boolean} (true if entire range successfully registered, false if any conflicts)
*/
BusPDP11.prototype.addIOTable = function(component, table, msgCategory)
BusPDP11.prototype.addIOTable = function(component, table, msgCategory, sName)
{
for (var port in table) {
var addr = +port;
@ -1338,9 +1342,12 @@ BusPDP11.prototype.addIOTable = function(component, table, msgCategory)
var sReg = afn[4];
for (var iReg = 0; iReg < nRegs; iReg++, addr += 2) {
if (sReg && nRegs > 1) sReg = afn[4] + iReg;
this.addIOHandlers(addr, addr, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, sReg, msgCategory || MessagesPDP11.BUS);
if (!this.addIOHandlers(addr, addr, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, msgCategory || MessagesPDP11.BUS, sReg || sName)) {
return false;
}
}
}
return true;
};
/**

View file

@ -38,7 +38,8 @@ var MessagesPDP11 = {
FAULT: 0x00000020,
BUS: 0x00000040,
MEMORY: 0x00000080,
DEVICE: 0x00000100,
ROM: 0x00000100,
DEVICE: 0x00000200,
KEYBOARD: 0x00010000,
KEYS: 0x00020000,
DISK: 0x00200000,
@ -71,6 +72,7 @@ MessagesPDP11.CATEGORIES = {
"fault": MessagesPDP11.FAULT,
"bus": MessagesPDP11.BUS,
"memory": MessagesPDP11.MEMORY,
"rom": MessagesPDP11.ROM,
"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

View file

@ -33,12 +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 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 PDP11 = require("./defines");
var BusPDP11 = require("./bus");
var MemoryPDP11 = require("./memory");
var MessagesPDP11 = require("./messages");
}
/**
@ -51,11 +53,11 @@ if (NODE) {
* alias: physical alias address (null if none)
* file: name of ROM data file
*
* NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the
* ROM data file has finished loading (see doneLoad()).
* NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND
* the ROM data file has finished loading (see doneLoad()).
*
* Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received
* is the ROM you expected.
* Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM
* you received is the ROM you expected.
*
* @constructor
* @extends Component
@ -70,6 +72,7 @@ function ROMPDP11(parmsROM)
this.addrROM = parmsROM['addr'];
this.sizeROM = parmsROM['size'];
this.fRetainROM = false;
/*
* The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of
@ -260,7 +263,9 @@ ROMPDP11.prototype.initROM = function()
* whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,
* and Debugger users should know better.
*/
delete this.abInit;
if (!this.fRetainROM) {
delete this.abInit;
}
}
}
this.setReady();
@ -276,7 +281,24 @@ ROMPDP11.prototype.initROM = function()
*/
ROMPDP11.prototype.addROM = function(addr)
{
if (this.bus.addMemory(addr, this.sizeROM, MemoryPDP11.TYPE.ROM)) {
this.status(this.sizeROM + "-byte ROM at " + str.toOct(addr));
if (addr >= BusPDP11.IOPAGE_16BIT && addr < BusPDP11.IOPAGE_16BIT + BusPDP11.IOPAGE_LENGTH) {
/*
* This code has been added as a work-around to effectively allow us to install small ROMs into portions
* of the IOPAGE address space, by installing I/O handlers for the entire range that return the corresponding
* bytes of the current ROM image on reads, and ignore any writes (which I'm only assuming is how a typical
* ROM "device" deals with writes; if we remove the write handler, then writes will cause a fault).
*/
var IOTable = {
[addr]: [ROMPDP11.prototype.readROMByte, ROMPDP11.prototype.writeROMByte, null, null, null, this.sizeROM >> 1]
};
if (this.bus.addIOTable(this, IOTable, MessagesPDP11.ROM, this.idComponent)) {
this.fRetainROM = true;
return true;
}
}
else if (this.bus.addMemory(addr, this.sizeROM, MemoryPDP11.TYPE.ROM)) {
if (DEBUG) this.log("addROM(): copying ROM to " + str.toHexLong(addr) + " (" + str.toHexLong(this.abInit.length) + " bytes)");
var i;
for (i = 0; i < this.abInit.length; i++) {
@ -284,6 +306,7 @@ ROMPDP11.prototype.addROM = function(addr)
}
return true;
}
/*
* We don't need to report an error here, because addMemory() already takes care of that.
*/
@ -309,6 +332,30 @@ ROMPDP11.prototype.cloneROM = function(addr)
this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);
};
/**
* readROMByte(addr)
*
* @this {ROMPDP11}
* @param {number} addr
* @return {number}
*/
ROMPDP11.prototype.readROMByte = function(addr)
{
var i = (addr - this.addrROM);
return this.abInit[i];
};
/**
* writeROMByte(data, addr)
*
* @this {ROMPDP11}
* @param {number} data
* @param {number} addr
*/
ROMPDP11.prototype.writeROMByte = function(data, addr)
{
};
/**
* ROMPDP11.init()
*