Minor annotation and name changes; the PDP11 emulator "branded" as PDP11js now, since PDP11 is too generic
This commit is contained in:
parent
f0d18af735
commit
483d247491
13 changed files with 137 additions and 135 deletions
|
|
@ -73,28 +73,15 @@ function CPUStatePDP11(parmsCPU)
|
|||
|
||||
CPUPDP11.call(this, parmsCPU, nCyclesDefault);
|
||||
|
||||
/*
|
||||
* Initialize processor operation to match the requested model
|
||||
*/
|
||||
this.initProcessor();
|
||||
|
||||
/*
|
||||
* A variety of stepCPU() state variables that don't strictly need to be initialized before the first
|
||||
* stepCPU() call, but it's good form to do so.
|
||||
*/
|
||||
this.resetCycles();
|
||||
this.flags.fComplete = this.flags.fDebugCheck = false;
|
||||
|
||||
/*
|
||||
* If there are no live registers to display, then updateStatus() can skip a bit....
|
||||
*/
|
||||
this.cLiveRegs = 0;
|
||||
|
||||
/*
|
||||
* This initRegs() call is important to create all the registers, so that if/when we call restore(),
|
||||
* it will have something to fill in.
|
||||
* Initialize processor operation to match the requested model
|
||||
*/
|
||||
this.initRegs();
|
||||
this.initProcessor();
|
||||
}
|
||||
|
||||
Component.subclass(CPUStatePDP11, CPUPDP11);
|
||||
|
|
@ -113,6 +100,13 @@ Component.subclass(CPUStatePDP11, CPUPDP11);
|
|||
CPUStatePDP11.prototype.initProcessor = function()
|
||||
{
|
||||
this.aOps = PDP11.aOpsPDP1170;
|
||||
this.initRegs();
|
||||
/*
|
||||
* A variety of stepCPU() state variables that don't strictly need to be initialized before the first
|
||||
* stepCPU() call, but it's good form to do so.
|
||||
*/
|
||||
this.resetCycles();
|
||||
this.flags.fComplete = this.flags.fDebugCheck = false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -269,7 +263,6 @@ CPUStatePDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sVal
|
|||
switch (sBinding) {
|
||||
case "PC":
|
||||
case "PSW":
|
||||
case "IF":
|
||||
case "SF":
|
||||
case "ZF":
|
||||
case "CF":
|
||||
|
|
@ -298,11 +291,11 @@ CPUStatePDP11.prototype.clearCF = function()
|
|||
* getCF()
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @return {number} 0 or 1 (PDP11.PS.CF)
|
||||
* @return {number} 0 or 1 (PDP11.PSW.CF)
|
||||
*/
|
||||
CPUStatePDP11.prototype.getCF = function()
|
||||
{
|
||||
return (this.resultZeroCarry & 0x100)? PDP11.PS.CF : 0;
|
||||
return (this.resultZeroCarry & 0x100)? PDP11.PSW.CF : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -340,11 +333,11 @@ CPUStatePDP11.prototype.clearZF = function()
|
|||
* getZF()
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @return {number} 0 or PDP11.PS.ZF
|
||||
* @return {number} 0 or PDP11.PSW.ZF
|
||||
*/
|
||||
CPUStatePDP11.prototype.getZF = function()
|
||||
{
|
||||
return (this.resultZeroCarry & 0xff)? 0 : PDP11.PS.ZF;
|
||||
return (this.resultZeroCarry & 0xff)? 0 : PDP11.PSW.ZF;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -371,11 +364,11 @@ CPUStatePDP11.prototype.clearSF = function()
|
|||
* getSF()
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @return {number} 0 or PDP11.PS.SF
|
||||
* @return {number} 0 or PDP11.PSW.SF
|
||||
*/
|
||||
CPUStatePDP11.prototype.getSF = function()
|
||||
{
|
||||
// return (this.resultParitySign & 0x80)? PDP11.PS.SF : 0;
|
||||
// return (this.resultParitySign & 0x80)? PDP11.PSW.SF : 0;
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
|
@ -419,7 +412,7 @@ CPUStatePDP11.prototype.setPC = function(addr)
|
|||
*/
|
||||
CPUStatePDP11.prototype.getPSW = function()
|
||||
{
|
||||
return (this.PSW & ~PDP11.PS.RESULT) | (this.getSF() | this.getZF() | this.getCF());
|
||||
return (this.PSW & ~PDP11.PSW.RESULT) | (this.getSF() | this.getZF() | this.getCF());
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -513,11 +506,11 @@ CPUStatePDP11.prototype.updateStatus = function(fForce)
|
|||
{
|
||||
if (this.cLiveRegs) {
|
||||
if (fForce || !this.flags.fRunning || this.flags.fDisplayLiveRegs) {
|
||||
var regPS = this.getPSW();
|
||||
this.updateReg("PSW", regPS, 4);
|
||||
this.updateReg("SF", (regPS & PDP11.PS.SF)? 1 : 0, 1);
|
||||
this.updateReg("ZF", (regPS & PDP11.PS.ZF)? 1 : 0, 1);
|
||||
this.updateReg("CF", (regPS & PDP11.PS.CF)? 1 : 0, 1);
|
||||
var regPSW = this.getPSW();
|
||||
this.updateReg("PSW", regPSW, 4);
|
||||
this.updateReg("SF", (regPSW & PDP11.PSW.SF)? 1 : 0, 1);
|
||||
this.updateReg("ZF", (regPSW & PDP11.PSW.ZF)? 1 : 0, 1);
|
||||
this.updateReg("CF", (regPSW & PDP11.PSW.CF)? 1 : 0, 1);
|
||||
}
|
||||
}
|
||||
var controlSpeed = this.bindings["speed"];
|
||||
|
|
@ -535,10 +528,11 @@ CPUStatePDP11.prototype.updateStatus = function(fForce)
|
|||
* If the current state is WAIT (runState === 2) then skip any delay and
|
||||
* go into RUN state.
|
||||
*
|
||||
* @param delay
|
||||
* @param priority
|
||||
* @param vector
|
||||
* @param callback
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} delay
|
||||
* @param {number} priority
|
||||
* @param {number} vector
|
||||
* @param {function()} callback
|
||||
*/
|
||||
CPUStatePDP11.prototype.interrupt = function(delay, priority, vector, callback)
|
||||
{
|
||||
|
|
@ -603,14 +597,14 @@ CPUStatePDP11.prototype.writePSW = function(newPSW)
|
|||
for (i = 0; i < 6; i++) {
|
||||
j = this.registerVal[i];
|
||||
this.registerVal[i] = this.registerAlt[i];
|
||||
this.registerAlt[i] = j; // swap to alternate register set
|
||||
this.registerAlt[i] = j; // swap to alternate register set
|
||||
}
|
||||
}
|
||||
if ((this.mmuMode = (newPSW >> 14) & 3) !== (j = (this.PSW >> 14) & 3)) {
|
||||
if ((this.mmuMode = (newPSW >> 14) & 3) !== ((this.PSW >> 14) & 3)) {
|
||||
this.stackPointer[j] = this.registerVal[6];
|
||||
this.registerVal[6] = this.stackPointer[this.mmuMode]; // swap to new mode SP
|
||||
}
|
||||
this.priorityReview = 2; // trigger check of priority levels
|
||||
this.priorityReview = 2; // trigger check of priority levels
|
||||
this.PSW = newPSW;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,13 +39,14 @@
|
|||
var APPCLASS = "pdp11"; // this @define is the default application class (eg, "pcx86", "c1pjs")
|
||||
|
||||
/**
|
||||
* APPNAME is used more for display purposes than anything else now. APPCLASS is what matters in terms
|
||||
* of folder and file names, CSS styles, etc.
|
||||
*
|
||||
* @define {string}
|
||||
*/
|
||||
var APPNAME = "PDP11"; // this @define is the default application name (eg, "PCx86", "C1Pjs")
|
||||
var APPNAME = "PDP11js"; // this @define is the default application name (eg, "PCx86", "C1Pjs")
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*
|
||||
* WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.
|
||||
* In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,
|
||||
* nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a
|
||||
|
|
@ -55,16 +56,18 @@ var APPNAME = "PDP11"; // this @define is the default application name
|
|||
* However, when we're in "development mode" and running uncompiled code in debugger-less configurations,
|
||||
* I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file
|
||||
* (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.
|
||||
*
|
||||
* @define {boolean}
|
||||
*/
|
||||
var DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*
|
||||
* BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,
|
||||
* where each a number represents ONE byte; very wasteful, but potentially slightly faster.
|
||||
*
|
||||
* See the Memory component for details.
|
||||
*
|
||||
* @define {boolean}
|
||||
*/
|
||||
var BYTEARRAYS = false;
|
||||
|
||||
|
|
@ -121,9 +124,9 @@ var PDP11 = {
|
|||
ADDR_INVALID: -1,
|
||||
|
||||
/*
|
||||
* Processor Status flag definitions (stored in regPS)
|
||||
* Processor Status flag definitions (stored in regPSW)
|
||||
*/
|
||||
PS: {
|
||||
PSW: {
|
||||
CF: 0x0001, // bit 0: Carry Flag
|
||||
OF: 0x0002, // bit 1: Overflow Flag
|
||||
ZF: 0x0004, // bit 2: Zero Flag
|
||||
|
|
@ -165,10 +168,10 @@ var PDP11 = {
|
|||
};
|
||||
|
||||
/*
|
||||
* PS "arithmetic" flags are NOT stored in the PS register; they are maintained across separate result registers,
|
||||
* PSW "arithmetic" flags are NOT stored in the PSW register; they are maintained across separate result registers,
|
||||
* hence the RESULT designation.
|
||||
*/
|
||||
PDP11.PS.RESULT = (PDP11.PS.CF | PDP11.PS.ZF | PDP11.PS.SF);
|
||||
PDP11.PSW.RESULT = (PDP11.PSW.CF | PDP11.PSW.ZF | PDP11.PSW.SF);
|
||||
|
||||
if (NODE) {
|
||||
global.APPCLASS = APPCLASS;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
if (NODE) {
|
||||
var Component = require("./component");
|
||||
var str = require("./strlib");
|
||||
var web = require("./weblib");
|
||||
var str = require("./strlib");
|
||||
var web = require("./weblib");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -55,7 +55,7 @@ var fAsync = true;
|
|||
var cAsyncMachines = 0;
|
||||
|
||||
/**
|
||||
* loadXML(sFile, idMachine, sAppClass, sParms, fResolve, display, done)
|
||||
* loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)
|
||||
*
|
||||
* This is the preferred way to load all XML and XSL files. It uses getResource()
|
||||
* to load them as strings, which parseXML() can massage before parsing/transforming them.
|
||||
|
|
@ -80,13 +80,14 @@ var cAsyncMachines = 0;
|
|||
*
|
||||
* @param {string} sXMLFile
|
||||
* @param {string|null|undefined} idMachine
|
||||
* @param {string|null|undefined} sAppName
|
||||
* @param {string|null|undefined} sAppClass
|
||||
* @param {string|null|undefined} sParms
|
||||
* @param {boolean} fResolve is true to resolve any "ref" attributes
|
||||
* @param {function(string)} display
|
||||
* @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)
|
||||
*/
|
||||
function loadXML(sXMLFile, idMachine, sAppClass, sParms, fResolve, display, done)
|
||||
function loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)
|
||||
{
|
||||
var doneLoadXML = function(sURLName, sXML, nErrorCode) {
|
||||
if (nErrorCode) {
|
||||
|
|
@ -94,14 +95,14 @@ function loadXML(sXMLFile, idMachine, sAppClass, sParms, fResolve, display, done
|
|||
done(sXML, null);
|
||||
return;
|
||||
}
|
||||
parseXML(sXML, sXMLFile, idMachine, sAppClass, sParms, fResolve, display, done);
|
||||
parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done);
|
||||
};
|
||||
display("Loading " + sXMLFile + "...");
|
||||
web.getResource(sXMLFile, null, fAsync, doneLoadXML);
|
||||
}
|
||||
|
||||
/**
|
||||
* parseXML(sXML, sXMLFile, idMachine, sAppClass, sParms, fResolve, display, done)
|
||||
* parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)
|
||||
*
|
||||
* Generates an XML document from an XML string. This function also provides a work-around for XSLT's
|
||||
* lack of support for the document() function (at least on some browsers), by replacing every reference
|
||||
|
|
@ -110,13 +111,14 @@ function loadXML(sXMLFile, idMachine, sAppClass, sParms, fResolve, display, done
|
|||
* @param {string} sXML
|
||||
* @param {string|null} sXMLFile
|
||||
* @param {string|null|undefined} idMachine
|
||||
* @param {string|null|undefined} sAppName
|
||||
* @param {string|null|undefined} sAppClass
|
||||
* @param {string|null|undefined} sParms
|
||||
* @param {boolean} fResolve is true to resolve any "ref" attributes; default is false
|
||||
* @param {function(string)} display
|
||||
* @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)
|
||||
*/
|
||||
function parseXML(sXML, sXMLFile, idMachine, sAppClass, sParms, fResolve, display, done)
|
||||
function parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)
|
||||
{
|
||||
var buildXML = function(sXML, sError) {
|
||||
if (sError) {
|
||||
|
|
@ -166,7 +168,6 @@ function parseXML(sXML, sXMLFile, idMachine, sAppClass, sParms, fResolve, displa
|
|||
* I'm trying to switch to a shared components.xsl (at least for all PC-class machines),
|
||||
* but in the interim, that means hacking the XSL file on the fly to reflect the actual class.
|
||||
*/
|
||||
var sAppName = sAppClass.toUpperCase().replace("X86", "x86").replace("JS", "js");
|
||||
sXML = sXML.replace(/(<xsl:variable name="APPNAME">).*?(<\/xsl:variable>)/, "$1" + sAppName + "$2");
|
||||
sXML = sXML.replace(/(<xsl:variable name="APPCLASS">).*?(<\/xsl:variable>)/, "$1" + sAppClass + "$2");
|
||||
|
||||
|
|
@ -329,11 +330,12 @@ function resolveXML(sXML, display, done)
|
|||
}
|
||||
|
||||
/**
|
||||
* embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
||||
* embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
||||
*
|
||||
* This allows to you embed a machine on a web page, by transforming the machine XML into HTML.
|
||||
*
|
||||
* @param {string} sName is the app name (eg, "PCjs")
|
||||
* @param {string} sAppName is the app name (eg, "PCx86")
|
||||
* @param {string} sAppClass is the app class (eg, "pcx86"); also known as the machine class
|
||||
* @param {string} sVersion is the app version (eg, "1.15.7")
|
||||
* @param {string} idMachine
|
||||
* @param {string} sXMLFile
|
||||
|
|
@ -341,7 +343,7 @@ function resolveXML(sXML, display, done)
|
|||
* @param {string} [sParms]
|
||||
* @return {boolean} true if successful, false if error
|
||||
*/
|
||||
function embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
||||
function embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
||||
{
|
||||
var eMachine, eWarning, fSuccess = true;
|
||||
|
||||
|
|
@ -402,7 +404,6 @@ function embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
|||
head.appendChild(style);
|
||||
}
|
||||
|
||||
var sAppClass = sName.toLowerCase(); // eg, "pcx86" or "c1pjs"
|
||||
if (!sXSLFile) {
|
||||
/*
|
||||
* Now that PCjs is an open-source project, we can make the following test more flexible,
|
||||
|
|
@ -518,13 +519,13 @@ function embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
|||
displayError("unable to transform XML: unsupported browser");
|
||||
}
|
||||
};
|
||||
loadXML(sXSLFile, null, sAppClass, null, false, displayMessage, transformXML);
|
||||
loadXML(sXSLFile, null, sAppName, sAppClass, null, false, displayMessage, transformXML);
|
||||
};
|
||||
|
||||
if (sXMLFile.charAt(0) != '<') {
|
||||
loadXML(sXMLFile, idMachine, sAppClass, sParms, true, displayMessage, processXML);
|
||||
loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, true, displayMessage, processXML);
|
||||
} else {
|
||||
parseXML(sXMLFile, null, idMachine, sAppClass, sParms, false, displayMessage, processXML);
|
||||
parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, false, displayMessage, processXML);
|
||||
}
|
||||
} else {
|
||||
displayError("missing machine element: " + idMachine);
|
||||
|
|
@ -546,7 +547,7 @@ function embedMachine(sName, sVersion, idMachine, sXMLFile, sXSLFile, sParms)
|
|||
function embedC1P(idMachine, sXMLFile, sXSLFile)
|
||||
{
|
||||
if (fAsync) web.enablePageEvents(false);
|
||||
return embedMachine("C1Pjs", APPVERSION, idMachine, sXMLFile, sXSLFile);
|
||||
return embedMachine("C1Pjs", "c1pjs", APPVERSION, idMachine, sXMLFile, sXSLFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -561,7 +562,7 @@ function embedC1P(idMachine, sXMLFile, sXSLFile)
|
|||
function embedPCx86(idMachine, sXMLFile, sXSLFile, sParms)
|
||||
{
|
||||
if (fAsync) web.enablePageEvents(false);
|
||||
return embedMachine("PCx86", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||
return embedMachine("PCx86", "pcx86", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -576,7 +577,7 @@ function embedPCx86(idMachine, sXMLFile, sXSLFile, sParms)
|
|||
function embedPC8080(idMachine, sXMLFile, sXSLFile, sParms)
|
||||
{
|
||||
if (fAsync) web.enablePageEvents(false);
|
||||
return embedMachine("PC8080", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||
return embedMachine("PC8080", "pc8080", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -591,12 +592,11 @@ function embedPC8080(idMachine, sXMLFile, sXSLFile, sParms)
|
|||
function embedPDP11(idMachine, sXMLFile, sXSLFile, sParms)
|
||||
{
|
||||
if (fAsync) web.enablePageEvents(false);
|
||||
return embedMachine("PDP11", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||
return embedMachine("PDP11js", "pdp11", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent the Closure Compiler from renaming functions we want to export,
|
||||
* by adding them as (named) properties of a global object.
|
||||
* Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.
|
||||
*/
|
||||
if (APPNAME == "C1Pjs") {
|
||||
window['embedC1P'] = embedC1P;
|
||||
|
|
@ -608,7 +608,7 @@ if (APPNAME == "PCx86") {
|
|||
if (APPNAME == "PC8080") {
|
||||
window['embedPC8080'] = embedPC8080;
|
||||
}
|
||||
if (APPNAME == "PDP11") {
|
||||
if (APPNAME == "PDP11js") {
|
||||
window['embedPDP11'] = embedPDP11;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue