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

@ -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()
*