From 4b778b281d2abbe492292f0102ff8ac03d04b937 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Sat, 3 Sep 2016 17:43:06 -0700 Subject: [PATCH] Groundwork for a PDP-11 emulator (starting with a gutted copy of PC8080) --- Gruntfile.js | 85 +- devices/pdp11/machine/1170/test/machine.xml | 10 + devices/pdp11/panel/1170/wide.xml | 27 + modules/htmlout/lib/htmlout.js | 6 +- modules/markout/lib/markout.js | 2 +- modules/pc8080/lib/bus.js | 10 +- modules/pc8080/lib/chipset.js | 2 +- modules/pc8080/lib/computer.js | 2 +- modules/pc8080/lib/cpu.js | 12 +- modules/pc8080/lib/cpudef.js | 6 +- modules/pc8080/lib/cpuops.js | 488 +-- modules/pc8080/lib/cpustate.js | 302 +- modules/pc8080/lib/debugger.js | 4 +- modules/pc8080/lib/keyboard.js | 2 +- modules/pc8080/lib/panel.js | 2 +- modules/pc8080/lib/ram.js | 2 +- modules/pc8080/lib/rom.js | 2 +- modules/pc8080/lib/serialport.js | 2 +- modules/pc8080/lib/video.js | 2 +- modules/pdp11/lib/bus.js | 767 ++++ modules/pdp11/lib/computer.js | 1595 +++++++ modules/pdp11/lib/cpu.js | 1228 ++++++ modules/pdp11/lib/cpudef.js | 115 + modules/pdp11/lib/cpuops.js | 124 + modules/pdp11/lib/cpustate.js | 1053 +++++ modules/pdp11/lib/debugger.js | 4219 +++++++++++++++++++ modules/pdp11/lib/defines.js | 108 + modules/pdp11/lib/keyboard.js | 295 ++ modules/pdp11/lib/memory.js | 826 ++++ modules/pdp11/lib/messages.js | 89 + modules/pdp11/lib/nodebugger.js | 48 + modules/pdp11/lib/panel.js | 185 + modules/pdp11/lib/ram.js | 199 + modules/pdp11/lib/rom.js | 391 ++ modules/shared/lib/embed.js | 18 + package.json | 28 +- versions/c1pjs/1.24.2/c1p-dbg.js | 166 + versions/c1pjs/1.24.2/c1p.js | 127 + versions/c1pjs/1.24.2/common.css | 265 ++ versions/c1pjs/1.24.2/common.xsl | 58 + versions/c1pjs/1.24.2/components.css | 108 + versions/c1pjs/1.24.2/components.xsl | 588 +++ versions/c1pjs/1.24.2/document.css | 162 + versions/c1pjs/1.24.2/document.xsl | 452 ++ versions/c1pjs/1.24.2/machine.xsl | 49 + versions/c1pjs/1.24.2/manifest.xsl | 247 ++ versions/c1pjs/1.24.2/outline.xsl | 47 + versions/pc8080/1.24.2/common.css | 265 ++ versions/pc8080/1.24.2/common.xsl | 58 + versions/pc8080/1.24.2/components.css | 159 + versions/pc8080/1.24.2/components.xsl | 1242 ++++++ versions/pc8080/1.24.2/document.css | 162 + versions/pc8080/1.24.2/document.xsl | 452 ++ versions/pc8080/1.24.2/machine.xsl | 49 + versions/pc8080/1.24.2/manifest.xsl | 247 ++ versions/pc8080/1.24.2/outline.xsl | 47 + versions/pc8080/1.24.2/pc8080-dbg.js | 245 ++ versions/pc8080/1.24.2/pc8080.js | 162 + versions/pcx86/1.24.2/common.css | 265 ++ versions/pcx86/1.24.2/common.xsl | 58 + versions/pcx86/1.24.2/components.css | 159 + versions/pcx86/1.24.2/components.xsl | 1242 ++++++ versions/pcx86/1.24.2/document.css | 162 + versions/pcx86/1.24.2/document.xsl | 452 ++ versions/pcx86/1.24.2/machine.xsl | 49 + versions/pcx86/1.24.2/manifest.xsl | 247 ++ versions/pcx86/1.24.2/outline.xsl | 47 + versions/pcx86/1.24.2/pcx86-dbg.js | 819 ++++ versions/pcx86/1.24.2/pcx86.js | 639 +++ versions/pdp11/1.24.2/common.css | 265 ++ versions/pdp11/1.24.2/common.xsl | 58 + versions/pdp11/1.24.2/components.css | 159 + versions/pdp11/1.24.2/components.xsl | 1242 ++++++ versions/pdp11/1.24.2/document.css | 162 + versions/pdp11/1.24.2/document.xsl | 452 ++ versions/pdp11/1.24.2/machine.xsl | 49 + versions/pdp11/1.24.2/manifest.xsl | 247 ++ versions/pdp11/1.24.2/outline.xsl | 47 + versions/pdp11/1.24.2/pdp11-dbg.js | 143 + versions/pdp11/1.24.2/pdp11.js | 81 + 80 files changed, 24230 insertions(+), 427 deletions(-) create mode 100644 devices/pdp11/machine/1170/test/machine.xml create mode 100644 devices/pdp11/panel/1170/wide.xml create mode 100644 modules/pdp11/lib/bus.js create mode 100644 modules/pdp11/lib/computer.js create mode 100644 modules/pdp11/lib/cpu.js create mode 100644 modules/pdp11/lib/cpudef.js create mode 100644 modules/pdp11/lib/cpuops.js create mode 100644 modules/pdp11/lib/cpustate.js create mode 100644 modules/pdp11/lib/debugger.js create mode 100644 modules/pdp11/lib/defines.js create mode 100644 modules/pdp11/lib/keyboard.js create mode 100644 modules/pdp11/lib/memory.js create mode 100644 modules/pdp11/lib/messages.js create mode 100644 modules/pdp11/lib/nodebugger.js create mode 100644 modules/pdp11/lib/panel.js create mode 100644 modules/pdp11/lib/ram.js create mode 100644 modules/pdp11/lib/rom.js create mode 100644 versions/c1pjs/1.24.2/c1p-dbg.js create mode 100644 versions/c1pjs/1.24.2/c1p.js create mode 100644 versions/c1pjs/1.24.2/common.css create mode 100644 versions/c1pjs/1.24.2/common.xsl create mode 100644 versions/c1pjs/1.24.2/components.css create mode 100644 versions/c1pjs/1.24.2/components.xsl create mode 100644 versions/c1pjs/1.24.2/document.css create mode 100644 versions/c1pjs/1.24.2/document.xsl create mode 100644 versions/c1pjs/1.24.2/machine.xsl create mode 100644 versions/c1pjs/1.24.2/manifest.xsl create mode 100644 versions/c1pjs/1.24.2/outline.xsl create mode 100644 versions/pc8080/1.24.2/common.css create mode 100644 versions/pc8080/1.24.2/common.xsl create mode 100644 versions/pc8080/1.24.2/components.css create mode 100644 versions/pc8080/1.24.2/components.xsl create mode 100644 versions/pc8080/1.24.2/document.css create mode 100644 versions/pc8080/1.24.2/document.xsl create mode 100644 versions/pc8080/1.24.2/machine.xsl create mode 100644 versions/pc8080/1.24.2/manifest.xsl create mode 100644 versions/pc8080/1.24.2/outline.xsl create mode 100644 versions/pc8080/1.24.2/pc8080-dbg.js create mode 100644 versions/pc8080/1.24.2/pc8080.js create mode 100644 versions/pcx86/1.24.2/common.css create mode 100644 versions/pcx86/1.24.2/common.xsl create mode 100644 versions/pcx86/1.24.2/components.css create mode 100644 versions/pcx86/1.24.2/components.xsl create mode 100644 versions/pcx86/1.24.2/document.css create mode 100644 versions/pcx86/1.24.2/document.xsl create mode 100644 versions/pcx86/1.24.2/machine.xsl create mode 100644 versions/pcx86/1.24.2/manifest.xsl create mode 100644 versions/pcx86/1.24.2/outline.xsl create mode 100644 versions/pcx86/1.24.2/pcx86-dbg.js create mode 100644 versions/pcx86/1.24.2/pcx86.js create mode 100644 versions/pdp11/1.24.2/common.css create mode 100644 versions/pdp11/1.24.2/common.xsl create mode 100644 versions/pdp11/1.24.2/components.css create mode 100644 versions/pdp11/1.24.2/components.xsl create mode 100644 versions/pdp11/1.24.2/document.css create mode 100644 versions/pdp11/1.24.2/document.xsl create mode 100644 versions/pdp11/1.24.2/machine.xsl create mode 100644 versions/pdp11/1.24.2/manifest.xsl create mode 100644 versions/pdp11/1.24.2/outline.xsl create mode 100644 versions/pdp11/1.24.2/pdp11-dbg.js create mode 100644 versions/pdp11/1.24.2/pdp11.js diff --git a/Gruntfile.js b/Gruntfile.js index 6e5ef85d4..91130b5d9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -118,13 +118,15 @@ module.exports = function(grunt) { * @property {Array.} c1pJSFiles * @property {Array.} pcX86Files * @property {Array.} pc8080Files + * @property {Array.} pdp11Files * @property {Array.} closureCompilerExterns */ var pkg = grunt.file.readJSON("package.json"); - var tmpC1Pjs = "./tmp/c1pjs/" + pkg.version + "/c1p.js"; - var tmpPCx86 = "./tmp/pcx86/" + pkg.version + "/pcx86.js"; + var tmpC1Pjs = "./tmp/c1pjs/" + pkg.version + "/c1p.js"; + var tmpPCx86 = "./tmp/pcx86/" + pkg.version + "/pcx86.js"; var tmpPC8080 = "./tmp/pc8080/" + pkg.version + "/pc8080.js"; + var tmpPDP11 = "./tmp/pdp11/" + pkg.version + "/pdp11.js"; grunt.initConfig({ pkg: pkg, // pass the "package.json" object to initConfig() as a property, too @@ -178,6 +180,19 @@ module.exports = function(grunt) { src: pkg.pc8080Files, dest: "./versions/pc8080/" + pkg.version + "/pc8080-dbg.js" }, + "pdp11.js": { + src: pkg.pdp11Files, + dest: "./versions/pdp11/" + pkg.version + "/pdp11.js", + options: { + process: function(src, filepath) { + return (path.basename(filepath) == "debugger.js"? "" : src); + } + } + }, + "pdp11-dbg.js": { + src: pkg.pdp11Files, + dest: "./versions/pdp11/" + pkg.version + "/pdp11-dbg.js" + }, "tmp-c1pjs": { src: pkg.c1pJSFiles, dest: tmpC1Pjs, @@ -210,8 +225,18 @@ module.exports = function(grunt) { src.replace(/(^|\n)[ \t]*(['"])use strict\2;?\s*/g, '$1').replace(/[ \t]*if\s*\(NODE\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '').replace(/[ \t]*if\s*\(typeof\s+(module|APP_PCJS)\s*!==\s*(['"])undefined\2\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '').replace(/[ \t]*[A-Za-z_][A-Za-z0-9_\.]*\.assert\([^\n]*\);[^\n]*/g, ''); } } + }, + "tmp-pdp11": { + src: pkg.pdp11Files, + dest: tmpPDP11, + options: { + banner: '"use strict";\n\n', + process: function(src, filepath) { + return "// " + filepath + "\n\n" + + src.replace(/(^|\n)[ \t]*(['"])use strict\2;?\s*/g, '$1').replace(/[ \t]*if\s*\(NODE\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '').replace(/[ \t]*if\s*\(typeof\s+(module|APP_PCJS)\s*!==\s*(['"])undefined\2\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, '').replace(/[ \t]*[A-Za-z_][A-Za-z0-9_\.]*\.assert\([^\n]*\);[^\n]*/g, ''); + } + } } - }, prepjs: { options: { @@ -231,7 +256,12 @@ module.exports = function(grunt) { "pc8080.js": { src: pkg.pc8080Files, dest: tmpPC8080 + }, + "pdp11.js": { + src: pkg.pdp11Files, + dest: tmpPDP11 } + }, closureCompiler: { options: { @@ -363,6 +393,33 @@ module.exports = function(grunt) { // src: pkg.pc8080Files, src: tmpPC8080, dest: "./versions/pc8080/" + pkg.version + "/pc8080-dbg.js" + }, + "pdp11.js": { + TEMPcompilerOpts: { + // create_source_map: "./tmp/pdp11/" + pkg.version + "/pdp11.map", + define: ["\"APPVERSION='" + pkg.version + "'\"", + "\"SITEHOST='www.pcjs.org'\"", "COMPILED=true", "DEBUG=false", "DEBUGGER=false"], + // output_wrapper: "\"(function(){%output%})();//@ sourceMappingURL=/tmp/pdp11/" + pkg.version + "/pdp11.map\"" + output_wrapper: "\"(function(){%output%})();\"" + }, + // src: pkg.pdp11Files, + src: tmpPDP11, + dest: "./versions/pdp11/" + pkg.version + "/pdp11.js" + }, + "pdp11-dbg.js": { + /* + * Technically, this is the one case we don't need to override the default 'define' settings, but maybe it's best to be explicit. + */ + TEMPcompilerOpts: { + // create_source_map: "./tmp/pdp11/" + pkg.version + "/pdp11-dbg.map", + define: ["\"APPVERSION='" + pkg.version + "'\"", + "\"SITEHOST='www.pcjs.org'\"", "COMPILED=true", "DEBUG=false", "DEBUGGER=true"], + // output_wrapper: "\"(function(){%output%})();//@ sourceMappingURL=/tmp/pdp11/" + pkg.version + "/pdp11-dbg.map\"" + output_wrapper: "\"(function(){%output%})();\"" + }, + // src: pkg.pdp11Files, + src: tmpPDP11, + dest: "./versions/pdp11/" + pkg.version + "/pdp11-dbg.js" } }, copy: { @@ -439,6 +496,26 @@ module.exports = function(grunt) { } } }, + "pdp11": { + files: [ + { + cwd: "modules/shared/templates/", + src: ["common.css", "common.xsl", "components.*", "document.css", "document.xsl", "machine.xsl", "manifest.xsl", "outline.xsl"], + dest: "versions/pdp11/<%= pkg.version %>/", + expand: true + } + ], + options: { + process: function(content, srcPath) { + var s = content.replace(/()[^<]*(<\/xsl:variable>)/g, "$1pdp11$2"); + s = s.replace(/()[^<]*(<\/xsl:variable>)/g, "$1PDP11$2"); + s = s.replace(/()[^<]*(<\/xsl:variable>)/g, "$1" + pkg.version + "$2"); + s = s.replace(/"[^"]*\/?(common.css|common.xsl|components.css|components.xsl|document.css|document.xsl)"/g, '"/versions/pdp11/' + pkg.version + '/$1"'); + s = s.replace(/[ \t]*\/\*[^\*][\s\S]*?\*\//g, "").replace(/[ \t]*[ \t]*\n?/g, ""); + return s; + } + } + }, "examples": { files: [ { @@ -559,7 +636,7 @@ module.exports = function(grunt) { grunt.loadTasks("modules/grunts/prepjs/tasks"); - grunt.registerTask("preCompiler", grunt.option("rebuild")? ["concat:tmp-c1pjs", "concat:tmp-pcx86", "concat:tmp-pc8080"] : ["newer:concat:tmp-c1pjs", "newer:concat:tmp-pcx86", "newer:concat:tmp-pc8080"]); + grunt.registerTask("preCompiler", grunt.option("rebuild")? ["concat:tmp-c1pjs", "concat:tmp-pcx86", "concat:tmp-pc8080", "concat:tmp-pdp11"] : ["newer:concat:tmp-c1pjs", "newer:concat:tmp-pcx86", "newer:concat:tmp-pc8080", "newer:concat:tmp-pdp11"]); grunt.registerTask("compile", ["preCompiler", "closureCompiler", "replace:fix-source-maps"]); diff --git a/devices/pdp11/machine/1170/test/machine.xml b/devices/pdp11/machine/1170/test/machine.xml new file mode 100644 index 000000000..61f86e6b7 --- /dev/null +++ b/devices/pdp11/machine/1170/test/machine.xml @@ -0,0 +1,10 @@ + + + + PDP-11/70 Test Machine + + + + + + diff --git a/devices/pdp11/panel/1170/wide.xml b/devices/pdp11/panel/1170/wide.xml new file mode 100644 index 000000000..3325bcbfa --- /dev/null +++ b/devices/pdp11/panel/1170/wide.xml @@ -0,0 +1,27 @@ + + + Control Panel + + + + + 0000 + + 0 + 0 + 0 + 0 + + Speed: + Stopped + + + + Enter + Clear + Run + Step + Reset + Fast + + diff --git a/modules/htmlout/lib/htmlout.js b/modules/htmlout/lib/htmlout.js index 906d6e134..f0431ebad 100644 --- a/modules/htmlout/lib/htmlout.js +++ b/modules/htmlout/lib/htmlout.js @@ -57,6 +57,7 @@ var usr = require("../../shared/lib/usrlib"); * @property {Array.} pcCSSFiles * @property {Array.} pcX86Files * @property {Array.} pc8080Files + * @property {Array.} pdp11Files */ var pkg = require("../../../package.json"); @@ -170,7 +171,8 @@ var aMachineFiles = { 'C1P': pkg.c1pCSSFiles.concat(pkg.c1pJSFiles), // will be deprecated when PC6502 becomes available 'PC': pkg.pcCSSFiles.concat(pkg.pcX86Files), // deprecated (same as PCx86) 'PCx86': pkg.pcCSSFiles.concat(pkg.pcX86Files), - 'PC8080': pkg.pcCSSFiles.concat(pkg.pc8080Files) + 'PC8080': pkg.pcCSSFiles.concat(pkg.pc8080Files), + 'PDP11': pkg.pcCSSFiles.concat(pkg.pdp11Files) }; var aMachineFileTypes = { 'head': [".css"], // put BOTH ".css" and ".js" here if convertMDMachineLinks() embeds its own scripts @@ -1437,7 +1439,7 @@ HTMLOut.prototype.getMachineXML = function(sToken, sIndent, aParms, sXMLFile, sS * The common denominator in both sets is either "/pc" or "/c1p", which in turn indicates the type of machine * (eg, "PC", "C1P", etc). */ - aMatch = sStyleSheet.match(/\/(pc|c1p)([^/]*)/); + aMatch = sStyleSheet.match(/\/(pc|c1p|pdp)([^/]*)/); if (aMatch) { var sMachineType = aMatch[1].toUpperCase() + (aMatch[2] != "js"? aMatch[2] : ""); /* diff --git a/modules/markout/lib/markout.js b/modules/markout/lib/markout.js index 28b543edd..7e2ec5c70 100644 --- a/modules/markout/lib/markout.js +++ b/modules/markout/lib/markout.js @@ -1168,7 +1168,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock) * Start looking for Markdown-style machine links now... */ var cMatches = 0; - var reMachines = /\[(.*?)]\((.*?)\s*"(PC|C1P)([^:!|]*)([:!|])(.*?)"\)/gi; + var reMachines = /\[(.*?)]\((.*?)\s*"(PC|C1P|PDP)([^:!|]*)([:!|])(.*?)"\)/gi; while ((aMatch = reMachines.exec(sBlock))) { diff --git a/modules/pc8080/lib/bus.js b/modules/pc8080/lib/bus.js index 824f8456b..64b4b963a 100644 --- a/modules/pc8080/lib/bus.js +++ b/modules/pc8080/lib/bus.js @@ -63,7 +63,7 @@ if (NODE) { * @constructor * @extends Component * @param {Object} parmsBus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ function Bus8080(parmsBus, cpu, dbg) @@ -191,7 +191,7 @@ var BlockInfo; Bus8080.BlockInfo = usr.defineBitFields({num:20, count:8, btmod:1, type:3}); /** - * Bus8080Info object definition (returned by scanMemory()) + * BusInfo8080 object definition (returned by scanMemory()) * * cbTotal: total bytes allocated * cBlocks: total Memory blocks allocated @@ -203,7 +203,7 @@ Bus8080.BlockInfo = usr.defineBitFields({num:20, count:8, btmod:1, type:3}); * aBlocks: Array. * }} */ -var Bus8080Info; +var BusInfo8080; /** * initMemory() @@ -364,10 +364,10 @@ Bus8080.prototype.cleanMemory = function(addr, size) /** * scanMemory(info, addr, size) * - * Returns a Bus8080Info object for the specified address range. + * Returns a BusInfo8080 object for the specified address range. * * @this {Bus8080} - * @param {Object} [info] previous Bus8080Info, if any + * @param {Object} [info] previous BusInfo8080, if any * @param {number} [addr] starting address of range (0 if none provided) * @param {number} [size] size of range, in bytes (up to end of address space if none provided) * @return {Object} updated info (or new info if no previous info provided) diff --git a/modules/pc8080/lib/chipset.js b/modules/pc8080/lib/chipset.js index 4f60fab87..7514533a9 100644 --- a/modules/pc8080/lib/chipset.js +++ b/modules/pc8080/lib/chipset.js @@ -400,7 +400,7 @@ ChipSet8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue * @this {ChipSet8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ ChipSet8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/computer.js b/modules/pc8080/lib/computer.js index 80d72eba0..df0a70f62 100644 --- a/modules/pc8080/lib/computer.js +++ b/modules/pc8080/lib/computer.js @@ -148,7 +148,7 @@ function Computer8080(parmsComputer, parmsMachine, fSuspended) { * where we know getComponentByType() will only return an CPUState object or null), wrap the expression * in parentheses. I never knew this until I stumbled across it in "Closure: The Definitive Guide". */ - this.cpu = /** @type {CPU8080State} */ (Component.getComponentByType("CPU", this.id)); + this.cpu = /** @type {CPUState8080} */ (Component.getComponentByType("CPU", this.id)); if (!this.cpu) { Component.error("Unable to find CPU component"); return; diff --git a/modules/pc8080/lib/cpu.js b/modules/pc8080/lib/cpu.js index d13140654..968c1508d 100644 --- a/modules/pc8080/lib/cpu.js +++ b/modules/pc8080/lib/cpu.js @@ -43,7 +43,7 @@ if (NODE) { * * The CPU8080 class supports the following (parmsCPU) properties: * - * cycles: the machine's base cycles per second; the CPU8080State constructor + * cycles: the machine's base cycles per second; the CPUState8080 constructor * will provide us with a default (based on the CPU model) to use as a fallback. * * multiplier: base cycle multiplier; default is 1. @@ -64,7 +64,7 @@ if (NODE) { * This component is primarily responsible for interfacing the CPU with the outside * world (eg, Panel and Debugger components), and managing overall CPU operation. * - * It is extended by the CPU8080State component, where the simulation control logic resides. + * It is extended by the CPUState8080 component, where the simulation control logic resides. * * @constructor * @extends Component @@ -199,7 +199,7 @@ CPU8080.prototype.reset = function() /** * save() * - * This is a placeholder for save support (overridden by the CPUState component). + * This is a placeholder for save support (overridden by the CPUState8080 component). * * @this {CPU8080} * @return {Object|null} @@ -212,7 +212,7 @@ CPU8080.prototype.save = function() /** * restore(data) * - * This is a placeholder for restore support (overridden by the CPUState component). + * This is a placeholder for restore support (overridden by the CPUState8080 component). * * @this {CPU8080} * @param {Object} data @@ -339,7 +339,7 @@ CPU8080.prototype.isRunning = function() /** * getChecksum() * - * This will be implemented by the CPUState component. + * This will be implemented by the CPUState8080 component. * * @this {CPU8080} * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code) @@ -1145,7 +1145,7 @@ CPU8080.prototype.startCPU = function(fUpdateFocus) /** * stepCPU(nMinCycles) * - * This will be implemented by the CPUState component. + * This will be implemented by the CPUState8080 component. * * @this {CPU8080} * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored) diff --git a/modules/pc8080/lib/cpudef.js b/modules/pc8080/lib/cpudef.js index 47f16fdd2..76f0513eb 100644 --- a/modules/pc8080/lib/cpudef.js +++ b/modules/pc8080/lib/cpudef.js @@ -94,9 +94,9 @@ var CPUDef8080 = { * Interrupt-related flags (stored in intFlags) */ INTFLAG: { - NONE: 0x0000, - INTR: 0x00ff, // mask for 8 bits, representing interrupt levels 0-7 - HALT: 0x0100 // halt requested; see opHLT() + NONE: 0x0000, + INTR: 0x00ff, // mask for 8 bits, representing interrupt levels 0-7 + HALT: 0x0100 // halt requested; see opHLT() }, /* * Opcode definitions diff --git a/modules/pc8080/lib/cpuops.js b/modules/pc8080/lib/cpuops.js index 4907afe53..cd56061a5 100644 --- a/modules/pc8080/lib/cpuops.js +++ b/modules/pc8080/lib/cpuops.js @@ -40,7 +40,7 @@ if (NODE) { /** * op=0x00 (NOP) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opNOP = function() { @@ -50,7 +50,7 @@ CPUDef8080.opNOP = function() /** * op=0x01 (LXI B,d16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLXIB = function() { @@ -61,7 +61,7 @@ CPUDef8080.opLXIB = function() /** * op=0x02 (STAX B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSTAXB = function() { @@ -72,7 +72,7 @@ CPUDef8080.opSTAXB = function() /** * op=0x03 (INX B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINXB = function() { @@ -83,7 +83,7 @@ CPUDef8080.opINXB = function() /** * op=0x04 (INR B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRB = function() { @@ -94,7 +94,7 @@ CPUDef8080.opINRB = function() /** * op=0x05 (DCR B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRB = function() { @@ -105,7 +105,7 @@ CPUDef8080.opDCRB = function() /** * op=0x06 (MVI B,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIB = function() { @@ -116,7 +116,7 @@ CPUDef8080.opMVIB = function() /** * op=0x07 (RLC) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRLC = function() { @@ -129,7 +129,7 @@ CPUDef8080.opRLC = function() /** * op=0x09 (DAD B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDADB = function() { @@ -142,7 +142,7 @@ CPUDef8080.opDADB = function() /** * op=0x0A (LDAX B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLDAXB = function() { @@ -153,7 +153,7 @@ CPUDef8080.opLDAXB = function() /** * op=0x0B (DCX B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCXB = function() { @@ -164,7 +164,7 @@ CPUDef8080.opDCXB = function() /** * op=0x0C (INR C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRC = function() { @@ -175,7 +175,7 @@ CPUDef8080.opINRC = function() /** * op=0x0D (DCR C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRC = function() { @@ -186,7 +186,7 @@ CPUDef8080.opDCRC = function() /** * op=0x0E (MVI C,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIC = function() { @@ -197,7 +197,7 @@ CPUDef8080.opMVIC = function() /** * op=0x0F (RRC) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRRC = function() { @@ -210,7 +210,7 @@ CPUDef8080.opRRC = function() /** * op=0x11 (LXI D,d16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLXID = function() { @@ -221,7 +221,7 @@ CPUDef8080.opLXID = function() /** * op=0x12 (STAX D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSTAXD = function() { @@ -232,7 +232,7 @@ CPUDef8080.opSTAXD = function() /** * op=0x13 (INX D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINXD = function() { @@ -243,7 +243,7 @@ CPUDef8080.opINXD = function() /** * op=0x14 (INR D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRD = function() { @@ -254,7 +254,7 @@ CPUDef8080.opINRD = function() /** * op=0x15 (DCR D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRD = function() { @@ -265,7 +265,7 @@ CPUDef8080.opDCRD = function() /** * op=0x16 (MVI D,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVID = function() { @@ -276,7 +276,7 @@ CPUDef8080.opMVID = function() /** * op=0x17 (RAL) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRAL = function() { @@ -289,7 +289,7 @@ CPUDef8080.opRAL = function() /** * op=0x19 (DAD D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDADD = function() { @@ -302,7 +302,7 @@ CPUDef8080.opDADD = function() /** * op=0x1A (LDAX D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLDAXD = function() { @@ -313,7 +313,7 @@ CPUDef8080.opLDAXD = function() /** * op=0x1B (DCX D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCXD = function() { @@ -324,7 +324,7 @@ CPUDef8080.opDCXD = function() /** * op=0x1C (INR E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRE = function() { @@ -335,7 +335,7 @@ CPUDef8080.opINRE = function() /** * op=0x1D (DCR E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRE = function() { @@ -346,7 +346,7 @@ CPUDef8080.opDCRE = function() /** * op=0x1E (MVI E,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIE = function() { @@ -357,7 +357,7 @@ CPUDef8080.opMVIE = function() /** * op=0x1F (RAR) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRAR = function() { @@ -370,7 +370,7 @@ CPUDef8080.opRAR = function() /** * op=0x21 (LXI H,d16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLXIH = function() { @@ -381,7 +381,7 @@ CPUDef8080.opLXIH = function() /** * op=0x22 (SHLD a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSHLD = function() { @@ -392,7 +392,7 @@ CPUDef8080.opSHLD = function() /** * op=0x23 (INX H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINXH = function() { @@ -403,7 +403,7 @@ CPUDef8080.opINXH = function() /** * op=0x24 (INR H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRH = function() { @@ -414,7 +414,7 @@ CPUDef8080.opINRH = function() /** * op=0x25 (DCR H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRH = function() { @@ -425,7 +425,7 @@ CPUDef8080.opDCRH = function() /** * op=0x26 (MVI H,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIH = function() { @@ -436,7 +436,7 @@ CPUDef8080.opMVIH = function() /** * op=0x27 (DAA) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDAA = function() { @@ -458,7 +458,7 @@ CPUDef8080.opDAA = function() /** * op=0x29 (DAD H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDADH = function() { @@ -471,7 +471,7 @@ CPUDef8080.opDADH = function() /** * op=0x2A (LHLD a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLHLD = function() { @@ -482,7 +482,7 @@ CPUDef8080.opLHLD = function() /** * op=0x2B (DCX H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCXH = function() { @@ -493,7 +493,7 @@ CPUDef8080.opDCXH = function() /** * op=0x2C (INR L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRL = function() { @@ -504,7 +504,7 @@ CPUDef8080.opINRL = function() /** * op=0x2D (DCR L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRL = function() { @@ -515,7 +515,7 @@ CPUDef8080.opDCRL = function() /** * op=0x2E (MVI L,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIL = function() { @@ -526,7 +526,7 @@ CPUDef8080.opMVIL = function() /** * op=0x2F (CMA) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMA = function() { @@ -537,7 +537,7 @@ CPUDef8080.opCMA = function() /** * op=0x31 (LXI SP,d16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLXISP = function() { @@ -548,7 +548,7 @@ CPUDef8080.opLXISP = function() /** * op=0x32 (STA a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSTA = function() { @@ -559,7 +559,7 @@ CPUDef8080.opSTA = function() /** * op=0x33 (INX SP) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINXSP = function() { @@ -570,7 +570,7 @@ CPUDef8080.opINXSP = function() /** * op=0x34 (INR M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRM = function() { @@ -582,7 +582,7 @@ CPUDef8080.opINRM = function() /** * op=0x35 (DCR M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRM = function() { @@ -594,7 +594,7 @@ CPUDef8080.opDCRM = function() /** * op=0x36 (MVI M,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIM = function() { @@ -605,7 +605,7 @@ CPUDef8080.opMVIM = function() /** * op=0x37 (STC) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSTC = function() { @@ -616,7 +616,7 @@ CPUDef8080.opSTC = function() /** * op=0x39 (DAD SP) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDADSP = function() { @@ -629,7 +629,7 @@ CPUDef8080.opDADSP = function() /** * op=0x3A (LDA a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opLDA = function() { @@ -640,7 +640,7 @@ CPUDef8080.opLDA = function() /** * op=0x3B (DCX SP) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCXSP = function() { @@ -651,7 +651,7 @@ CPUDef8080.opDCXSP = function() /** * op=0x3C (INR A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opINRA = function() { @@ -662,7 +662,7 @@ CPUDef8080.opINRA = function() /** * op=0x3D (DCR A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDCRA = function() { @@ -673,7 +673,7 @@ CPUDef8080.opDCRA = function() /** * op=0x3E (MVI A,d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMVIA = function() { @@ -684,7 +684,7 @@ CPUDef8080.opMVIA = function() /** * op=0x3F (CMC) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMC = function() { @@ -695,7 +695,7 @@ CPUDef8080.opCMC = function() /** * op=0x40 (MOV B,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBB = function() { @@ -705,7 +705,7 @@ CPUDef8080.opMOVBB = function() /** * op=0x41 (MOV B,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBC = function() { @@ -716,7 +716,7 @@ CPUDef8080.opMOVBC = function() /** * op=0x42 (MOV B,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBD = function() { @@ -727,7 +727,7 @@ CPUDef8080.opMOVBD = function() /** * op=0x43 (MOV B,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBE = function() { @@ -738,7 +738,7 @@ CPUDef8080.opMOVBE = function() /** * op=0x44 (MOV B,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBH = function() { @@ -749,7 +749,7 @@ CPUDef8080.opMOVBH = function() /** * op=0x45 (MOV B,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBL = function() { @@ -760,7 +760,7 @@ CPUDef8080.opMOVBL = function() /** * op=0x46 (MOV B,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBM = function() { @@ -771,7 +771,7 @@ CPUDef8080.opMOVBM = function() /** * op=0x47 (MOV B,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVBA = function() { @@ -782,7 +782,7 @@ CPUDef8080.opMOVBA = function() /** * op=0x48 (MOV C,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCB = function() { @@ -793,7 +793,7 @@ CPUDef8080.opMOVCB = function() /** * op=0x49 (MOV C,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCC = function() { @@ -803,7 +803,7 @@ CPUDef8080.opMOVCC = function() /** * op=0x4A (MOV C,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCD = function() { @@ -814,7 +814,7 @@ CPUDef8080.opMOVCD = function() /** * op=0x4B (MOV C,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCE = function() { @@ -825,7 +825,7 @@ CPUDef8080.opMOVCE = function() /** * op=0x4C (MOV C,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCH = function() { @@ -836,7 +836,7 @@ CPUDef8080.opMOVCH = function() /** * op=0x4D (MOV C,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCL = function() { @@ -847,7 +847,7 @@ CPUDef8080.opMOVCL = function() /** * op=0x4E (MOV C,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCM = function() { @@ -858,7 +858,7 @@ CPUDef8080.opMOVCM = function() /** * op=0x4F (MOV C,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVCA = function() { @@ -869,7 +869,7 @@ CPUDef8080.opMOVCA = function() /** * op=0x50 (MOV D,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDB = function() { @@ -880,7 +880,7 @@ CPUDef8080.opMOVDB = function() /** * op=0x51 (MOV D,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDC = function() { @@ -891,7 +891,7 @@ CPUDef8080.opMOVDC = function() /** * op=0x52 (MOV D,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDD = function() { @@ -901,7 +901,7 @@ CPUDef8080.opMOVDD = function() /** * op=0x53 (MOV D,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDE = function() { @@ -912,7 +912,7 @@ CPUDef8080.opMOVDE = function() /** * op=0x54 (MOV D,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDH = function() { @@ -923,7 +923,7 @@ CPUDef8080.opMOVDH = function() /** * op=0x55 (MOV D,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDL = function() { @@ -934,7 +934,7 @@ CPUDef8080.opMOVDL = function() /** * op=0x56 (MOV D,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDM = function() { @@ -945,7 +945,7 @@ CPUDef8080.opMOVDM = function() /** * op=0x57 (MOV D,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVDA = function() { @@ -956,7 +956,7 @@ CPUDef8080.opMOVDA = function() /** * op=0x58 (MOV E,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEB = function() { @@ -967,7 +967,7 @@ CPUDef8080.opMOVEB = function() /** * op=0x59 (MOV E,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEC = function() { @@ -978,7 +978,7 @@ CPUDef8080.opMOVEC = function() /** * op=0x5A (MOV E,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVED = function() { @@ -989,7 +989,7 @@ CPUDef8080.opMOVED = function() /** * op=0x5B (MOV E,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEE = function() { @@ -999,7 +999,7 @@ CPUDef8080.opMOVEE = function() /** * op=0x5C (MOV E,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEH = function() { @@ -1010,7 +1010,7 @@ CPUDef8080.opMOVEH = function() /** * op=0x5D (MOV E,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEL = function() { @@ -1021,7 +1021,7 @@ CPUDef8080.opMOVEL = function() /** * op=0x5E (MOV E,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEM = function() { @@ -1032,7 +1032,7 @@ CPUDef8080.opMOVEM = function() /** * op=0x5F (MOV E,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVEA = function() { @@ -1043,7 +1043,7 @@ CPUDef8080.opMOVEA = function() /** * op=0x60 (MOV H,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHB = function() { @@ -1054,7 +1054,7 @@ CPUDef8080.opMOVHB = function() /** * op=0x61 (MOV H,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHC = function() { @@ -1065,7 +1065,7 @@ CPUDef8080.opMOVHC = function() /** * op=0x62 (MOV H,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHD = function() { @@ -1076,7 +1076,7 @@ CPUDef8080.opMOVHD = function() /** * op=0x63 (MOV H,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHE = function() { @@ -1087,7 +1087,7 @@ CPUDef8080.opMOVHE = function() /** * op=0x64 (MOV H,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHH = function() { @@ -1097,7 +1097,7 @@ CPUDef8080.opMOVHH = function() /** * op=0x65 (MOV H,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHL = function() { @@ -1108,7 +1108,7 @@ CPUDef8080.opMOVHL = function() /** * op=0x66 (MOV H,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHM = function() { @@ -1119,7 +1119,7 @@ CPUDef8080.opMOVHM = function() /** * op=0x67 (MOV H,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVHA = function() { @@ -1130,7 +1130,7 @@ CPUDef8080.opMOVHA = function() /** * op=0x68 (MOV L,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLB = function() { @@ -1141,7 +1141,7 @@ CPUDef8080.opMOVLB = function() /** * op=0x69 (MOV L,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLC = function() { @@ -1152,7 +1152,7 @@ CPUDef8080.opMOVLC = function() /** * op=0x6A (MOV L,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLD = function() { @@ -1163,7 +1163,7 @@ CPUDef8080.opMOVLD = function() /** * op=0x6B (MOV L,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLE = function() { @@ -1174,7 +1174,7 @@ CPUDef8080.opMOVLE = function() /** * op=0x6C (MOV L,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLH = function() { @@ -1185,7 +1185,7 @@ CPUDef8080.opMOVLH = function() /** * op=0x6D (MOV L,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLL = function() { @@ -1195,7 +1195,7 @@ CPUDef8080.opMOVLL = function() /** * op=0x6E (MOV L,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLM = function() { @@ -1206,7 +1206,7 @@ CPUDef8080.opMOVLM = function() /** * op=0x6F (MOV L,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVLA = function() { @@ -1217,7 +1217,7 @@ CPUDef8080.opMOVLA = function() /** * op=0x70 (MOV M,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVMB = function() { @@ -1228,7 +1228,7 @@ CPUDef8080.opMOVMB = function() /** * op=0x71 (MOV M,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVMC = function() { @@ -1239,7 +1239,7 @@ CPUDef8080.opMOVMC = function() /** * op=0x72 (MOV M,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVMD = function() { @@ -1250,7 +1250,7 @@ CPUDef8080.opMOVMD = function() /** * op=0x73 (MOV M,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVME = function() { @@ -1261,7 +1261,7 @@ CPUDef8080.opMOVME = function() /** * op=0x74 (MOV M,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVMH = function() { @@ -1272,7 +1272,7 @@ CPUDef8080.opMOVMH = function() /** * op=0x75 (MOV M,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVML = function() { @@ -1283,7 +1283,7 @@ CPUDef8080.opMOVML = function() /** * op=0x76 (HLT) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opHLT = function() { @@ -1331,7 +1331,7 @@ CPUDef8080.opHLT = function() /** * op=0x77 (MOV M,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVMA = function() { @@ -1342,7 +1342,7 @@ CPUDef8080.opMOVMA = function() /** * op=0x78 (MOV A,B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAB = function() { @@ -1353,7 +1353,7 @@ CPUDef8080.opMOVAB = function() /** * op=0x79 (MOV A,C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAC = function() { @@ -1364,7 +1364,7 @@ CPUDef8080.opMOVAC = function() /** * op=0x7A (MOV A,D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAD = function() { @@ -1375,7 +1375,7 @@ CPUDef8080.opMOVAD = function() /** * op=0x7B (MOV A,E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAE = function() { @@ -1386,7 +1386,7 @@ CPUDef8080.opMOVAE = function() /** * op=0x7C (MOV A,H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAH = function() { @@ -1397,7 +1397,7 @@ CPUDef8080.opMOVAH = function() /** * op=0x7D (MOV A,L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAL = function() { @@ -1408,7 +1408,7 @@ CPUDef8080.opMOVAL = function() /** * op=0x7E (MOV A,M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAM = function() { @@ -1419,7 +1419,7 @@ CPUDef8080.opMOVAM = function() /** * op=0x7F (MOV A,A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opMOVAA = function() { @@ -1429,7 +1429,7 @@ CPUDef8080.opMOVAA = function() /** * op=0x80 (ADD B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDB = function() { @@ -1440,7 +1440,7 @@ CPUDef8080.opADDB = function() /** * op=0x81 (ADD C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDC = function() { @@ -1451,7 +1451,7 @@ CPUDef8080.opADDC = function() /** * op=0x82 (ADD D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDD = function() { @@ -1462,7 +1462,7 @@ CPUDef8080.opADDD = function() /** * op=0x83 (ADD E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDE = function() { @@ -1473,7 +1473,7 @@ CPUDef8080.opADDE = function() /** * op=0x84 (ADD H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDH = function() { @@ -1484,7 +1484,7 @@ CPUDef8080.opADDH = function() /** * op=0x85 (ADD L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDL = function() { @@ -1495,7 +1495,7 @@ CPUDef8080.opADDL = function() /** * op=0x86 (ADD M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDM = function() { @@ -1506,7 +1506,7 @@ CPUDef8080.opADDM = function() /** * op=0x87 (ADD A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADDA = function() { @@ -1517,7 +1517,7 @@ CPUDef8080.opADDA = function() /** * op=0x88 (ADC B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCB = function() { @@ -1528,7 +1528,7 @@ CPUDef8080.opADCB = function() /** * op=0x89 (ADC C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCC = function() { @@ -1539,7 +1539,7 @@ CPUDef8080.opADCC = function() /** * op=0x8A (ADC D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCD = function() { @@ -1550,7 +1550,7 @@ CPUDef8080.opADCD = function() /** * op=0x8B (ADC E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCE = function() { @@ -1561,7 +1561,7 @@ CPUDef8080.opADCE = function() /** * op=0x8C (ADC H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCH = function() { @@ -1572,7 +1572,7 @@ CPUDef8080.opADCH = function() /** * op=0x8D (ADC L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCL = function() { @@ -1583,7 +1583,7 @@ CPUDef8080.opADCL = function() /** * op=0x8E (ADC M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCM = function() { @@ -1594,7 +1594,7 @@ CPUDef8080.opADCM = function() /** * op=0x8F (ADC A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADCA = function() { @@ -1605,7 +1605,7 @@ CPUDef8080.opADCA = function() /** * op=0x90 (SUB B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBB = function() { @@ -1616,7 +1616,7 @@ CPUDef8080.opSUBB = function() /** * op=0x91 (SUB C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBC = function() { @@ -1627,7 +1627,7 @@ CPUDef8080.opSUBC = function() /** * op=0x92 (SUB D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBD = function() { @@ -1638,7 +1638,7 @@ CPUDef8080.opSUBD = function() /** * op=0x93 (SUB E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBE = function() { @@ -1649,7 +1649,7 @@ CPUDef8080.opSUBE = function() /** * op=0x94 (SUB H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBH = function() { @@ -1660,7 +1660,7 @@ CPUDef8080.opSUBH = function() /** * op=0x95 (SUB L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBL = function() { @@ -1671,7 +1671,7 @@ CPUDef8080.opSUBL = function() /** * op=0x96 (SUB M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBM = function() { @@ -1682,7 +1682,7 @@ CPUDef8080.opSUBM = function() /** * op=0x97 (SUB A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUBA = function() { @@ -1693,7 +1693,7 @@ CPUDef8080.opSUBA = function() /** * op=0x98 (SBB B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBB = function() { @@ -1704,7 +1704,7 @@ CPUDef8080.opSBBB = function() /** * op=0x99 (SBB C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBC = function() { @@ -1715,7 +1715,7 @@ CPUDef8080.opSBBC = function() /** * op=0x9A (SBB D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBD = function() { @@ -1726,7 +1726,7 @@ CPUDef8080.opSBBD = function() /** * op=0x9B (SBB E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBE = function() { @@ -1737,7 +1737,7 @@ CPUDef8080.opSBBE = function() /** * op=0x9C (SBB H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBH = function() { @@ -1748,7 +1748,7 @@ CPUDef8080.opSBBH = function() /** * op=0x9D (SBB L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBL = function() { @@ -1759,7 +1759,7 @@ CPUDef8080.opSBBL = function() /** * op=0x9E (SBB M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBM = function() { @@ -1770,7 +1770,7 @@ CPUDef8080.opSBBM = function() /** * op=0x9F (SBB A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBBA = function() { @@ -1781,7 +1781,7 @@ CPUDef8080.opSBBA = function() /** * op=0xA0 (ANA B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAB = function() { @@ -1792,7 +1792,7 @@ CPUDef8080.opANAB = function() /** * op=0xA1 (ANA C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAC = function() { @@ -1803,7 +1803,7 @@ CPUDef8080.opANAC = function() /** * op=0xA2 (ANA D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAD = function() { @@ -1814,7 +1814,7 @@ CPUDef8080.opANAD = function() /** * op=0xA3 (ANA E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAE = function() { @@ -1825,7 +1825,7 @@ CPUDef8080.opANAE = function() /** * op=0xA4 (ANA H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAH = function() { @@ -1836,7 +1836,7 @@ CPUDef8080.opANAH = function() /** * op=0xA5 (ANA L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAL = function() { @@ -1847,7 +1847,7 @@ CPUDef8080.opANAL = function() /** * op=0xA6 (ANA M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAM = function() { @@ -1858,7 +1858,7 @@ CPUDef8080.opANAM = function() /** * op=0xA7 (ANA A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANAA = function() { @@ -1869,7 +1869,7 @@ CPUDef8080.opANAA = function() /** * op=0xA8 (XRA B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAB = function() { @@ -1880,7 +1880,7 @@ CPUDef8080.opXRAB = function() /** * op=0xA9 (XRA C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAC = function() { @@ -1891,7 +1891,7 @@ CPUDef8080.opXRAC = function() /** * op=0xAA (XRA D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAD = function() { @@ -1902,7 +1902,7 @@ CPUDef8080.opXRAD = function() /** * op=0xAB (XRA E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAE = function() { @@ -1913,7 +1913,7 @@ CPUDef8080.opXRAE = function() /** * op=0xAC (XRA H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAH = function() { @@ -1924,7 +1924,7 @@ CPUDef8080.opXRAH = function() /** * op=0xAD (XRA L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAL = function() { @@ -1935,7 +1935,7 @@ CPUDef8080.opXRAL = function() /** * op=0xAE (XRA M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAM = function() { @@ -1946,7 +1946,7 @@ CPUDef8080.opXRAM = function() /** * op=0xAF (XRA A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRAA = function() { @@ -1957,7 +1957,7 @@ CPUDef8080.opXRAA = function() /** * op=0xB0 (ORA B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAB = function() { @@ -1968,7 +1968,7 @@ CPUDef8080.opORAB = function() /** * op=0xB1 (ORA C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAC = function() { @@ -1979,7 +1979,7 @@ CPUDef8080.opORAC = function() /** * op=0xB2 (ORA D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAD = function() { @@ -1990,7 +1990,7 @@ CPUDef8080.opORAD = function() /** * op=0xB3 (ORA E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAE = function() { @@ -2001,7 +2001,7 @@ CPUDef8080.opORAE = function() /** * op=0xB4 (ORA H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAH = function() { @@ -2012,7 +2012,7 @@ CPUDef8080.opORAH = function() /** * op=0xB5 (ORA L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAL = function() { @@ -2023,7 +2023,7 @@ CPUDef8080.opORAL = function() /** * op=0xB6 (ORA M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAM = function() { @@ -2034,7 +2034,7 @@ CPUDef8080.opORAM = function() /** * op=0xB7 (ORA A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORAA = function() { @@ -2045,7 +2045,7 @@ CPUDef8080.opORAA = function() /** * op=0xB8 (CMP B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPB = function() { @@ -2056,7 +2056,7 @@ CPUDef8080.opCMPB = function() /** * op=0xB9 (CMP C) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPC = function() { @@ -2067,7 +2067,7 @@ CPUDef8080.opCMPC = function() /** * op=0xBA (CMP D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPD = function() { @@ -2078,7 +2078,7 @@ CPUDef8080.opCMPD = function() /** * op=0xBB (CMP E) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPE = function() { @@ -2089,7 +2089,7 @@ CPUDef8080.opCMPE = function() /** * op=0xBC (CMP H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPH = function() { @@ -2100,7 +2100,7 @@ CPUDef8080.opCMPH = function() /** * op=0xBD (CMP L) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPL = function() { @@ -2111,7 +2111,7 @@ CPUDef8080.opCMPL = function() /** * op=0xBE (CMP M) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPM = function() { @@ -2122,7 +2122,7 @@ CPUDef8080.opCMPM = function() /** * op=0xBF (CMP A) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCMPA = function() { @@ -2133,7 +2133,7 @@ CPUDef8080.opCMPA = function() /** * op=0xC0 (RNZ) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRNZ = function() { @@ -2147,7 +2147,7 @@ CPUDef8080.opRNZ = function() /** * op=0xC1 (POP B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPOPB = function() { @@ -2158,7 +2158,7 @@ CPUDef8080.opPOPB = function() /** * op=0xC2 (JNZ a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJNZ = function() { @@ -2170,7 +2170,7 @@ CPUDef8080.opJNZ = function() /** * op=0xC3 (JMP a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJMP = function() { @@ -2181,7 +2181,7 @@ CPUDef8080.opJMP = function() /** * op=0xC4 (CNZ a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCNZ = function() { @@ -2197,7 +2197,7 @@ CPUDef8080.opCNZ = function() /** * op=0xC5 (PUSH B) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPUSHB = function() { @@ -2208,7 +2208,7 @@ CPUDef8080.opPUSHB = function() /** * op=0xC6 (ADI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opADI = function() { @@ -2219,7 +2219,7 @@ CPUDef8080.opADI = function() /** * op=0xC7 (RST 0) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST0 = function() { @@ -2231,7 +2231,7 @@ CPUDef8080.opRST0 = function() /** * op=0xC8 (RZ) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRZ = function() { @@ -2245,7 +2245,7 @@ CPUDef8080.opRZ = function() /** * op=0xC9 (RET) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRET = function() { @@ -2256,7 +2256,7 @@ CPUDef8080.opRET = function() /** * op=0xCA (JZ a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJZ = function() { @@ -2268,7 +2268,7 @@ CPUDef8080.opJZ = function() /** * op=0xCC (CZ a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCZ = function() { @@ -2284,7 +2284,7 @@ CPUDef8080.opCZ = function() /** * op=0xCD (CALL a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCALL = function() { @@ -2297,7 +2297,7 @@ CPUDef8080.opCALL = function() /** * op=0xCE (ACI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opACI = function() { @@ -2308,7 +2308,7 @@ CPUDef8080.opACI = function() /** * op=0xCF (RST 1) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST1 = function() { @@ -2320,7 +2320,7 @@ CPUDef8080.opRST1 = function() /** * op=0xD0 (RNC) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRNC = function() { @@ -2334,7 +2334,7 @@ CPUDef8080.opRNC = function() /** * op=0xD1 (POP D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPOPD = function() { @@ -2345,7 +2345,7 @@ CPUDef8080.opPOPD = function() /** * op=0xD2 (JNC a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJNC = function() { @@ -2357,7 +2357,7 @@ CPUDef8080.opJNC = function() /** * op=0xD3 (OUT d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opOUT = function() { @@ -2369,7 +2369,7 @@ CPUDef8080.opOUT = function() /** * op=0xD4 (CNC a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCNC = function() { @@ -2385,7 +2385,7 @@ CPUDef8080.opCNC = function() /** * op=0xD5 (PUSH D) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPUSHD = function() { @@ -2396,7 +2396,7 @@ CPUDef8080.opPUSHD = function() /** * op=0xD6 (SUI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSUI = function() { @@ -2407,7 +2407,7 @@ CPUDef8080.opSUI = function() /** * op=0xD7 (RST 2) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST2 = function() { @@ -2419,7 +2419,7 @@ CPUDef8080.opRST2 = function() /** * op=0xD8 (RC) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRC = function() { @@ -2433,7 +2433,7 @@ CPUDef8080.opRC = function() /** * op=0xDA (JC a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJC = function() { @@ -2445,7 +2445,7 @@ CPUDef8080.opJC = function() /** * op=0xDB (IN d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opIN = function() { @@ -2457,7 +2457,7 @@ CPUDef8080.opIN = function() /** * op=0xDC (CC a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCC = function() { @@ -2473,7 +2473,7 @@ CPUDef8080.opCC = function() /** * op=0xDE (SBI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSBI = function() { @@ -2484,7 +2484,7 @@ CPUDef8080.opSBI = function() /** * op=0xDF (RST 3) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST3 = function() { @@ -2496,7 +2496,7 @@ CPUDef8080.opRST3 = function() /** * op=0xE0 (RPO) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRPO = function() { @@ -2510,7 +2510,7 @@ CPUDef8080.opRPO = function() /** * op=0xE1 (POP H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPOPH = function() { @@ -2521,7 +2521,7 @@ CPUDef8080.opPOPH = function() /** * op=0xE2 (JPO a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJPO = function() { @@ -2533,7 +2533,7 @@ CPUDef8080.opJPO = function() /** * op=0xE3 (XTHL) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXTHL = function() { @@ -2546,7 +2546,7 @@ CPUDef8080.opXTHL = function() /** * op=0xE4 (CPO a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCPO = function() { @@ -2562,7 +2562,7 @@ CPUDef8080.opCPO = function() /** * op=0xE5 (PUSH H) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPUSHH = function() { @@ -2573,7 +2573,7 @@ CPUDef8080.opPUSHH = function() /** * op=0xE6 (ANI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opANI = function() { @@ -2584,7 +2584,7 @@ CPUDef8080.opANI = function() /** * op=0xE7 (RST 4) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST4 = function() { @@ -2596,7 +2596,7 @@ CPUDef8080.opRST4 = function() /** * op=0xE8 (RPE) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRPE = function() { @@ -2610,7 +2610,7 @@ CPUDef8080.opRPE = function() /** * op=0xE9 (PCHL) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPCHL = function() { @@ -2621,7 +2621,7 @@ CPUDef8080.opPCHL = function() /** * op=0xEA (JPE a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJPE = function() { @@ -2633,7 +2633,7 @@ CPUDef8080.opJPE = function() /** * op=0xEB (XCHG) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXCHG = function() { @@ -2646,7 +2646,7 @@ CPUDef8080.opXCHG = function() /** * op=0xEC (CPE a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCPE = function() { @@ -2662,7 +2662,7 @@ CPUDef8080.opCPE = function() /** * op=0xEE (XRI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opXRI = function() { @@ -2673,7 +2673,7 @@ CPUDef8080.opXRI = function() /** * op=0xEF (RST 5) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST5 = function() { @@ -2685,7 +2685,7 @@ CPUDef8080.opRST5 = function() /** * op=0xF0 (RP) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRP = function() { @@ -2699,7 +2699,7 @@ CPUDef8080.opRP = function() /** * op=0xF1 (POP PSW) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPOPSW = function() { @@ -2710,7 +2710,7 @@ CPUDef8080.opPOPSW = function() /** * op=0xF2 (JP a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJP = function() { @@ -2722,7 +2722,7 @@ CPUDef8080.opJP = function() /** * op=0xF3 (DI) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opDI = function() { @@ -2733,7 +2733,7 @@ CPUDef8080.opDI = function() /** * op=0xF4 (CP a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCP = function() { @@ -2749,7 +2749,7 @@ CPUDef8080.opCP = function() /** * op=0xF5 (PUSH PSW) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opPUPSW = function() { @@ -2760,7 +2760,7 @@ CPUDef8080.opPUPSW = function() /** * op=0xF6 (ORI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opORI = function() { @@ -2771,7 +2771,7 @@ CPUDef8080.opORI = function() /** * op=0xF7 (RST 6) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST6 = function() { @@ -2783,7 +2783,7 @@ CPUDef8080.opRST6 = function() /** * op=0xF8 (RM) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRM = function() { @@ -2797,7 +2797,7 @@ CPUDef8080.opRM = function() /** * op=0xF9 (SPHL) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opSPHL = function() { @@ -2808,7 +2808,7 @@ CPUDef8080.opSPHL = function() /** * op=0xFA (JM a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opJM = function() { @@ -2820,7 +2820,7 @@ CPUDef8080.opJM = function() /** * op=0xFB (EI) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opEI = function() { @@ -2832,7 +2832,7 @@ CPUDef8080.opEI = function() /** * op=0xFC (CM a16) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCM = function() { @@ -2848,7 +2848,7 @@ CPUDef8080.opCM = function() /** * op=0xFE (CPI d8) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opCPI = function() { @@ -2859,7 +2859,7 @@ CPUDef8080.opCPI = function() /** * op=0xFF (RST 7) * - * @this {CPU8080State} + * @this {CPUState8080} */ CPUDef8080.opRST7 = function() { diff --git a/modules/pc8080/lib/cpustate.js b/modules/pc8080/lib/cpustate.js index 5ab1fe374..5900e3d2c 100644 --- a/modules/pc8080/lib/cpustate.js +++ b/modules/pc8080/lib/cpustate.js @@ -44,9 +44,9 @@ if (NODE) { } /** - * CPU8080State(parmsCPU) + * CPUState8080(parmsCPU) * - * The CPU8080State class uses the following (parmsCPU) properties: + * The CPUState8080 class uses the following (parmsCPU) properties: * * model: a number (eg, 8080) that should match one of the CPUDef8080.MODEL_* values * @@ -54,14 +54,14 @@ if (NODE) { * constructor, along with a default speed (cycles per second) based on the specified (or default) * CPU model number. * - * The CPU8080State class was initially written to simulate a 8080 microprocessor, although over time + * The CPUState8080 class was initially written to simulate a 8080 microprocessor, although over time * it may evolved to support other microprocessors (eg, the Zilog Z80). * * @constructor * @extends CPU8080 * @param {Object} parmsCPU */ -function CPU8080State(parmsCPU) +function CPUState8080(parmsCPU) { this.model = +parmsCPU['model'] || CPUDef8080.MODEL_8080; @@ -105,17 +105,17 @@ function CPU8080State(parmsCPU) this.resetRegs(); } -Component.subclass(CPU8080State, CPU8080); +Component.subclass(CPUState8080, CPU8080); /** * addHaltCheck(fn) * * Records a function that will be called during HLT opcode processing. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {function(number)} fn */ -CPU8080State.prototype.addHaltCheck = function(fn) +CPUState8080.prototype.addHaltCheck = function(fn) { this.afnHalt.push(fn); }; @@ -129,9 +129,9 @@ CPU8080State.prototype.addHaltCheck = function(fn) * a Closure Compiler optimization is defeated when generating the function array at run-time instead of at * compile-time. * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.initProcessor = function() +CPUState8080.prototype.initProcessor = function() { this.aOps = CPUDef8080.aOps8080; }; @@ -139,9 +139,9 @@ CPU8080State.prototype.initProcessor = function() /** * reset() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.reset = function() +CPUState8080.prototype.reset = function() { if (this.flags.fRunning) this.stopCPU(); this.resetRegs(); @@ -153,9 +153,9 @@ CPU8080State.prototype.reset = function() /** * resetRegs() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.resetRegs = function() +CPUState8080.prototype.resetRegs = function() { this.regA = 0; this.regB = 0; @@ -183,10 +183,10 @@ CPU8080State.prototype.resetRegs = function() /** * setReset(addr) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} addr */ -CPU8080State.prototype.setReset = function(addr) +CPUState8080.prototype.setReset = function(addr) { this.addrReset = addr; this.setPC(addr); @@ -195,10 +195,10 @@ CPU8080State.prototype.setReset = function(addr) /** * getChecksum() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code) */ -CPU8080State.prototype.getChecksum = function() +CPUState8080.prototype.getChecksum = function() { var sum = (this.regA + this.regB + this.regC + this.regD + this.regE + this.regH + this.regL)|0; sum = (sum + this.getSP() + this.getPC() + this.getPS())|0; @@ -208,12 +208,12 @@ CPU8080State.prototype.getChecksum = function() /** * save() * - * This implements save support for the CPU8080State component. + * This implements save support for the CPUState8080 component. * - * @this {CPU8080State} + * @this {CPUState8080} * @return {Object|null} */ -CPU8080State.prototype.save = function() +CPUState8080.prototype.save = function() { var state = new State(this); state.set(0, [this.regA, this.regB, this.regC, this.regD, this.regE, this.regH, this.regL, this.getSP(), this.getPC(), this.getPS()]); @@ -225,13 +225,13 @@ CPU8080State.prototype.save = function() /** * restore(data) * - * This implements restore support for the CPU8080State component. + * This implements restore support for the CPUState8080 component. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {Object} data * @return {boolean} true if restore successful, false if not */ -CPU8080State.prototype.restore = function(data) +CPUState8080.prototype.restore = function(data) { var a = data[0]; this.regA = a[0]; @@ -254,14 +254,14 @@ CPU8080State.prototype.restore = function(data) /** * setBinding(sHTMLType, sBinding, control, sValue) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "AX") * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value * @return {boolean} true if binding was successful, false if unrecognized binding request */ -CPU8080State.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) +CPUState8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) { var fBound = false; switch (sBinding) { @@ -298,10 +298,10 @@ CPU8080State.prototype.setBinding = function(sHTMLType, sBinding, control, sValu /** * getBC() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getBC = function() +CPUState8080.prototype.getBC = function() { return (this.regB << 8) | this.regC; }; @@ -309,10 +309,10 @@ CPU8080State.prototype.getBC = function() /** * setBC(w) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} w */ -CPU8080State.prototype.setBC = function(w) +CPUState8080.prototype.setBC = function(w) { this.regB = (w >> 8) & 0xff; this.regC = w & 0xff; @@ -321,10 +321,10 @@ CPU8080State.prototype.setBC = function(w) /** * getDE() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getDE = function() +CPUState8080.prototype.getDE = function() { return (this.regD << 8) | this.regE; }; @@ -332,10 +332,10 @@ CPU8080State.prototype.getDE = function() /** * setDE(w) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} w */ -CPU8080State.prototype.setDE = function(w) +CPUState8080.prototype.setDE = function(w) { this.regD = (w >> 8) & 0xff; this.regE = w & 0xff; @@ -344,10 +344,10 @@ CPU8080State.prototype.setDE = function(w) /** * getHL() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getHL = function() +CPUState8080.prototype.getHL = function() { return (this.regH << 8) | this.regL; }; @@ -355,10 +355,10 @@ CPU8080State.prototype.getHL = function() /** * setHL(w) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} w */ -CPU8080State.prototype.setHL = function(w) +CPUState8080.prototype.setHL = function(w) { this.regH = (w >> 8) & 0xff; this.regL = w & 0xff; @@ -367,10 +367,10 @@ CPU8080State.prototype.setHL = function(w) /** * getSP() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getSP = function() +CPUState8080.prototype.getSP = function() { return this.regSP; }; @@ -378,10 +378,10 @@ CPU8080State.prototype.getSP = function() /** * setSP(off) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} off */ -CPU8080State.prototype.setSP = function(off) +CPUState8080.prototype.setSP = function(off) { this.regSP = off & 0xffff; }; @@ -389,10 +389,10 @@ CPU8080State.prototype.setSP = function(off) /** * getPC() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getPC = function() +CPUState8080.prototype.getPC = function() { return this.regPC; }; @@ -400,11 +400,11 @@ CPU8080State.prototype.getPC = function() /** * offPC() * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} off * @return {number} */ -CPU8080State.prototype.offPC = function(off) +CPUState8080.prototype.offPC = function(off) { return (this.regPC + off) & 0xffff; }; @@ -412,10 +412,10 @@ CPU8080State.prototype.offPC = function(off) /** * setPC(off) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} off */ -CPU8080State.prototype.setPC = function(off) +CPUState8080.prototype.setPC = function(off) { this.regPC = off & 0xffff; }; @@ -423,9 +423,9 @@ CPU8080State.prototype.setPC = function(off) /** * clearCF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.clearCF = function() +CPUState8080.prototype.clearCF = function() { this.resultZeroCarry &= 0xff; }; @@ -433,10 +433,10 @@ CPU8080State.prototype.clearCF = function() /** * getCF() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} 0 or 1 (CPUDef8080.PS.CF) */ -CPU8080State.prototype.getCF = function() +CPUState8080.prototype.getCF = function() { return (this.resultZeroCarry & 0x100)? CPUDef8080.PS.CF : 0; }; @@ -444,9 +444,9 @@ CPU8080State.prototype.getCF = function() /** * setCF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.setCF = function() +CPUState8080.prototype.setCF = function() { this.resultZeroCarry |= 0x100; }; @@ -454,10 +454,10 @@ CPU8080State.prototype.setCF = function() /** * updateCF(CF) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} CF (0x000 or 0x100) */ -CPU8080State.prototype.updateCF = function(CF) +CPUState8080.prototype.updateCF = function(CF) { this.resultZeroCarry = (this.resultZeroCarry & 0xff) | CF; }; @@ -465,9 +465,9 @@ CPU8080State.prototype.updateCF = function(CF) /** * clearPF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.clearPF = function() +CPUState8080.prototype.clearPF = function() { if (this.getPF()) this.resultParitySign ^= 0x1; }; @@ -475,10 +475,10 @@ CPU8080State.prototype.clearPF = function() /** * getPF() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} 0 or CPUDef8080.PS.PF */ -CPU8080State.prototype.getPF = function() +CPUState8080.prototype.getPF = function() { return (CPUDef8080.PARITY[this.resultParitySign & 0xff])? CPUDef8080.PS.PF : 0; }; @@ -486,9 +486,9 @@ CPU8080State.prototype.getPF = function() /** * setPF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.setPF = function() +CPUState8080.prototype.setPF = function() { if (!this.getPF()) this.resultParitySign ^= 0x1; }; @@ -496,9 +496,9 @@ CPU8080State.prototype.setPF = function() /** * clearAF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.clearAF = function() +CPUState8080.prototype.clearAF = function() { this.resultAuxOverflow = (this.resultParitySign & 0x10) | (this.resultAuxOverflow & ~0x10); }; @@ -506,10 +506,10 @@ CPU8080State.prototype.clearAF = function() /** * getAF() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} 0 or CPUDef8080.PS.AF */ -CPU8080State.prototype.getAF = function() +CPUState8080.prototype.getAF = function() { return ((this.resultParitySign ^ this.resultAuxOverflow) & 0x10)? CPUDef8080.PS.AF : 0; }; @@ -517,9 +517,9 @@ CPU8080State.prototype.getAF = function() /** * setAF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.setAF = function() +CPUState8080.prototype.setAF = function() { this.resultAuxOverflow = (~this.resultParitySign & 0x10) | (this.resultAuxOverflow & ~0x10); }; @@ -527,9 +527,9 @@ CPU8080State.prototype.setAF = function() /** * clearZF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.clearZF = function() +CPUState8080.prototype.clearZF = function() { this.resultZeroCarry |= 0xff; }; @@ -537,10 +537,10 @@ CPU8080State.prototype.clearZF = function() /** * getZF() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} 0 or CPUDef8080.PS.ZF */ -CPU8080State.prototype.getZF = function() +CPUState8080.prototype.getZF = function() { return (this.resultZeroCarry & 0xff)? 0 : CPUDef8080.PS.ZF; }; @@ -548,9 +548,9 @@ CPU8080State.prototype.getZF = function() /** * setZF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.setZF = function() +CPUState8080.prototype.setZF = function() { this.resultZeroCarry &= ~0xff; }; @@ -558,9 +558,9 @@ CPU8080State.prototype.setZF = function() /** * clearSF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.clearSF = function() +CPUState8080.prototype.clearSF = function() { if (this.getSF()) this.resultParitySign ^= 0xc0; }; @@ -568,10 +568,10 @@ CPU8080State.prototype.clearSF = function() /** * getSF() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} 0 or CPUDef8080.PS.SF */ -CPU8080State.prototype.getSF = function() +CPUState8080.prototype.getSF = function() { return (this.resultParitySign & 0x80)? CPUDef8080.PS.SF : 0; }; @@ -579,9 +579,9 @@ CPU8080State.prototype.getSF = function() /** * setSF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.setSF = function() +CPUState8080.prototype.setSF = function() { if (!this.getSF()) this.resultParitySign ^= 0xc0; }; @@ -589,9 +589,9 @@ CPU8080State.prototype.setSF = function() /** * clearIF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.clearIF = function() +CPUState8080.prototype.clearIF = function() { this.regPS &= ~CPUDef8080.PS.IF; }; @@ -599,10 +599,10 @@ CPU8080State.prototype.clearIF = function() /** * getIF() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} 0 or CPUDef8080.PS.IF */ -CPU8080State.prototype.getIF = function() +CPUState8080.prototype.getIF = function() { return (this.regPS & CPUDef8080.PS.IF); }; @@ -610,9 +610,9 @@ CPU8080State.prototype.getIF = function() /** * setIF() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.setIF = function() +CPUState8080.prototype.setIF = function() { this.regPS |= CPUDef8080.PS.IF; }; @@ -620,10 +620,10 @@ CPU8080State.prototype.setIF = function() /** * getPS() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getPS = function() +CPUState8080.prototype.getPS = function() { return (this.regPS & ~CPUDef8080.PS.RESULT) | (this.getSF() | this.getZF() | this.getAF() | this.getPF() | this.getCF()); }; @@ -631,10 +631,10 @@ CPU8080State.prototype.getPS = function() /** * setPS(regPS) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} regPS */ -CPU8080State.prototype.setPS = function(regPS) +CPUState8080.prototype.setPS = function(regPS) { this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = 0; if (regPS & CPUDef8080.PS.CF) this.resultZeroCarry |= 0x100; @@ -649,10 +649,10 @@ CPU8080State.prototype.setPS = function(regPS) /** * getPSW() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} */ -CPU8080State.prototype.getPSW = function() +CPUState8080.prototype.getPSW = function() { return (this.getPS() & CPUDef8080.PS.MASK) | (this.regA << 8); }; @@ -660,10 +660,10 @@ CPU8080State.prototype.getPSW = function() /** * setPSW(w) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} w */ -CPU8080State.prototype.setPSW = function(w) +CPUState8080.prototype.setPSW = function(w) { this.setPS((w & CPUDef8080.PS.MASK) | (this.regPS & ~CPUDef8080.PS.MASK)); this.regA = w >> 8; @@ -672,11 +672,11 @@ CPU8080State.prototype.setPSW = function(w) /** * addByte(src) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA + src */ -CPU8080State.prototype.addByte = function(src) +CPUState8080.prototype.addByte = function(src) { this.resultAuxOverflow = this.regA ^ src; return this.resultParitySign = (this.resultZeroCarry = this.regA + src) & 0xff; @@ -685,11 +685,11 @@ CPU8080State.prototype.addByte = function(src) /** * addByteCarry(src) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA + src + carry */ -CPU8080State.prototype.addByteCarry = function(src) +CPUState8080.prototype.addByteCarry = function(src) { this.resultAuxOverflow = this.regA ^ src; return this.resultParitySign = (this.resultZeroCarry = this.regA + src + ((this.resultZeroCarry & 0x100)? 1 : 0)) & 0xff; @@ -701,11 +701,11 @@ CPU8080State.prototype.addByteCarry = function(src) * Ordinarily, one would expect the Auxiliary Carry flag (AF) to be clear after this operation, * but apparently the 8080 will set AF if bit 3 in either operand is set. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA & src */ -CPU8080State.prototype.andByte = function(src) +CPUState8080.prototype.andByte = function(src) { this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = this.regA & src; if ((this.regA | src) & 0x8) this.resultAuxOverflow ^= 0x10; // set AF by inverting bit 4 in resultAuxOverflow @@ -718,11 +718,11 @@ CPU8080State.prototype.andByte = function(src) * We perform this operation using 8-bit two's complement arithmetic, by negating and then adding * the implied src of 1. This appears to mimic how the 8080 manages the Auxiliary Carry flag (AF). * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} b * @return {number} */ -CPU8080State.prototype.decByte = function(b) +CPUState8080.prototype.decByte = function(b) { this.resultAuxOverflow = b ^ 0xff; b = this.resultParitySign = (b + 0xff) & 0xff; @@ -733,11 +733,11 @@ CPU8080State.prototype.decByte = function(b) /** * incByte(b) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} b * @return {number} */ -CPU8080State.prototype.incByte = function(b) +CPUState8080.prototype.incByte = function(b) { this.resultAuxOverflow = b; b = this.resultParitySign = (b + 1) & 0xff; @@ -748,11 +748,11 @@ CPU8080State.prototype.incByte = function(b) /** * orByte(src) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA | src */ -CPU8080State.prototype.orByte = function(src) +CPUState8080.prototype.orByte = function(src) { return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA | src; }; @@ -787,11 +787,11 @@ CPU8080State.prototype.orByte = function(src) * --------- * 1 0101 0110 (0x56) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA - src */ -CPU8080State.prototype.subByte = function(src) +CPUState8080.prototype.subByte = function(src) { src ^= 0xff; this.resultAuxOverflow = this.regA ^ src; @@ -808,11 +808,11 @@ CPU8080State.prototype.subByte = function(src) * This mimics the behavior of subByte() when the Carry flag (CF) is clear, and hopefully also mimics how the * 8080 manages the Auxiliary Carry flag (AF) when the Carry flag (CF) is set. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA - src - carry */ -CPU8080State.prototype.subByteBorrow = function(src) +CPUState8080.prototype.subByteBorrow = function(src) { src ^= 0xff; this.resultAuxOverflow = this.regA ^ src; @@ -822,11 +822,11 @@ CPU8080State.prototype.subByteBorrow = function(src) /** * xorByte(src) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} src * @return {number} regA ^ src */ -CPU8080State.prototype.xorByte = function(src) +CPUState8080.prototype.xorByte = function(src) { return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA ^ src; }; @@ -834,11 +834,11 @@ CPU8080State.prototype.xorByte = function(src) /** * getByte(addr) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} addr is a linear address * @return {number} byte (8-bit) value at that address */ -CPU8080State.prototype.getByte = function(addr) +CPUState8080.prototype.getByte = function(addr) { return this.bus.getByte(addr); }; @@ -846,11 +846,11 @@ CPU8080State.prototype.getByte = function(addr) /** * getWord(addr) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} addr is a linear address * @return {number} word (16-bit) value at that address */ -CPU8080State.prototype.getWord = function(addr) +CPUState8080.prototype.getWord = function(addr) { return this.bus.getShort(addr); }; @@ -858,11 +858,11 @@ CPU8080State.prototype.getWord = function(addr) /** * setByte(addr, b) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} addr is a linear address * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb) */ -CPU8080State.prototype.setByte = function(addr, b) +CPUState8080.prototype.setByte = function(addr, b) { this.bus.setByte(addr, b); }; @@ -870,11 +870,11 @@ CPU8080State.prototype.setByte = function(addr, b) /** * setWord(addr, w) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} addr is a linear address * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe) */ -CPU8080State.prototype.setWord = function(addr, w) +CPUState8080.prototype.setWord = function(addr, w) { this.bus.setShort(addr, w); }; @@ -882,10 +882,10 @@ CPU8080State.prototype.setWord = function(addr, w) /** * getPCByte() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} byte at the current PC; PC advanced by 1 */ -CPU8080State.prototype.getPCByte = function() +CPUState8080.prototype.getPCByte = function() { var b = this.getByte(this.regPC); this.setPC(this.regPC + 1); @@ -895,10 +895,10 @@ CPU8080State.prototype.getPCByte = function() /** * getPCWord() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} word at the current PC; PC advanced by 2 */ -CPU8080State.prototype.getPCWord = function() +CPUState8080.prototype.getPCWord = function() { var w = this.getWord(this.regPC); this.setPC(this.regPC + 2); @@ -908,10 +908,10 @@ CPU8080State.prototype.getPCWord = function() /** * popWord() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {number} word popped from the current SP; SP increased by 2 */ -CPU8080State.prototype.popWord = function() +CPUState8080.prototype.popWord = function() { var w = this.getWord(this.regSP); this.setSP(this.regSP + 2); @@ -921,10 +921,10 @@ CPU8080State.prototype.popWord = function() /** * pushWord(w) * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} w is the word (16-bit) value to push at current SP; SP decreased by 2 */ -CPU8080State.prototype.pushWord = function(w) +CPUState8080.prototype.pushWord = function(w) { this.setSP(this.regSP - 2); this.setWord(this.regSP, w); @@ -933,10 +933,10 @@ CPU8080State.prototype.pushWord = function(w) /** * checkINTR() * - * @this {CPU8080State} + * @this {CPUState8080} * @return {boolean} true if execution may proceed, false if not */ -CPU8080State.prototype.checkINTR = function() +CPUState8080.prototype.checkINTR = function() { /* * If the Debugger is single-stepping, this.nStepCycles will always be zero, which we take @@ -976,10 +976,10 @@ CPU8080State.prototype.checkINTR = function() * nLevel can either be a valid interrupt level (0-7), or -1 to clear all pending interrupts * (eg, in the event of a system-wide reset). * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} nLevel (0-7, or -1 for all) */ -CPU8080State.prototype.clearINTR = function(nLevel) +CPUState8080.prototype.clearINTR = function(nLevel) { var bitsClear = nLevel < 0? 0xff : (1 << nLevel); this.intFlags &= ~bitsClear; @@ -989,9 +989,9 @@ CPU8080State.prototype.clearINTR = function(nLevel) /** * requestHALT() * - * @this {CPU8080State} + * @this {CPUState8080} */ -CPU8080State.prototype.requestHALT = function() +CPUState8080.prototype.requestHALT = function() { this.intFlags |= CPUDef8080.INTFLAG.HALT; this.nBurstCycles -= this.nStepCycles; @@ -1008,10 +1008,10 @@ CPU8080State.prototype.requestHALT = function() * by setting nStepCycles to zero. But before we do, we subtract nStepCycles from nBurstCycles, * so that the calculation of how many cycles were actually executed on this burst is correct. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} nLevel (0-7) */ -CPU8080State.prototype.requestINTR = function(nLevel) +CPUState8080.prototype.requestINTR = function(nLevel) { this.intFlags |= (1 << nLevel); if (this.getIF()) { @@ -1027,12 +1027,12 @@ CPU8080State.prototype.requestINTR = function(nLevel) * CPU type before passing the call to displayValue(); in the "old days", updateStatus() called * displayValue() directly (although then it was called displayReg()). * - * @this {CPU8080State} + * @this {CPUState8080} * @param {string} sReg * @param {number} nValue * @param {number} [cch] (default is 2 hex digits) */ -CPU8080State.prototype.updateReg = function(sReg, nValue, cch) +CPUState8080.prototype.updateReg = function(sReg, nValue, cch) { this.displayValue(sReg, nValue, cch || 2); }; @@ -1040,16 +1040,16 @@ CPU8080State.prototype.updateReg = function(sReg, nValue, cch) /** * updateStatus(fForce) * - * This provides periodic Control Panel updates (eg, a few times per second; see STATUS_UPDATES_PER_SECOND). + * This provides periodic Control Panel updates (eg, a few times per second; see YIELDS_PER_STATUS). * this is where we take care of any DOM updates (eg, register values) while the CPU is running. * - * Any high-frequency updates should be performed in updateVideo(), which should avoid DOM updates, since updateVideo() - * can be called up to 60 times per second (see VIDEO_UPDATES_PER_SECOND). + * Any high-frequency updates should be performed in updateVideo(), which should avoid DOM updates, + * since updateVideo() can be called up to 60 times per second. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {boolean} [fForce] (true will display registers even if the CPU is running and "live" registers are not enabled) */ -CPU8080State.prototype.updateStatus = function(fForce) +CPUState8080.prototype.updateStatus = function(fForce) { if (this.cLiveRegs) { if (fForce || !this.flags.fRunning || this.flags.fDisplayLiveRegs) { @@ -1091,13 +1091,13 @@ CPU8080State.prototype.updateStatus = function(fForce) * As a result, the Debugger's complete independence means you can run other 8086/8088 debuggers * (eg, DEBUG) inside the simulation without interference; you can even "debug" them with the Debugger. * - * @this {CPU8080State} + * @this {CPUState8080} * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored) * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive * number indicates successful completion of that many cycles (which should always be >= nMinCycles). */ -CPU8080State.prototype.stepCPU = function(nMinCycles) +CPUState8080.prototype.stepCPU = function(nMinCycles) { /* * The Debugger uses fComplete to determine if the instruction completed (true) or was interrupted @@ -1155,21 +1155,21 @@ CPU8080State.prototype.stepCPU = function(nMinCycles) }; /** - * CPU8080State.init() + * CPUState8080.init() * * This function operates on every HTML element of class "cpu", extracting the - * JSON-encoded parameters for the CPU8080State constructor from the element's "data-value" + * JSON-encoded parameters for the CPUState8080 constructor from the element's "data-value" * attribute, invoking the constructor (which in turn invokes the CPU constructor) - * to create a CPU8080State component, and then binding any associated HTML controls to the + * to create a CPUState8080 component, and then binding any associated HTML controls to the * new component. */ -CPU8080State.init = function() +CPUState8080.init = function() { var aeCPUs = Component.getElementsByClass(document, PC8080.APPCLASS, "cpu"); for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) { var eCPU = aeCPUs[iCPU]; var parmsCPU = Component.getComponentParms(eCPU); - var cpu = new CPU8080State(parmsCPU); + var cpu = new CPUState8080(parmsCPU); Component.bindComponentControls(cpu, eCPU, PC8080.APPCLASS); } }; @@ -1177,6 +1177,6 @@ CPU8080State.init = function() /* * Initialize every CPU module on the page */ -web.onInit(CPU8080State.init); +web.onInit(CPUState8080.init); -if (NODE) module.exports = CPU8080State; +if (NODE) module.exports = CPUState8080; diff --git a/modules/pc8080/lib/debugger.js b/modules/pc8080/lib/debugger.js index 411ebb097..afa709e84 100644 --- a/modules/pc8080/lib/debugger.js +++ b/modules/pc8080/lib/debugger.js @@ -361,7 +361,7 @@ if (DEBUGGER) { /* * TYPE_IREG values, based on the REG_* constants. * - * NOte that TYPE_M isn't really a register, just an alternative form of TYPE_HL | TYPE_MEM. + * Note that TYPE_M isn't really a register, just an alternative form of TYPE_HL | TYPE_MEM. */ Debugger8080.TYPE_A = (Debugger8080.REG_A << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE); Debugger8080.TYPE_B = (Debugger8080.REG_B << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE); @@ -673,7 +673,7 @@ if (DEBUGGER) { * @this {Debugger8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ Debugger8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/keyboard.js b/modules/pc8080/lib/keyboard.js index 49911c14e..22b5def73 100644 --- a/modules/pc8080/lib/keyboard.js +++ b/modules/pc8080/lib/keyboard.js @@ -541,7 +541,7 @@ Keyboard8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValu * @this {Keyboard8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ Keyboard8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/panel.js b/modules/pc8080/lib/panel.js index ae2d05466..fd780a0df 100644 --- a/modules/pc8080/lib/panel.js +++ b/modules/pc8080/lib/panel.js @@ -87,7 +87,7 @@ Panel8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) * @this {Panel8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ Panel8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/ram.js b/modules/pc8080/lib/ram.js index 77501323a..37238ffc6 100644 --- a/modules/pc8080/lib/ram.js +++ b/modules/pc8080/lib/ram.js @@ -74,7 +74,7 @@ Component.subclass(RAM8080); * @this {RAM8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ RAM8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/rom.js b/modules/pc8080/lib/rom.js index e01554f10..b8a6e1ae6 100644 --- a/modules/pc8080/lib/rom.js +++ b/modules/pc8080/lib/rom.js @@ -158,7 +158,7 @@ ROM8080.CPM.VECTORS = [ROM8080.CPM.BIOS.VECTOR, ROM8080.CPM.BDOS.VECTOR]; * @this {ROM8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ ROM8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/serialport.js b/modules/pc8080/lib/serialport.js index 226646df1..4ba66a468 100644 --- a/modules/pc8080/lib/serialport.js +++ b/modules/pc8080/lib/serialport.js @@ -442,7 +442,7 @@ SerialPort8080.prototype.echoByte = function(b) * @this {SerialPort8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ SerialPort8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pc8080/lib/video.js b/modules/pc8080/lib/video.js index fd3585ac7..3ed414f93 100644 --- a/modules/pc8080/lib/video.js +++ b/modules/pc8080/lib/video.js @@ -399,7 +399,7 @@ Video8080.prototype.initBuffers = function() * @this {Video8080} * @param {Computer8080} cmp * @param {Bus8080} bus - * @param {CPU8080State} cpu + * @param {CPUState8080} cpu * @param {Debugger8080} dbg */ Video8080.prototype.initBus = function(cmp, bus, cpu, dbg) diff --git a/modules/pdp11/lib/bus.js b/modules/pdp11/lib/bus.js new file mode 100644 index 000000000..2f6d4cd66 --- /dev/null +++ b/modules/pdp11/lib/bus.js @@ -0,0 +1,767 @@ +/** + * @fileoverview Implements the PDP11 Bus component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var usr = require("../../shared/lib/usrlib"); + var Component = require("../../shared/lib/component"); + var State = require("../../shared/lib/state"); + var MemoryPDP11 = require("./memory"); + var MessagesPDP11 = require("./messages"); +} + +/** + * BusPDP11(cpu, dbg) + * + * The BusPDP11 component manages physical memory and I/O address spaces. + * + * The BusPDP11 component has no UI elements, so it does not require an init() handler, + * but it still inherits from the Component class and must be allocated like any + * other device component. It's currently allocated by the Computer's init() handler, + * which then calls the initBus() method of all the other components. + * + * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped + * devices), the address space must still be allocated through the BusPDP11 component via + * addMemory(). If the component needs something more than simple read/write storage, + * it must provide a custom controller. + * + * All port (I/O) operations are defined by external handlers; they register with us, + * and we manage those registrations and provide support for I/O breakpoints, but the + * only default I/O behavior we provide is ignoring writes to any unregistered output + * ports and returning 0xff from any unregistered input ports. + * + * @constructor + * @extends Component + * @param {Object} parmsBus + * @param {CPUStatePDP11} cpu + * @param {DebuggerPDP11} dbg + */ +function BusPDP11(parmsBus, cpu, dbg) +{ + Component.call(this, "Bus", parmsBus, BusPDP11); + + this.cpu = cpu; + this.dbg = dbg; + + this.nBusWidth = parmsBus['busWidth'] || 16; + + /* + * Compute all BusPDP11 memory block parameters, based on the width of the bus. + * + * Regarding blockTotal, we want to avoid using block overflow expressions like: + * + * iBlock < this.nBlockTotal? iBlock : 0 + * + * As long as we know that blockTotal is a power of two (eg, 256 or 0x100, in the case of + * nBusWidth == 20 and blockSize == 4096), we can define blockMask as (blockTotal - 1) and + * rewrite the previous expression as: + * + * iBlock & this.nBlockMask + * + * Bus Property Old hard-coded values (when nBusWidth was always 20) + * ------------ ---------------------------------------------------- + * this.nBusLimit 0xfffff + * this.nBusMask [same as busLimit] + * this.nBlockSize 4096 + * this.nBlockLen (this.nBlockSize >> 2) + * this.nBlockShift 12 + * this.nBlockLimit 0xfff + * this.nBlockTotal ((this.nBusLimit + this.nBlockSize) / this.nBlockSize) | 0 + * this.nBlockMask (this.nBlockTotal - 1) [ie, 0xff] + * + * Note that we choose a nBlockShift value (and thus a physical memory block size) based on "buswidth": + * + * Bus Width Block Shift Block Size + * --------- ----------- ---------- + * 16 bits (64Kb address space): 10 1Kb (64 maximum blocks) + * 20 bits (1Mb address space): 12 4Kb (256 maximum blocks) + * 24 bits (16Mb address space): 14 16Kb (1K maximum blocks) + * 32 bits (4Gb address space); 15 32Kb (128K maximum blocks) + * + * The coarser block granularities (ie, 16Kb and 32Kb) may cause problems for certain RAM and/or ROM + * allocations that are contiguous but are allocated out of order, or that have different controller + * requirements. Your choices, for the moment, are either to ensure the allocations are performed in + * order, or to choose smaller nBlockShift values (at the expense of a generating a larger block array). + */ + this.addrTotal = Math.pow(2, this.nBusWidth); + this.nBusLimit = this.nBusMask = (this.addrTotal - 1) | 0; + this.nBlockShift = (this.nBusWidth <= 16)? 10 : ((this.nBusWidth <= 20)? 12 : (this.nBusWidth <= 24? 14 : 15)); + this.nBlockSize = 1 << this.nBlockShift; + this.nBlockLen = this.nBlockSize >> 2; + this.nBlockLimit = this.nBlockSize - 1; + this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0; + this.nBlockMask = this.nBlockTotal - 1; + this.assert(this.nBlockMask <= BusPDP11.BlockInfo.num.mask); + + /* + * Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by + * port, of sub-arrays which contain: + * + * [0]: registered function to call for every I/O access + * + * The registered function is called with the port address, and if the access was triggered by the CPU, + * the instruction pointer (IP) at the point of access. + * + * WARNING: Unlike the (old) read and write memory notification functions, these support only one + * pair of input/output functions per port. A more sophisticated architecture could support a list + * of chained functions across multiple components, but I doubt that will be necessary here. + * + * UPDATE: The Debugger now piggy-backs on these arrays to indicate ports for which it wants notification + * of I/O. In those cases, the registered component/function elements may or may not be set, but the + * following additional element will be set: + * + * [1]: true to break on I/O, false to ignore I/O + * + * The false case is important if fPortInputBreakAll and/or fPortOutputBreakAll is set, because it allows the + * Debugger to selectively ignore specific ports. + */ + this.aPortInputNotify = []; + this.aPortOutputNotify = []; + this.fPortInputBreakAll = this.fPortOutputBreakAll = false; + + /* + * By default, all I/O ports are 1 byte wide; ports that are wider must add themselves to one or both of + * these lists, using addPortInputWidth() and/or addPortOutputWidth(). + */ + this.aPortInputWidth = []; + this.aPortOutputWidth = []; + + /* + * Allocate empty Memory blocks to span the entire physical address space. + */ + this.initMemory(); + + this.setReady(); +} + +Component.subclass(BusPDP11); + +BusPDP11.ERROR = { + ADD_MEM_INUSE: 1, + ADD_MEM_BADRANGE: 2, + SET_MEM_BADRANGE: 4, + REM_MEM_BADRANGE: 5 +}; + +/** + * @typedef {number} + */ +var BlockInfo; + +/** + * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array. + * + * @typedef {{ + * num: BitField, + * count: BitField, + * btmod: BitField, + * type: BitField + * }} + */ +BusPDP11.BlockInfo = usr.defineBitFields({num:20, count:8, btmod:1, type:3}); + +/** + * BusInfoPDP11 object definition (returned by scanMemory()) + * + * cbTotal: total bytes allocated + * cBlocks: total Memory blocks allocated + * aBlocks: array of allocated Memory block numbers + * + * @typedef {{ + * cbTotal: number, + * cBlocks: number, + * aBlocks: Array. + * }} + */ +var BusInfoPDP11; + +/** + * initMemory() + * + * Allocate enough (empty) Memory blocks to span the entire physical address space. + * + * @this {BusPDP11} + */ +BusPDP11.prototype.initMemory = function() +{ + var block = new MemoryPDP11(); + block.copyBreakpoints(this.dbg); + this.aMemBlocks = new Array(this.nBlockTotal); + for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) { + this.aMemBlocks[iBlock] = block; + } +}; + +/** + * reset() + * + * @this {BusPDP11} + */ +BusPDP11.prototype.reset = function() +{ +}; + +/** + * powerUp(data, fRepower) + * + * We don't need a powerDown() handler, because for largely historical reasons, our state is saved by saveMemory(), + * which called by the CPU. + * + * However, we do need a powerUp() handler, because on resumable machines, the Computer's onReset() function calls + * everyone's powerUp() handler rather than their reset() handler. + * + * TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler. + * In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub. + * + * @this {BusPDP11} + * @param {Object|null} data (always null because we supply no powerDown() handler) + * @param {boolean} [fRepower] + * @return {boolean} true if successful, false if failure + */ +BusPDP11.prototype.powerUp = function(data, fRepower) +{ + if (!fRepower) this.reset(); + return true; +}; + +/** + * addMemory(addr, size, type) + * + * Adds new Memory blocks to the specified address range. Any Memory blocks previously + * added to that range must first be removed via removeMemory(); otherwise, you'll get + * an allocation conflict error. This helps prevent address calculation errors, redundant + * allocations, etc. + * + * We've relaxed some of the original requirements (ie, that addresses must start at a + * block-granular address, or that sizes must be equal to exactly one or more blocks), + * because machines with large block sizes can make it impossible to load certain ROMs at + * their required addresses. Every allocation still allocates a whole number of blocks. + * + * Even so, BusPDP11 memory management does NOT provide a general-purpose heap. Most memory + * allocations occur during machine initialization and never change. In particular, there + * is NO support for removing partial-block allocations. + * + * Each Memory block keeps track of a start address (addr) and length (used), indicating + * the used space within the block; any free space that precedes or follows that used space + * can be allocated later, by simply extending the beginning or ending of the previously used + * space. However, any holes that might have existed between the original allocation and an + * extension are subsumed by the extension. + * + * @this {BusPDP11} + * @param {number} addr is the starting physical address of the request + * @param {number} size of the request, in bytes + * @param {number} type is one of the MemoryPDP11.TYPE constants + * @return {boolean} true if successful, false if not + */ +BusPDP11.prototype.addMemory = function(addr, size, type) +{ + var addrNext = addr; + var sizeLeft = size; + var iBlock = addrNext >>> this.nBlockShift; + + while (sizeLeft > 0 && iBlock < this.aMemBlocks.length) { + + var block = this.aMemBlocks[iBlock]; + var addrBlock = iBlock * this.nBlockSize; + var sizeBlock = this.nBlockSize - (addrNext - addrBlock); + if (sizeBlock > sizeLeft) sizeBlock = sizeLeft; + + if (block && block.size) { + if (block.type == type) { + /* + * Where there is already a similar block with a non-zero size, we allow the allocation only if: + * + * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or + * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block) + */ + if (addrNext + sizeLeft <= block.addr) { + block.used += (block.addr - addrNext); + block.addr = addrNext; + return true; + } + if (addrNext >= block.addr + block.used) { + var sizeAvail = block.size - (addrNext - addrBlock); + if (sizeAvail > sizeLeft) sizeAvail = sizeLeft; + block.used = addrNext - block.addr + sizeAvail; + addrNext = addrBlock + this.nBlockSize; + sizeLeft -= sizeAvail; + iBlock++; + continue; + } + } + return this.reportError(BusPDP11.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft); + } + + var blockNew = new MemoryPDP11(addrNext, sizeBlock, this.nBlockSize, type); + blockNew.copyBreakpoints(this.dbg, block); + this.aMemBlocks[iBlock++] = blockNew; + + addrNext = addrBlock + this.nBlockSize; + sizeLeft -= sizeBlock; + } + + if (sizeLeft <= 0) { + this.status(Math.floor(size / 1024) + "Kb " + MemoryPDP11.TYPE.NAMES[type] + " at " + str.toHexWord(addr)); + return true; + } + + return this.reportError(BusPDP11.ERROR.ADD_MEM_BADRANGE, addr, size); +}; + +/** + * cleanMemory(addr, size) + * + * @this {BusPDP11} + * @param {number} addr + * @param {number} size + * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process + */ +BusPDP11.prototype.cleanMemory = function(addr, size) +{ + var fClean = true; + var iBlock = addr >>> this.nBlockShift; + while (size > 0 && iBlock < this.aMemBlocks.length) { + if (this.aMemBlocks[iBlock].fDirty) { + this.aMemBlocks[iBlock].fDirty = fClean = false; + this.aMemBlocks[iBlock].fDirtyEver = true; + } + size -= this.nBlockSize; + iBlock++; + } + return fClean; +}; + +/** + * scanMemory(info, addr, size) + * + * Returns a BusInfoPDP11 object for the specified address range. + * + * @this {BusPDP11} + * @param {Object} [info] previous BusInfoPDP11, if any + * @param {number} [addr] starting address of range (0 if none provided) + * @param {number} [size] size of range, in bytes (up to end of address space if none provided) + * @return {Object} updated info (or new info if no previous info provided) + */ +BusPDP11.prototype.scanMemory = function(info, addr, size) +{ + if (addr == null) addr = 0; + if (size == null) size = (this.addrTotal - addr) | 0; + if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []}; + + var iBlock = addr >>> this.nBlockShift; + var iBlockMax = ((addr + size - 1) >>> this.nBlockShift); + + info.cbTotal = 0; + info.cBlocks = 0; + while (iBlock <= iBlockMax) { + var block = this.aMemBlocks[iBlock]; + info.cbTotal += block.size; + if (block.size) { + info.aBlocks.push(usr.initBitFields(BusPDP11.BlockInfo, iBlock, 0, 0, block.type)); + info.cBlocks++ + } + iBlock++; + } + return info; +}; + +/** + * getWidth() + * + * @this {BusPDP11} + * @return {number} + */ +BusPDP11.prototype.getWidth = function() +{ + return this.nBusWidth; +}; + +/** + * removeMemory(addr, size) + * + * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes. + * + * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface. + * + * @this {BusPDP11} + * @param {number} addr + * @param {number} size + * @return {boolean} true if successful, false if not + */ +BusPDP11.prototype.removeMemory = function(addr, size) +{ + if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) { + var iBlock = addr >>> this.nBlockShift; + while (size > 0) { + var blockOld = this.aMemBlocks[iBlock]; + var blockNew = new MemoryPDP11(addr); + blockNew.copyBreakpoints(this.dbg, blockOld); + this.aMemBlocks[iBlock++] = blockNew; + addr = iBlock * this.nBlockSize; + size -= this.nBlockSize; + } + return true; + } + return this.reportError(BusPDP11.ERROR.REM_MEM_BADRANGE, addr, size); +}; + +/** + * getMemoryBlocks(addr, size) + * + * @this {BusPDP11} + * @param {number} addr is the starting physical address + * @param {number} size of the request, in bytes + * @return {Array} of Memory blocks + */ +BusPDP11.prototype.getMemoryBlocks = function(addr, size) +{ + var aBlocks = []; + var iBlock = addr >>> this.nBlockShift; + while (size > 0 && iBlock < this.aMemBlocks.length) { + aBlocks.push(this.aMemBlocks[iBlock++]); + size -= this.nBlockSize; + } + return aBlocks; +}; + +/** + * setMemoryBlocks(addr, size, aBlocks, type) + * + * If no type is specified, then specified address range uses all the provided blocks as-is; + * this form of setMemoryBlocks() is used for complete physical aliases. + * + * Otherwise, new blocks are allocated with the specified type; the underlying memory from the + * provided blocks is still used, but the new blocks may have different access to that memory. + * + * @this {BusPDP11} + * @param {number} addr is the starting physical address + * @param {number} size of the request, in bytes + * @param {Array} aBlocks as returned by getMemoryBlocks() + * @param {number} [type] is one of the MemoryPDP11.TYPE constants + */ +BusPDP11.prototype.setMemoryBlocks = function(addr, size, aBlocks, type) +{ + var i = 0; + var iBlock = addr >>> this.nBlockShift; + while (size > 0 && iBlock < this.aMemBlocks.length) { + var block = aBlocks[i++]; + this.assert(block); + if (!block) break; + if (type !== undefined) { + var blockNew = new MemoryPDP11(addr); + blockNew.clone(block, type, this.dbg); + block = blockNew; + } + this.aMemBlocks[iBlock++] = block; + size -= this.nBlockSize; + } +}; + +/** + * getByte(addr) + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @return {number} byte (8-bit) value at that address + */ +BusPDP11.prototype.getByte = function(addr) +{ + return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr); +}; + +/** + * getByteDirect(addr) + * + * This is useful for the Debugger and other components that want to bypass getByte() breakpoint detection. + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @return {number} byte (8-bit) value at that address + */ +BusPDP11.prototype.getByteDirect = function(addr) +{ + return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr); +}; + +/** + * getShort(addr) + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @return {number} word (16-bit) value at that address + */ +BusPDP11.prototype.getShort = function(addr) +{ + var off = addr & this.nBlockLimit; + var iBlock = (addr & this.nBusMask) >>> this.nBlockShift; + if (off != this.nBlockLimit) { + return this.aMemBlocks[iBlock].readShort(off, addr); + } + return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8); +}; + +/** + * getShortDirect(addr) + * + * This is useful for the Debugger and other components that want to bypass getShort() breakpoint detection. + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @return {number} word (16-bit) value at that address + */ +BusPDP11.prototype.getShortDirect = function(addr) +{ + var off = addr & this.nBlockLimit; + var iBlock = (addr & this.nBusMask) >>> this.nBlockShift; + if (off != this.nBlockLimit) { + return this.aMemBlocks[iBlock].readShortDirect(off, addr); + } + return this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8); +}; + +/** + * setByte(addr, b) + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe) + */ +BusPDP11.prototype.setByte = function(addr, b) +{ + this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr); +}; + +/** + * setByteDirect(addr, b) + * + * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only + * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents). + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe) + */ +BusPDP11.prototype.setByteDirect = function(addr, b) +{ + this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr); +}; + +/** + * setShort(addr, w) + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe) + */ +BusPDP11.prototype.setShort = function(addr, w) +{ + var off = addr & this.nBlockLimit; + var iBlock = (addr & this.nBusMask) >>> this.nBlockShift; + if (off != this.nBlockLimit) { + this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr); + return; + } + this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr); + this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1); +}; + +/** + * setShortDirect(addr, w) + * + * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only + * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents). + * + * @this {BusPDP11} + * @param {number} addr is a physical address + * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe) + */ +BusPDP11.prototype.setShortDirect = function(addr, w) +{ + var off = addr & this.nBlockLimit; + var iBlock = (addr & this.nBusMask) >>> this.nBlockShift; + if (off != this.nBlockLimit) { + this.aMemBlocks[iBlock].writeShortDirect(off, w & 0xffff, addr); + return; + } + this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr); + this.aMemBlocks[iBlock & this.nBlockMask].writeByteDirect(0, (w >> 8) & 0xff, addr + 1); +}; + +/** + * addMemBreak(addr, fWrite) + * + * @this {BusPDP11} + * @param {number} addr + * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint + */ +BusPDP11.prototype.addMemBreak = function(addr, fWrite) +{ + if (DEBUGGER) { + var iBlock = addr >>> this.nBlockShift; + this.aMemBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite); + } +}; + +/** + * removeMemBreak(addr, fWrite) + * + * @this {BusPDP11} + * @param {number} addr + * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint + */ +BusPDP11.prototype.removeMemBreak = function(addr, fWrite) +{ + if (DEBUGGER) { + var iBlock = addr >>> this.nBlockShift; + this.aMemBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite); + } +}; + +/** + * saveMemory(fAll) + * + * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty, + * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed + * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least + * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them). + * + * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so: + * + * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...] + * + * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit + * integer (because they are formed using bit-wise operator rather than floating-point math operators), so don't be + * surprised to see negative numbers in the data. + * + * The above example assumes "uncompressed" data arrays. If we choose to use "compressed" data arrays, the data arrays + * will look like: + * + * [count0, dw0, count1, dw1, ...] + * + * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates + * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State + * helper methods compress() and decompress() to create and expand the compressed data arrays. + * + * @this {BusPDP11} + * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags) + * @return {Array} a + */ +BusPDP11.prototype.saveMemory = function(fAll) +{ + var i = 0; + var a = []; + + for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) { + var block = this.aMemBlocks[iBlock]; + /* + * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of + * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag, + * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine. + */ + if (fAll && block.type != MemoryPDP11.TYPE.ROM || block.fDirty || block.fDirtyEver) { + a[i++] = iBlock; + a[i++] = State.compress(block.save()); + } + } + + return a; +}; + +/** + * restoreMemory(a) + * + * This restores the contents of all Memory blocks; called by CPUState.restore(). + * + * In theory, we ONLY have to save/restore block contents. Other block attributes, + * like the type, the memory controller (if any), and the active memory access functions, + * should already be restored, since every component (re)allocates all the memory blocks + * it was using when it's restored. And since the CPU is guaranteed to be the last + * component to be restored, all those blocks (and their attributes) should be in place now. + * + * See saveMemory() for more information on how the memory block contents are saved. + * + * @this {BusPDP11} + * @param {Array} a + * @return {boolean} true if successful, false if not + */ +BusPDP11.prototype.restoreMemory = function(a) +{ + var i; + for (i = 0; i < a.length - 1; i += 2) { + var iBlock = a[i]; + var adw = a[i+1]; + if (adw && adw.length < this.nBlockLen) { + adw = State.decompress(adw, this.nBlockLen); + } + var block = this.aMemBlocks[iBlock]; + if (!block || !block.restore(adw)) { + /* + * Either the block to restore hasn't been allocated, indicating a change in the machine + * configuration since it was last saved (the most likely explanation) or there's some internal + * inconsistency (eg, the block size is wrong). + */ + Component.error("Unable to restore memory block " + iBlock); + return false; + } + } + return true; +}; + +/** + * reportError(op, addr, size, fQuiet) + * + * @this {BusPDP11} + * @param {number} op + * @param {number} addr + * @param {number} size + * @param {boolean} [fQuiet] (true if any error should be quietly logged) + * @return {boolean} false + */ +BusPDP11.prototype.reportError = function(op, addr, size, fQuiet) +{ + var sError = "Memory block error (" + op + ": " + str.toHex(addr) + "," + str.toHex(size) + ")"; + if (fQuiet) { + if (this.dbg) { + this.dbg.message(sError); + } else { + this.log(sError); + } + } else { + Component.error(sError); + } + return false; +}; + +if (NODE) module.exports = BusPDP11; diff --git a/modules/pdp11/lib/computer.js b/modules/pdp11/lib/computer.js new file mode 100644 index 000000000..515906375 --- /dev/null +++ b/modules/pdp11/lib/computer.js @@ -0,0 +1,1595 @@ +/** + * @fileoverview Implements the PDP11 Computer component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var usr = require("../../shared/lib/usrlib"); + var web = require("../../shared/lib/weblib"); + var UserAPI = require("../../shared/lib/userapi"); + var ReportAPI = require("../../shared/lib/reportapi"); + var Component = require("../../shared/lib/component"); + var State = require("../../shared/lib/state"); + var PDP11 = require("./defines"); + var BusPDP11 = require("./bus"); + var MessagesPDP11 = require("./messages"); +} + +/** + * ComputerPDP11(parmsComputer, parmsMachine, fSuspended) + * + * @constructor + * @extends Component + * @param {Object} parmsComputer + * @param {Object} [parmsMachine] + * @param {boolean} [fSuspended] + * + * The ComputerPDP11 component has no required (parmsComputer) properties, but it does + * support the following: + * + * autoPower: true to automatically power the computer (default), false to wait; + * false is honored only if a "power" button binding exists. + * + * busWidth: number of memory address lines (address bits) on the computer's "bus"; + * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing, + * while 24 is required for 80286 protected-mode addressing. This value is passed + * directly through to the Bus component; see that component for more details. + * + * resume: one of the ComputerPDP11.RESUME constants, which are as follows: + * '0' if resume disabled (default) + * '1' if enabled without prompting + * '2' if enabled with prompting + * '3' if enabled with prompting and auto-delete + * or a string containing the path of a predefined JSON-encoded state + * + * state: the path to JSON-encoded state file (see details regarding 'state' below) + * + * The parmsMachine object, if provided, may contain any of: + * + * autoMount: if set, this should override any 'autoMount' property in the FDC's + * parmsFDC object. + * + * autoPower: if set, this should override any 'autoPower' property in the ComputerPDP11's + * parmsComputer object. + * + * messages: if set, this should override any 'messages' property in the Debugger's + * parmsDbg object. + * + * state: if set, this should override any 'state' property in the ComputerPDP11's + * parmsComputer object. + * + * url: the location of the machine XML file + * + * If a predefined state is supplied AND it's successfully loaded, then resume behavior + * defaults to '1' (ie, resume enabled without prompting). + * + * This component insures that all components are ready before "powering" them. + * + * Different components become ready at different times, and initialization order (ie, + * the order the scripts are combined on the page) only partially determines readiness. + * This is because components like ROM and Video must finish loading their resource files + * before they are ready. Other components become ready after we call their initBus() + * function, because they have a Bus or CPU dependency, such as access to memory management + * functions. And other components, like CPU and Panel, are ready as soon as their + * constructor finishes. + * + * Once a component has indicated it's ready, we call its powerUp() notification + * function (if it has one--it's optional). We call the CPU's powerUp() function last, + * so that the CPU is assured that all other components are ready and "powered". + */ +function ComputerPDP11(parmsComputer, parmsMachine, fSuspended) { + + Component.call(this, "Computer", parmsComputer, ComputerPDP11, MessagesPDP11.COMPUTER); + + this.flags.fPowered = false; + + this.setMachineParms(parmsMachine); + + this.fAutoPower = this.getMachineParm('autoPower', parmsComputer); + + /* + * nPowerChange is 0 while the power state is stable, 1 while power is transitioning + * to "on", and -1 while power is transitioning to "off". + */ + this.nPowerChange = 0; + + /* + * TODO: Deprecate 'buswidth' (it should have always used camelCase) + */ + this.nBusWidth = parmsComputer['busWidth'] || parmsComputer['buswidth']; + + this.resume = ComputerPDP11.RESUME_NONE; + this.sStateData = null; + this.fStateData = false; // remembers if sStateData was loaded + this.fServerState = false; + + this.url = this.getMachineParm('url') || ""; + + /* + * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be + * non-zero, convert to base 36, and chop off the leading digit and "decimal" point. + */ + this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12); + this.sUserID = this.queryUserID(); + + /* + * Find the appropriate CPU (and Debugger and Control Panel, if any) + * + * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here, + * where we know getComponentByType() will only return an CPUState object or null), wrap the expression + * in parentheses. I never knew this until I stumbled across it in "Closure: The Definitive Guide". + */ + this.cpu = /** @type {CPUStatePDP11} */ (Component.getComponentByType("CPU", this.id)); + if (!this.cpu) { + Component.error("Unable to find CPU component"); + return; + } + this.dbg = /** @type {DebuggerPDP11} */ (Component.getComponentByType("Debugger", this.id)); + + /* + * Initialize the Bus component + */ + this.bus = new BusPDP11({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg); + + /* + * Iterate through all the components and connect them to the Control Panel, if any + */ + var iComponent, component; + var aComponents = Component.getComponents(this.id); + this.panel = /** @type {PanelPDP11} */ (Component.getComponentByType("Panel", this.id)); + + if (this.panel && this.panel.controlPrint) { + for (iComponent = 0; iComponent < aComponents.length; iComponent++) { + component = aComponents[iComponent]; + /* + * I can think of many "cleaner" ways for the Control Panel component to pass its + * notice(), println(), etc, overrides on to all the other components, but it's just + * too darn convenient to slam those overrides into the components directly. + */ + component.notice = this.panel.notice; + component.println = this.panel.println; + component.controlPrint = this.panel.controlPrint; + } + } + + this.println(PDP11.APPNAME + " v" + (XMLVERSION || PDP11.APPVERSION) + "\n" + COPYRIGHT + "\n" + LICENSE); + + if (DEBUG && this.messageEnabled()) this.printMessage("TYPEDARRAYS: " + TYPEDARRAYS); + + /* + * Iterate through all the components again and call their initBus() handler, if any + */ + for (iComponent = 0; iComponent < aComponents.length; iComponent++) { + component = aComponents[iComponent]; + if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg); + } + + var sStatePath = null; + var sResume = parmsComputer['resume']; + if (sResume !== undefined) { + /* + * DEPRECATE: This goofiness is a holdover from when the 'resume' property was a string (either a + * single-digit string or a path); now it's always a number, so it never has a 'length' property and + * the call to parseInt() is unnecessary. + */ + if (sResume.length > 1) { + sStatePath = this.sResumePath = sResume; + } else { + this.resume = parseInt(sResume, 10); + } + } + + /* + * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature; + * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state + * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file. + * + * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists. + * So we have to peek at localStorage, and unfortunately, the only way to "peek" is to actually load the data, + * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've + * already loaded. + * + * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that + * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in + * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off). + */ + var fAllowResume; + var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state']; + + if (sState) { + sStatePath = this.sStatePath = sState; + if (!fAllowResume) { + this.fServerState = true; + this.resume = ComputerPDP11.RESUME_NONE; + } + if (this.resume) { + this.stateComputer = new State(this, PDP11.APPVERSION); + if (this.stateComputer.load()) { + sStatePath = null; + } else { + delete this.stateComputer; + } + } + } + + /* + * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set, + * then we have the option of resuming from a server-side state, assuming a valid USERID. + */ + if (!sStatePath && this.resume) { + sStatePath = this.getServerStatePath(); + if (sStatePath) this.fServerState = true; + } + + if (!sStatePath) { + this.setReady(); + } else { + var cmp = this; + web.getResource(sStatePath, null, true, function(sURL, sResource, nErrorCode) { + cmp.doneLoad(sURL, sResource, nErrorCode); + }); + } + + if (!this.bindings["power"]) this.fAutoPower = true; + + /* + * Power on the computer, giving every component the opportunity to reset or restore itself. + */ + if (!fSuspended && this.fAutoPower) this.wait(this.powerOn); +} + +Component.subclass(ComputerPDP11); + +ComputerPDP11.STATE_FAILSAFE = "failsafe"; +ComputerPDP11.STATE_VALIDATE = "validate"; +ComputerPDP11.STATE_TIMESTAMP = "timestamp"; +ComputerPDP11.STATE_VERSION = "version"; +ComputerPDP11.STATE_HOSTURL = "url"; +ComputerPDP11.STATE_BROWSER = "browser"; +ComputerPDP11.STATE_USERID = "user"; + +/* + * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for + * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states + * whenever a resume is declined). As a result, the only "end-user" values are 0, 1 and 2. + */ +ComputerPDP11.RESUME_REPOWER = -1; // resume without changing any state (for internal use only) +ComputerPDP11.RESUME_NONE = 0; // default (no resume) +ComputerPDP11.RESUME_AUTO = 1; // automatically save/restore state +ComputerPDP11.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded) +ComputerPDP11.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented) + +/** + * getMachineID() + * + * @return {string} + */ +ComputerPDP11.prototype.getMachineID = function() +{ + return this.sMachineID; +}; + +/** + * setMachineParms(parmsMachine) + * + * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any). + * + * @param {Object} [parmsMachine] + */ +ComputerPDP11.prototype.setMachineParms = function(parmsMachine) +{ + if (!parmsMachine) { + var sParms; + if (typeof resources == 'object' && (sParms = resources['parms'])) { + try { + parmsMachine = /** @type {Object} */ (eval("(" + sParms + ")")); + } catch(e) { + Component.error(e.message + " (" + sParms + ")"); + } + } + } + this.parmsMachine = parmsMachine; +}; + +/** + * getMachineParm(sParm, parmsComponent) + * + * If the machine parameter doesn't exist, we check for a matching component parameter (if parmsComponent is provided), + * and failing that, we check the bundled resources (if any). + * + * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists, then we return + * 'state' back to the caller (ie, the name of the resource), so that the caller will then attempt to load the 'state' + * resource to obtain the actual state. + * + * @param {string} sParm + * @param {Object} [parmsComponent] + * @return {string|undefined} + */ +ComputerPDP11.prototype.getMachineParm = function(sParm, parmsComponent) +{ + /* + * When checking parmsURL, the check is allowed be a bit looser, because URL parameters are + * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer + * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'), + * but there are limits to my paranoia. + */ + var sParmLC = sParm.toLowerCase(); + var value = Component.parmsURL[sParm] || Component.parmsURL[sParmLC]; + + if (value === undefined && this.parmsMachine) { + value = this.parmsMachine[sParm]; + } + if (value === undefined && parmsComponent) { + value = parmsComponent[sParm]; + } + if (value === undefined && typeof resources == 'object' && resources[sParm]) { + value = sParm; + } + return value; +}; + +/** + * saveMachineParms() + * + * @return {string|null} + */ +ComputerPDP11.prototype.saveMachineParms = function() +{ + return this.parmsMachine? JSON.stringify(this.parmsMachine) : null; +}; + +/** + * getUserID() + * + * @return {string} + */ +ComputerPDP11.prototype.getUserID = function() +{ + return this.sUserID || ""; +}; + +/** + * doneLoad(sURL, sStateData, nErrorCode) + * + * @this {ComputerPDP11} + * @param {string} sURL + * @param {string} sStateData + * @param {number} nErrorCode + */ +ComputerPDP11.prototype.doneLoad = function(sURL, sStateData, nErrorCode) +{ + if (!nErrorCode) { + this.sStateData = sStateData; + this.fStateData = true; + if (DEBUG && this.messageEnabled()) { + this.printMessage("loaded state file " + sURL.replace(this.sUserID || "xxx", "xxx")); + } + } else { + this.sResumePath = null; + this.fServerState = false; + this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + str.trim(sStateData) : '') + ')'); + } + this.setReady(); +}; + +/** + * wait(fn, parms) + * + * wait() waits until every component is ready (including ourselves, the last component we check), then calls the + * specified Computer method. + * + * TODO: The Closure Compiler makes it difficult for us to define a function type for "fn" that works in all cases; + * sometimes we want to pass a function that takes only a "number", and other times we want to pass a function that + * takes only an "Array" (the type will mirror that of the "parms" parameter). However, the Closure Compiler insists + * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped + * function declaration, instead of something stricter like: + * + * param {function(this:Computer, (number|Array|undefined)): undefined} fn + * + * @this {ComputerPDP11} + * @param {function(...)} fn + * @param {number|Array} [parms] optional parameters + */ +ComputerPDP11.prototype.wait = function(fn, parms) +{ + var computer = this; + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) { + var component = (iComponent < aComponents.length ? aComponents[iComponent] : this); + if (!component.isReady()) { + component.isReady(function onComponentReady() { + computer.wait(fn, parms); + }); + return; + } + } + if (DEBUG && this.messageEnabled()) this.printMessage("ComputerPDP11.wait(ready)"); + fn.call(this, parms); +}; + +/** + * validateState(stateComputer) + * + * NOTE: We clear() stateValidate only when there's no stateComputer. + * + * @this {ComputerPDP11} + * @param {State|null} [stateComputer] + * @return {boolean} true if state passes validation, false if not + */ +ComputerPDP11.prototype.validateState = function(stateComputer) +{ + var fValid = true; + var stateValidate = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_VALIDATE); + if (stateValidate.load() && stateValidate.parse()) { + var sTimestampValidate = stateValidate.get(ComputerPDP11.STATE_TIMESTAMP); + var sTimestampComputer = stateComputer? stateComputer.get(ComputerPDP11.STATE_TIMESTAMP) : "unknown"; + if (sTimestampValidate != sTimestampComputer) { + this.notice("Machine state may be out-of-date\n(" + sTimestampValidate + " vs. " + sTimestampComputer + ")\nCheck your browser's local storage limits"); + fValid = false; + if (!stateComputer) stateValidate.clear(); + } else { + if (DEBUG && this.messageEnabled()) { + this.printMessage("Last state: " + sTimestampComputer + " (validate: " + sTimestampValidate + ")"); + } + } + } + return fValid; +}; + +/** + * powerOn(resume) + * + * Power every component "up", applying any previously available state information. + * + * @this {ComputerPDP11} + * @param {number} [resume] is a valid RESUME value; default is this.resume + */ +ComputerPDP11.prototype.powerOn = function(resume) +{ + if (resume === undefined) { + resume = this.resume || (this.sStateData? ComputerPDP11.RESUME_AUTO : ComputerPDP11.RESUME_NONE); + } + + if (DEBUG && this.messageEnabled()) { + this.printMessage("ComputerPDP11.powerOn(" + (resume == ComputerPDP11.RESUME_REPOWER ? "repower" : (resume ? "resume" : "")) + ")"); + } + + if (this.nPowerChange) { + return; + } + this.nPowerChange++; + + var fRepower = false; + var fRestore = false; + this.fRestoreError = false; + var stateComputer = this.stateComputer || new State(this, PDP11.APPVERSION); + + if (resume == ComputerPDP11.RESUME_REPOWER) { + fRepower = true; + } + else if (resume > ComputerPDP11.RESUME_NONE) { + if (stateComputer.load(this.sStateData)) { + /* + * Since we're resuming something (either a predefined state or a state from localStorage), let's + * create a "failsafe" checkpoint in localStorage, and destroy it at the end of a successful powerOn(). + * Which means, of course, that if a previous "failsafe" checkpoint already exists, something bad + * may have happened the last time around. + */ + this.stateFailSafe = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_FAILSAFE); + if (this.stateFailSafe.load()) { + this.powerReport(stateComputer); + /* + * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it + * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to + * restore, the state will be removed. + */ + resume = ComputerPDP11.RESUME_PROMPT; + /* + * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail + * with a "read only" error (eg, "TypeError: Cannot assign to read only property 'timestamp'"). + */ + this.stateFailSafe.unload(); + } + + this.stateFailSafe.set(ComputerPDP11.STATE_TIMESTAMP, usr.getTimestamp()); + this.stateFailSafe.store(); + + var fValidate = this.resume && !this.fServerState; + if (resume == ComputerPDP11.RESUME_AUTO || web.confirmUser("Click OK to restore the previous " + PDP11.APPNAME + " machine state, or CANCEL to reset the machine.")) { + fRestore = stateComputer.parse(); + if (fRestore) { + var sCode = stateComputer.get(UserAPI.RES.CODE); + var sData = stateComputer.get(UserAPI.RES.DATA); + if (sCode) { + if (sCode == UserAPI.CODE.OK) { + stateComputer.load(sData); + } else { + /* + * A missing (or not yet created) state file is no cause for alarm, but other errors might be + */ + if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) { + this.notice("Error: " + sData); + if (sData == UserAPI.FAIL.VERIFY) this.resetUserID(); + } else { + this.println(sCode + ": " + sData); + } + /* + * Try falling back to the state that we should have saved in localStorage, as a backup to the + * server-side state. + */ + stateComputer.unload(); // discard the invalid server-side state first + if (stateComputer.load()) { + fRestore = stateComputer.parse(); + fValidate = true; + } else { + fRestore = false; // hmmm, there was nothing in localStorage either + } + } + } + } + /* + * If the load/parse was successful, and it was from localStorage (not sStateData), + * then we should to try verify that localStorage snapshot is current. One reason it may + * NOT be current is if localStorage was full and we got a quota error during the last + * powerOff(). + */ + if (fValidate) this.validateState(fRestore? stateComputer : null); + } else { + /* + * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above. + */ + if (resume == ComputerPDP11.RESUME_PROMPT) stateComputer.clear(); + } + } else { + /* + * If there's no state, then there should also be no validation timestamp; if there is, then once again, + * we're probably dealing with a quota error. + */ + this.validateState(); + } + delete this.sStateData; + delete this.stateComputer; + } + + /* + * Start powering all components, including any data they may need to restore their state; + * we restore power to the CPU last. + */ + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent < aComponents.length; iComponent++) { + var component = aComponents[iComponent]; + if (component !== this && component != this.cpu) { + fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore); + } + } + + /* + * Assuming this is not a repower, we must perform another wait, because some components may + * have marked themselves as "not ready" again (eg, the FDC component, if the restore forced it + * to mount one or more additional disk images). + */ + var aParms = [stateComputer, resume, fRestore]; + + if (resume != ComputerPDP11.RESUME_REPOWER) { + this.wait(this.donePowerOn, aParms); + return; + } + this.donePowerOn(aParms); +}; + +/** + * powerRestore(component, stateComputer, fRepower, fRestore) + * + * @this {ComputerPDP11} + * @param {Component} component + * @param {State} stateComputer + * @param {boolean} fRepower + * @param {boolean} fRestore + * @return {boolean} true if restore should continue, false if not + */ +ComputerPDP11.prototype.powerRestore = function(component, stateComputer, fRepower, fRestore) +{ + if (!component.flags.fPowered) { + + component.flags.fPowered = true; + + if (component.powerUp) { + + var data = null; + if (fRestore) { + data = stateComputer.get(component.id); + if (!data) { + /* + * This is a hack that makes it possible for a machine whose ID has been + * supplemented with a suffix (a single letter or digit) to find object IDs + * in states created from a machine without the suffix. + * + * For example, if a state file was created from a machine with ID "ibm5160" + * but the current machine is "ibm5160a", this attempts a second lookup with + * "ibm5160", enabling us to find objects that match the original machine ID + * (eg, "ibm5160.romEGA"). + */ + data = stateComputer.get(component.id.replace(/[a-z0-9]\./i, '.')); + } + } + + /* + * State.get() will return whatever was originally passed to State.set() (eg, an + * Object or a string), but components are supposed to store only Objects, so if a + * string comes back, something went wrong. By explicitly eliminating "string" data, + * the Closure Compiler stops complaining that we might be passing strings to our + * powerUp() functions (even though we know we're not). + * + * TODO: Determine if there's some way to coerce the Closure Compiler into treating + * data as Object or null, without having to include this runtime check. An assert + * would be a good idea, but this is overkill. + */ + if (typeof data === "string") data = null; + + /* + * If computer is null, this is simply a repower notification, which most components + * don't do anything with. Exceptions include: CPU (since it may be halted) and Video + * (since its screen may be "turned off"). + */ + if (!component.powerUp(data, fRepower) && data) { + + Component.error("Unable to restore state for " + component.type); + /* + * If this is a resume error for a machine that also has a predefined state + * AND we're not restoring from that state, then throw away the current state, + * prevent any new state from being created, and then force a reload, which will + * hopefully restore us to the functioning predefined state. + * + * TODO: Considering doing this in ALL cases, not just in situations where a + * 'state' exists but we're not actually resuming from it. + */ + if (this.sStatePath && !this.fStateData) { + stateComputer.clear(); + this.resume = ComputerPDP11.RESUME_NONE; + web.reloadPage(); + } else { + /* + * In all other cases, we set fRestoreError, which should trigger a call to + * powerReport() and then delete the offending state. + */ + this.fRestoreError = true; + } + /* + * Any failure triggers an automatic to call powerUp() again, without any state, + * in the hopes that the component can recover by performing a reset. + */ + component.powerUp(null); + /* + * We also disable the rest of the restore operation, because it's not clear + * the remaining state information can be trusted; the machine is already in an + * inconsistent state, so we're not likely to make things worse, and the only + * alternative (starting over and performing a state-less reset) isn't likely to make + * the user any happier. But, we'll see... we need some experience with the code. + */ + fRestore = false; + } + } + + if (!fRepower && component.comment) { + var asComments = component.comment.split("|"); + for (var i = 0; i < asComments.length; i++) { + component.status(asComments[i]); + } + } + } + return fRestore; +}; + +/** + * donePowerOn(aParms) + * + * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time. + * + * @this {ComputerPDP11} + * @param {Array} aParms containing [stateComputer, resume, fRestore] + */ +ComputerPDP11.prototype.donePowerOn = function(aParms) +{ + var stateComputer = aParms[0]; + var fRepower = (aParms[1] < 0); + var fRestore = aParms[2]; + + if (DEBUG && this.flags.fPowered && this.messageEnabled()) { + this.printMessage("ComputerPDP11.donePowerOn(): redundant"); + } + + this.fInitialized = true; + this.flags.fPowered = true; + var controlPower = this.bindings["power"]; + if (controlPower) controlPower.textContent = "Shutdown"; + + /* + * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU; + * the CPU should begin executing immediately, unless a debugger is attached. + */ + if (this.cpu) { + /* + * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)? + */ + this.powerRestore(this.cpu, stateComputer, fRepower, fRestore); + this.cpu.autoStart(); + } + + /* + * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new + * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same. + */ + if (this.fRestoreError) { + this.powerReport(stateComputer); + stateComputer.clear(); + } + + if (!fRepower && this.stateFailSafe) { + this.stateFailSafe.clear(); + delete this.stateFailSafe; + } + + this.nPowerChange = 0; +}; + +/** + * checkPower() + * + * @this {ComputerPDP11} + * @return {boolean} true if the computer is fully powered, false otherwise + */ +ComputerPDP11.prototype.checkPower = function() +{ + if (this.flags.fPowered) return true; + + var component = null, iComponent; + var aComponents = Component.getComponents(this.id); + for (iComponent = 0; iComponent < aComponents.length; iComponent++) { + component = aComponents[iComponent]; + if (component !== this && !component.flags.fReady) break; + } + if (iComponent == aComponents.length) { + for (iComponent = 0; iComponent < aComponents.length; iComponent++) { + component = aComponents[iComponent]; + if (component !== this && !component.flags.fPowered) break; + } + } + if (iComponent == aComponents.length) component = this; + var s = "The " + component.type + " component (" + component.id + ") is not " + (!component.flags.fReady? "ready yet" + (component.fnReady? " (waiting for notification)" : "") : "powered yet") + "."; + web.alertUser(s); + return false; +}; + +/** + * powerReport(stateComputer) + * + * @this {ComputerPDP11} + * @param {State} stateComputer + */ +ComputerPDP11.prototype.powerReport = function(stateComputer) +{ + if (web.confirmUser("There may be a problem with your " + PDP11.APPNAME + " machine.\n\nTo help us diagnose it, click OK to send this " + PDP11.APPNAME + " machine state to http://" + SITEHOST + ".")) { + web.sendReport(PDP11.APPNAME, PDP11.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString()); + } +}; + +/** + * powerOff(fSave, fShutdown) + * + * Power every component "down" and optionally save the machine state. + * + * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when + * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The + * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't + * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact + * it was only partially successful. + * + * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to + * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport() + * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new + * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future + * restores won't remount them either. + * + * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag + * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false, + * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to + * do in a "fRestoreIncomplete" situation. Also, we have to worry about Disk operations that fail for other reasons, + * making sure those failures don't interfere with the save process in the same way. + * + * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted, + * which doesn't seem like a huge problem. + * + * @this {ComputerPDP11} + * @param {boolean} [fSave] is true to request a saved state + * @param {boolean} [fShutdown] is true if the machine is being shut down + * @return {string|null} string representing the saved state (or null if error) + */ +ComputerPDP11.prototype.powerOff = function(fSave, fShutdown) +{ + var data; + var sState = "none"; + + if (DEBUG && this.messageEnabled()) { + this.printMessage("ComputerPDP11.powerOff(" + (fSave ? "save" : "nosave") + (fShutdown ? ",shutdown" : "") + ")"); + } + + if (this.nPowerChange) { + return null; + } + this.nPowerChange--; + + var stateComputer = new State(this, PDP11.APPVERSION); + var stateValidate = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_VALIDATE); + + var sTimestamp = usr.getTimestamp(); + stateValidate.set(ComputerPDP11.STATE_TIMESTAMP, sTimestamp); + stateComputer.set(ComputerPDP11.STATE_TIMESTAMP, sTimestamp); + stateComputer.set(ComputerPDP11.STATE_VERSION, APPVERSION); + stateComputer.set(ComputerPDP11.STATE_HOSTURL, web.getHostURL()); + stateComputer.set(ComputerPDP11.STATE_BROWSER, web.getUserAgent()); + + /* + * Always power the CPU "down" first, just to help insure it doesn't ask other components to do anything + * after they're no longer ready. + */ + if (this.cpu && this.cpu.powerDown) { + if (fShutdown) this.cpu.stopCPU(); + data = this.cpu.powerDown(fSave, fShutdown); + if (typeof data === "object") stateComputer.set(this.cpu.id, data); + if (fShutdown) { + this.cpu.flags.fPowered = false; + if (data === false) sState = null; + } + } + + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent < aComponents.length; iComponent++) { + var component = aComponents[iComponent]; + if (component.flags.fPowered) { + if (component.powerDown) { + data = component.powerDown(fSave, fShutdown); + if (typeof data === "object") stateComputer.set(component.id, data); + } + if (fShutdown) { + component.flags.fPowered = false; + if (data === false) sState = null; + } + } + } + + if (sState) { + if (fShutdown) { + var fClear = false; + var fClearAll = false; + if (fSave) { + if (this.sUserID) { + this.saveServerState(this.sUserID, stateComputer.toString()); + } + if (!stateValidate.store() || !stateComputer.store()) { + sState = null; + /* + * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away. + * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a + * particular machine's state. Historically, attempting to limp along with whatever localStorage + * is left just generates the same useless and annoying warnings over and over. + */ + fClear = fClearAll = true; + } + } + else { + /* + * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the + * current machine is "resumable", because there are situations where I have two configurations + * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the + * state of the former. + * + * So this code is here now strictly for callers to delete the state of a "resumable" machine, not as + * some paranoid clean-up operation. + * + * An undocumented feature of this operation is that if your configuration uses the special 'resume="3"' + * value, and you click the "Reset" button, and then you click OK to reset the everything, this will + * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed). + */ + if (this.resume) { + fClear = true; + fClearAll = (this.resume == ComputerPDP11.RESUME_DELETE); + } + } + if (fClear) { + stateComputer.clear(fClearAll); + } + } else { + sState = stateComputer.toString(); + } + } + + if (fShutdown) { + this.flags.fPowered = false; + var controlPower = this.bindings["power"]; + if (controlPower) controlPower.textContent = "Power"; + } + + this.nPowerChange = 0; + + return sState; +}; + +/** + * reset() + * + * Notify all (other) components with a reset() method that the Computer is being reset. + * + * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we + * allocated the Bus object ourselves, after all the other components were allocated, it ends + * up near the end of Component's list of components. Hence the special case for this.bus below. + * + * @this {ComputerPDP11} + */ +ComputerPDP11.prototype.reset = function() +{ + if (this.bus && this.bus.reset) { + /* + * TODO: Why does WebStorm think that this.bus.type is undefined? The base class (Component) + * constructor defines it. + */ + this.printMessage("Resetting " + this.bus.type); + this.bus.reset(); + } + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent < aComponents.length; iComponent++) { + var component = aComponents[iComponent]; + if (component !== this && component !== this.bus && component.reset) { + this.printMessage("Resetting " + component.type); + component.reset(); + } + } +}; + +/** + * start(ms, nCycles) + * + * Notify all (other) components with a start() method that the CPU has started. + * + * Note that we're called by runCPU(), which is why we exclude the CPU component, + * as well as ourselves. + * + * @this {ComputerPDP11} + * @param {number} ms + * @param {number} nCycles + */ +ComputerPDP11.prototype.start = function(ms, nCycles) +{ + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent < aComponents.length; iComponent++) { + var component = aComponents[iComponent]; + if (component.type == "CPU" || component === this) continue; + if (component.start) { + component.start(ms, nCycles); + } + } +}; + +/** + * stop(ms, nCycles) + * + * Notify all (other) components with a stop() method that the CPU has stopped. + * + * Note that we're called by runCPU(), which is why we exclude the CPU component, + * as well as ourselves. + * + * @this {ComputerPDP11} + * @param {number} ms + * @param {number} nCycles + */ +ComputerPDP11.prototype.stop = function(ms, nCycles) +{ + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent < aComponents.length; iComponent++) { + var component = aComponents[iComponent]; + if (component.type == "CPU" || component === this) continue; + if (component.stop) { + component.stop(ms, nCycles); + } + } +}; + +/** + * setBinding(sHTMLType, sBinding, control, sValue) + * + * @this {ComputerPDP11} + * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") + * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) + * @param {string} [sValue] optional data value + * @return {boolean} true if binding was successful, false if unrecognized binding request + */ +ComputerPDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) +{ + var computer = this; + + switch (sBinding) { + case "power": + this.bindings[sBinding] = control; + control.onclick = function onClickPower() { + computer.onPower(); + }; + return true; + + case "reset": + this.bindings[sBinding] = control; + control.onclick = function onClickReset() { + computer.onReset(); + }; + return true; + + /* + * Technically, this binding should now be called "saveState", to clearly distinguish it from + * the "Save Machine" control that's normally bound to the savePC() function in save.js. Saving + * an entire machine includes everything needed to start/restore the machine; eg, the machine + * XML configuration file(s) *and* the JSON-encoded machine state. + */ + case "save": + /* + * Since this feature depends on the server supporting the PCjs User API (see userapi.js), + * and since pcjs.org is no longer running a Node web server, we disable the feature for that + * particular host. + */ + if (str.endsWith(web.getHost(), "pcjs.org")) { + if (DEBUG) this.log("Remote user API not available"); + /* + * We could also simply hide the control; eg: + * + * control.style.display = "none"; + * + * but removing the control altogether seems better. + */ + control.parentNode.removeChild(/** @type {Node} */ (control)); + return false; + } + this.bindings[sBinding] = control; + control.onclick = function onClickSave() { + var sUserID = computer.queryUserID(true); + if (sUserID) { + /* + * I modified the test to include a check for sStatePath so that I could save new states + * for machines with existing states; otherwise, I'd have no (easy) way of capturing and + * updating their state. Making the machine (even temporarily) resumable would have been + * one work-around, but it's not appropriate for some machines, as their state is simply + * too large (for localStorage anyway, which is the default storage solution). + */ + var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath); + var sState = computer.powerOff(fSave); + if (fSave) { + computer.saveServerState(sUserID, sState); + } else { + computer.notice("Resume disabled, machine state not saved"); + } + } + /* + * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states: + * + * var sState = computer.powerOff(true); + * if (sState) { + * sState = "data:text/json;charset=utf-8," + encodeURIComponent(sState); + * window.open(sState); + * } + * + * Perhaps if I embedded the data in a link on the current page instead; eg: + * + * $('Download').appendTo('#container'); + */ + }; + return true; + + default: + break; + } + return false; +}; + +/** + * resetUserID() + */ +ComputerPDP11.prototype.resetUserID = function() +{ + web.setLocalStorageItem(ComputerPDP11.STATE_USERID, ""); + this.sUserID = null; +}; + +/** + * queryUserID(fPrompt) + * + * @param {boolean} [fPrompt] + * @returns {string|null|undefined} + */ +ComputerPDP11.prototype.queryUserID = function(fPrompt) +{ + var sUserID = this.sUserID; + if (!sUserID) { + sUserID = web.getLocalStorageItem(ComputerPDP11.STATE_USERID); + if (sUserID !== undefined) { + if (!sUserID && fPrompt) { + /* + * NOTE: Warning the user here that "Save" operations are not currently supported by pcjs.org is + * merely a precaution, because ordinarily, setBinding() should have already determined if we are + * running from pcjs.org and disabled any "Save" button. + */ + sUserID = web.promptUser("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below."); + if (sUserID) { + sUserID = this.verifyUserID(sUserID); + if (!sUserID) this.notice("The user ID is invalid."); + } + } + } else if (fPrompt) { + this.notice("Browser local storage is not available"); + } + } + return sUserID; +}; + +/** + * verifyUserID(sUserID) + * + * @this {ComputerPDP11} + * @param {string} sUserID + * @return {string} validated user ID, or null if error + */ +ComputerPDP11.prototype.verifyUserID = function(sUserID) +{ + this.sUserID = null; + var fMessages = DEBUG && this.messageEnabled(); + if (fMessages) this.printMessage("verifyUserID(" + sUserID + ")"); + var sRequest = web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID; + var response = web.getResource(sRequest); + var nErrorCode = response[0]; + var sResponse = response[1]; + if (!nErrorCode && sResponse) { + try { + response = eval("(" + sResponse + ")"); + if (response.code && response.code == UserAPI.CODE.OK) { + web.setLocalStorageItem(ComputerPDP11.STATE_USERID, response.data); + if (fMessages) this.printMessage(ComputerPDP11.STATE_USERID + " updated: " + response.data); + this.sUserID = response.data; + } else { + if (fMessages) this.printMessage(response.code + ": " + response.data); + } + } catch (e) { + Component.error(e.message + " (" + sResponse + ")"); + } + } else { + if (fMessages) this.printMessage("invalid response (error " + nErrorCode + ")"); + } + return this.sUserID; +}; + +/** + * getServerStatePath() + * + * @this {ComputerPDP11} + * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage) + */ +ComputerPDP11.prototype.getServerStatePath = function() +{ + var sStatePath = null; + if (this.sUserID) { + if (DEBUG && this.messageEnabled()) { + this.printMessage(ComputerPDP11.STATE_USERID + " for load: " + this.sUserID); + } + sStatePath = web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PDP11.APPVERSION); + } else { + if (DEBUG && this.messageEnabled()) { + this.printMessage(ComputerPDP11.STATE_USERID + " unavailable"); + } + } + return sStatePath; +}; + +/** + * saveServerState(sUserID, sState) + * + * @param {string} sUserID + * @param {string|null} sState + */ +ComputerPDP11.prototype.saveServerState = function(sUserID, sState) +{ + /* + * We must pass fSync == true, because (as I understand it) browsers will blow off any async + * requests when a page is being closed. Since our request is synchronous, storeServerState() + * should also return a result, but there's not much we can do with it, since browsers ALSO + * tend to blow off alerts() and the like when closing down. + */ + if (sState) { + if (DEBUG && this.messageEnabled()) { + this.printMessage("size of server state: " + sState.length + " bytes"); + } + var response = this.storeServerState(sUserID, sState, true); + if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) { + this.notice("Machine state saved to server"); + } else if (sState) { + var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE; + if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) { + sError = "Error: " + sError; + } else { + sError = "Error " + response[UserAPI.RES.CODE] + ": " + sError; + } + this.notice(sError); + this.resetUserID(); + } + } else { + if (DEBUG && this.messageEnabled()) { + this.printMessage("no state to store"); + } + } +}; + +/** + * storeServerState(sUserID, sState, fSync) + * + * @this {ComputerPDP11} + * @param {string} sUserID + * @param {string} sState + * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async) + * @return {*} server response if fSync is true and a response was received; otherwise null + */ +ComputerPDP11.prototype.storeServerState = function(sUserID, sState, fSync) +{ + if (DEBUG && this.messageEnabled()) { + this.printMessage(ComputerPDP11.STATE_USERID + " for store: " + sUserID); + } + /* + * TODO: Determine whether or not any browsers cancel our request if we're called during a browser "shutdown" event, + * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through). + */ + var dataPost = {}; + dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE; + dataPost[UserAPI.QUERY.USER] = sUserID; + dataPost[UserAPI.QUERY.STATE] = State.key(this, PDP11.APPVERSION); + dataPost[UserAPI.QUERY.DATA] = sState; + var sRequest = web.getHost() + UserAPI.ENDPOINT; + if (!fSync) { + web.getResource(sRequest, dataPost, true); + } else { + var response = web.getResource(sRequest, dataPost); + var sResponse = response[0]; + if (response[1]) { + if (sResponse) { + var i = sResponse.indexOf('\n'); + if (i > 0) sResponse = sResponse.substr(0, i); + if (!sResponse.indexOf("Error: ")) sResponse = sResponse.substr(7); + } + sResponse = '{"' + UserAPI.RES.CODE + '":' + response[1] + ',"' + UserAPI.RES.DATA + '":"' + sResponse + '"}'; + } + if (DEBUG && this.messageEnabled()) this.printMessage(sResponse); + return JSON.parse(sResponse); + } + return null; +}; + +/** + * onPower() + * + * This handles UI requests to toggle the computer's power (eg, see the "power" button binding). + * + * @this {ComputerPDP11} + */ +ComputerPDP11.prototype.onPower = function() +{ + if (!this.nPowerChange) { + if (!this.flags.fPowered) { + this.wait(this.powerOn); + } else { + this.powerOff(false, true); + } + } +}; + +/** + * onReset() + * + * This handles UI requests to reset the computer's state (eg, see the "reset" button binding). + * + * @this {ComputerPDP11} + */ +ComputerPDP11.prototype.onReset = function() +{ + /* + * I'm going to start with the presumption that it makes little sense for an "unpowered" computer to be "reset"; + * ditto if the power state is currently being changed. + */ + if (!this.flags.fPowered || this.nPowerChange) return; + + /* + * If this is a "resumable" machine (and it's not using a predefined state), then we overload the reset + * operation to offer an explicit "save or discard" option first. This is currently the only UI we offer to + * discard a machine's state, including any disk changes. The traditional "reset" operation is still available + * for non-resumable machines. + * + * TODO: Break this behavior out into a separate "discard" operation, in case the designer of the machine really + * wants to clutter the UI with confusing options. ;-) + */ + if (this.resume && !this.sResumePath) { + /* + * I used to bypass the prompt if this.resume == ComputerPDP11.RESUME_AUTO, setting fSave to true automatically, + * but that gives the user no means of resetting a resumable machine that contains errors in its resume state. + */ + var fSave = (/* this.resume == ComputerPDP11.RESUME_AUTO || */ web.confirmUser("Click OK to save changes to this " + PDP11.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.")); + this.powerOff(fSave, true); + /* + * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn() + * and rely on all the components to reset themselves to their default state. The components with + * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether + * or not to unload/reload all their original auto-mounted disk images. + * + * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because + * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource() + * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory. + * + * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer. + */ + if (!fSave && this.sStatePath) { + web.reloadPage(); + return; + } + if (!fSave) this.fReload = true; + this.powerOn(ComputerPDP11.RESUME_NONE); + this.fReload = false; + } else { + this.reset(); + if (this.cpu) this.cpu.autoStart(); + } +}; + +/** + * getMachineComponent(sType, componentPrev) + * + * @this {ComputerPDP11} + * @param {string} sType + * @param {Component|null} [componentPrev] of previously returned component, if any + * @return {Component|null} + */ +ComputerPDP11.prototype.getMachineComponent = function(sType, componentPrev) +{ + var componentLast = componentPrev; + var aComponents = Component.getComponents(this.id); + for (var iComponent = 0; iComponent < aComponents.length; iComponent++) { + var component = aComponents[iComponent]; + if (componentPrev) { + if (componentPrev == component) componentPrev = null; + continue; + } + if (component.type == sType) return component; + } + if (!componentLast) Component.log("Machine component type '" + sType + "' not found", "warning"); + return null; +}; + +/** + * updateFocus(fScroll) + * + * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button), + * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS, + * where the display is more constrained, so we no longer do it by default (fScroll must be true). + * + * @this {ComputerPDP11} + * @param {boolean} [fScroll] + */ +ComputerPDP11.prototype.updateFocus = function(fScroll) +{ +}; + +/** + * updateStatus(fForce) + * + * If any DOM controls were bound to the CPU, then we need to call its updateStatus() handler; if there are no + * such bindings, then cpu.updateStatus() does nothing. + * + * Similarly, if there's a Panel, then we need to call its updateStatus() handler, in case it created its own canvas + * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateStatus() also does nothing. + * + * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or* + * neither. In theory, there could be BOTH, but that would be unusual. + * + * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to + * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately + * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate, + * but Panel is an optional component; generally, only machines that include Debugger also include Panel. + * + * @this {ComputerPDP11} + * @param {boolean} [fForce] (true will display registers even if the CPU is running and "live" registers are not enabled) + */ +ComputerPDP11.prototype.updateStatus = function(fForce) +{ + /* + * fForce is generally set to true whenever the CPU is transitioning to/from a running state, in which case + * cpu.updateStatus() will definitely want to hide/show register contents; however, at other times, when the + * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance. + * + * So fForce serves as a hint to help cpu.updateStatus() make a more informed decision. panel.updateStatus() + * currently doesn't care, on the theory that canvas updates should be significantly faster than DOM updates, + * but we still pass fForce on. + */ + if (this.cpu) this.cpu.updateStatus(fForce); + if (this.panel) this.panel.updateStatus(fForce); +}; + +/** + * ComputerPDP11.init() + * + * For every machine represented by an HTML element of class "pcjs-machine", this function + * locates the HTML element of class "computer", extracting the JSON-encoded parameters for the + * Computer constructor from the element's "data-value" attribute, invoking the constructor to + * create a Computer component, and then binding any associated HTML controls to the new component. + */ +ComputerPDP11.init = function() +{ + /* + * In non-COMPILED builds, embedMachine() may have set XMLVERSION. + */ + if (!COMPILED && PDP11.XMLVERSION) PDP11.APPVERSION = PDP11.XMLVERSION; + + var aeMachines = Component.getElementsByClass(document, PDP11.APPCLASS + "-machine"); + + for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) { + + var eMachine = aeMachines[iMachine]; + var parmsMachine = Component.getComponentParms(eMachine); + + var aeComputers = Component.getElementsByClass(eMachine, PDP11.APPCLASS, "computer"); + + for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) { + + var eComputer = aeComputers[iComputer]; + var parmsComputer = Component.getComponentParms(eComputer); + + /* + * We set fSuspended in the Computer constructor because we want to "power up" the + * computer ourselves, after any/all bindings are in place. + */ + var computer = new ComputerPDP11(parmsComputer, parmsMachine, true); + + if (DEBUG && computer.messageEnabled()) { + computer.printMessage("onInit(" + computer.flags.fPowered + ")"); + } + + /* + * Bind any "power", "reset" and "save" buttons. An "erase" button was also considered, + * but "reset" now provides a way to force the machine to start from scratch again, so "erase" + * may be redundant now. + */ + Component.bindComponentControls(computer, eComputer, PDP11.APPCLASS); + + /* + * Power on the computer, giving every component the opportunity to reset or restore itself. + */ + if (computer.fAutoPower) computer.wait(computer.powerOn); + } + } +}; + +/** + * ComputerPDP11.show() + * + * When exit() is using an "onbeforeunload" handler, this "onpageshow" handler allows us to repower everything, + * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the + * computer is already marked as "ready", meaning the browser didn't change anything. This "repower" process + * should be very quick, essentially just marking all components as powered again (so that, for example, the Video + * component will start drawing again) and firing the CPU up again. + */ +ComputerPDP11.show = function() +{ + var aeComputers = Component.getElementsByClass(document, PDP11.APPCLASS, "computer"); + for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) { + var eComputer = aeComputers[iComputer]; + var parmsComputer = Component.getComponentParms(eComputer); + var computer = /** @type {ComputerPDP11} */ (Component.getComponentByType("Computer", parmsComputer['id'])); + if (computer) { + + if (DEBUG && computer.messageEnabled()) { + computer.printMessage("onShow(" + computer.fInitialized + "," + computer.flags.fPowered + ")"); + } + + /* + * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs + * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet. + * So, practically speaking, the first show() callback isn't all that useful. + */ + if (computer.fInitialized && !computer.flags.fPowered) { + /** + * Repower the computer, notifying every component to continue running as-is. + */ + computer.powerOn(ComputerPDP11.RESUME_REPOWER); + } + } + } +}; + +/** + * ComputerPDP11.exit() + * + * The Computer is currently the only component that uses an "exit" handler, which web.onExit() defines as + * either an "unload" or "onbeforeunload" handler. This gives us the opportunity to save the machine state, + * using our powerOff() function, before the page goes away. + * + * It's worth noting that "onbeforeunload" offers one nice feature when used instead of "onload": the entire + * page (and therefore this entire application) is retained in its current state by the browser (well, some + * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing + * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state. + * + * In fact, that's how some browsers operate whether you have an "onbeforeunload" handler or not; in other words, + * an "onbeforeunload" handler doesn't change the page retention behavior of the browser. By contrast, the mere + * presence of an "onunload" handler generally causes a browser to throw the page away once the handler returns. + * + * However, in order to safely use "onbeforeunload", we must add yet another handler ("onpageshow") to repower + * everything, without either resetting or restoring. Hence, the ComputerPDP11.show() function, which calls powerOn() + * with a special resume value (RESUME_REPOWER) if the computer is already marked as "ready", meaning the browser + * didn't change anything. This "repower" process should be very quick, essentially just marking all components as + * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again. + * + * Reportedly, some browsers (eg, Opera) don't support "onbeforeunload", in which case Component will have to use + * "unload" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and + * localStorage means the simulation should be restored and become operational almost immediately. + */ +ComputerPDP11.exit = function() +{ + var aeComputers = Component.getElementsByClass(document, PDP11.APPCLASS, "computer"); + for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) { + var eComputer = aeComputers[iComputer]; + var parmsComputer = Component.getComponentParms(eComputer); + var computer = /** @type {ComputerPDP11} */ (Component.getComponentByType("Computer", parmsComputer['id'])); + if (computer) { + + if (DEBUG && computer.messageEnabled()) { + computer.printMessage("onExit(" + computer.flags.fPowered + ")"); + } + + if (computer.flags.fPowered) { + /** + * Power off the computer, giving every component an opportunity to save its state, + * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume + * path exists, we'll always load our state from there, and not from whatever we save here). + */ + computer.powerOff(!!(computer.resume && !computer.sResumePath), true); + } + } + } +}; + +/* + * Initialize every Computer on the page. + */ +web.onInit(ComputerPDP11.init); +web.onShow(ComputerPDP11.show); +web.onExit(ComputerPDP11.exit); + +if (NODE) module.exports = ComputerPDP11; diff --git a/modules/pdp11/lib/cpu.js b/modules/pdp11/lib/cpu.js new file mode 100644 index 000000000..7b93e19c7 --- /dev/null +++ b/modules/pdp11/lib/cpu.js @@ -0,0 +1,1228 @@ +/** + * @fileoverview Controls the PDP11 CPU component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var usr = require("../../shared/lib/usrlib"); + var Component = require("../../shared/lib/component"); + var MessagesPDP11 = require("./messages"); +} + +/** + * CPUPDP11(parmsCPU, nCyclesDefault) + * + * The CPUPDP11 class supports the following (parmsCPU) properties: + * + * cycles: the machine's base cycles per second; the CPUStatePDP11 constructor + * will provide us with a default (based on the CPU model) to use as a fallback. + * + * multiplier: base cycle multiplier; default is 1. + * + * autoStart: true to automatically start, false to not, or null if "it depends"; + * null is the default, which means do not autostart UNLESS there is no Debugger + * and no "Run" button (ie, no way to manually start the machine). + * + * csStart: the number of cycles that runCPU() must wait before generating + * checksum records; -1 if disabled. checksum records are a diagnostic aid + * used to help compare one CPU run to another. + * + * csInterval: the number of cycles that runCPU() must execute before generating + * a checksum record; -1 if disabled. + * + * csStop: the number of cycles to stop generating checksum records. + * + * This component is primarily responsible for interfacing the CPU with the outside + * world (eg, Panel and Debugger components), and managing overall CPU operation. + * + * It is extended by the CPUStatePDP11 component, where the simulation control logic resides. + * + * @constructor + * @extends Component + * @param {Object} parmsCPU + * @param {number} nCyclesDefault + */ +function CPUPDP11(parmsCPU, nCyclesDefault) +{ + Component.call(this, "CPU", parmsCPU, CPUPDP11, MessagesPDP11.CPU); + + var nCycles = parmsCPU['cycles'] || nCyclesDefault; + + var nMultiplier = parmsCPU['multiplier'] || 1; + + this.nCyclesPerSecond = nCycles; + + /* + * nCyclesMultiplier replaces the old "speed" variable (0, 1, 2) and eliminates the need for + * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier + * until we've exceeded the host's speed limit and then starts the multiplier over at 1. + */ + this.nCyclesMultiplier = nMultiplier; + this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100; + /* + * TODO: Take care of this with an initial setSpeed() call instead? + */ + this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier; + + /* + * We add a number of flags to the set initialized by Component + */ + this.flags.fRunning = false; + this.flags.fStarting = false; + this.flags.fAutoStart = parmsCPU['autoStart']; + + /* + * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both) + */ + this.flags.fDisplayLiveRegs = false; + + /* + * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum + * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval + * ("csInterval") set to a positive value. + * + * As above, any of these parameters can also be set with the Debugger's execution options + * command ("x"); for example, "x cs int 5000" will set nCyclesChecksumInterval to 5000 + * and call resetChecksum(). + */ + this.flags.fChecksum = false; + this.nChecksum = this.nCyclesChecksumNext = 0; + this.nCyclesChecksumStart = parmsCPU["csStart"]; + this.nCyclesChecksumInterval = parmsCPU["csInterval"]; + this.nCyclesChecksumStop = parmsCPU["csStop"]; + + /* + * Array of countdown timers managed by addTimer() and setTimer(). + */ + this.aTimers = []; + + this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); }; + + this.setReady(); +} + +Component.subclass(CPUPDP11); + +/* + * Constants that control the frequency at which various updates should occur. + * + * These values do NOT control the simulation directly. Instead, they are used by + * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting + * point and computes the following variables: + * + * this.nCyclesPerYield: (this.nCyclesPerSecond / CPUPDP11.YIELDS_PER_SECOND) + * + * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(), + * and then they're used to initialize another set of variables for each runCPU() iteration: + * + * this.nCyclesNextYield: this.nCyclesPerYield + */ +CPUPDP11.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second +CPUPDP11.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates + +CPUPDP11.BUTTONS = ["power", "reset"]; + +/** + * initBus(cmp, bus, cpu, dbg) + * + * @this {CPUPDP11} + * @param {ComputerPDP11} cmp + * @param {BusPDP11} bus + * @param {CPUPDP11} cpu + * @param {DebuggerPDP11} dbg + */ +CPUPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) +{ + this.cmp = cmp; + this.bus = bus; + this.dbg = dbg; + + for (var i = 0; i < CPUPDP11.BUTTONS.length; i++) { + var control = this.bindings[CPUPDP11.BUTTONS[i]]; + if (control) this.cmp.setBinding(null, CPUPDP11.BUTTONS[i], control); + } + + /* + * Attach the ChipSet component to the CPU so that it can be notified whenever the CPU stops and starts. + */ + this.chipset = null; // /** @type {ChipSetPDP11} */ (cmp.getMachineComponent("ChipSet")); + + /* + * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override. + */ + var sAutoStart = cmp.getMachineParm('autoStart'); + if (sAutoStart != null) { + this.flags.fAutoStart = (sAutoStart == "true"? true : (sAutoStart == "false"? false : !!sAutoStart)); + } + + this.setReady(); +}; + +/** + * reset() + * + * @this {CPUPDP11} + */ +CPUPDP11.prototype.reset = function() +{ +}; + +/** + * save() + * + * This is a placeholder for save support (overridden by the CPUStatePDP11 component). + * + * @this {CPUPDP11} + * @return {Object|null} + */ +CPUPDP11.prototype.save = function() +{ + return null; +}; + +/** + * restore(data) + * + * This is a placeholder for restore support (overridden by the CPUStatePDP11 component). + * + * @this {CPUPDP11} + * @param {Object} data + * @return {boolean} true if restore successful, false if not + */ +CPUPDP11.prototype.restore = function(data) +{ + return false; +}; + +/** + * powerUp(data, fRepower) + * + * @this {CPUPDP11} + * @param {Object|null} data + * @param {boolean} [fRepower] + * @return {boolean} true if successful, false if failure + */ +CPUPDP11.prototype.powerUp = function(data, fRepower) +{ + if (!fRepower) { + if (!data || !this.restore) { + this.reset(); + } else { + this.resetCycles(); + if (!this.restore(data)) return false; + this.resetChecksum(); + } + /* + * Give the Debugger a chance to do/print something once we've powered up + */ + if (DEBUGGER && this.dbg) { + this.dbg.init(); + } else { + /* + * The Computer (this.cmp) knows if there's a Control Panel (this.cmp.panel), and the Control Panel + * knows if there's a "print" control (this.cmp.panel.controlPrint), and if there IS a "print" control + * but no debugger, the machine is probably misconfigured (most likely, the page simply neglected to + * load the Debugger component). + * + * However, we don't actually need to check all that; it's always safe use println(), regardless whether + * a Control Panel with a "print" control is present or not. + */ + this.println("No debugger detected"); + } + } + /* + * The Computer component (which is responsible for all powerDown and powerUp notifications) + * is now responsible for managing a component's fPowered flag, not us. + * + * this.flags.fPowered = true; + */ + this.updateCPU(); + return true; +}; + +/** + * powerDown(fSave, fShutdown) + * + * @this {CPUPDP11} + * @param {boolean} [fSave] + * @param {boolean} [fShutdown] + * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure + */ +CPUPDP11.prototype.powerDown = function(fSave, fShutdown) +{ + /* + * The Computer component (which is responsible for all powerDown and powerUp notifications) + * is now responsible for managing a component's fPowered flag, not us. + * + * this.flags.fPowered = false; + */ + return fSave? this.save() : true; +}; + +/** + * autoStart() + * + * @this {CPUPDP11} + * @return {boolean} true if started, false if not + */ +CPUPDP11.prototype.autoStart = function() +{ + /* + * Start running automatically on power-up, assuming there's no Debugger and no "Run" button + */ + if (this.flags.fAutoStart || (!DEBUGGER || !this.dbg) && this.bindings["run"] === undefined) { + /* + * Now we ALSO set fUpdateFocus when calling runCPU(), on the assumption that in the "auto-starting" context, + * a machine without focus is like a day without sunshine. + */ + this.runCPU(true); + return true; + } + return false; +}; + +/** + * isPowered() + * + * @this {CPUPDP11} + * @return {boolean} + */ +CPUPDP11.prototype.isPowered = function() +{ + if (!this.flags.fPowered) { + this.println(this.toString() + " not powered"); + return false; + } + return true; +}; + +/** + * isRunning() + * + * @this {CPUPDP11} + * @return {boolean} + */ +CPUPDP11.prototype.isRunning = function() +{ + return this.flags.fRunning; +}; + +/** + * getChecksum() + * + * This will be implemented by the CPUStatePDP11 component. + * + * @this {CPUPDP11} + * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code) + */ +CPUPDP11.prototype.getChecksum = function() +{ + return 0; +}; + +/** + * resetChecksum() + * + * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the + * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever + * the CPU is reset or restored. + * + * @this {CPUPDP11} + * @return {boolean} true if checksum generation enabled, false if not + */ +CPUPDP11.prototype.resetChecksum = function() +{ + if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0; + if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1; + if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1; + this.flags.fChecksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0); + if (this.flags.fChecksum) { + this.nChecksum = 0; + this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles; + /* + * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval - + * (this.nTotalCycles % this.nCyclesChecksumInterval); + */ + return true; + } + return false; +}; + +/** + * updateChecksum(nCycles) + * + * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum + * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with + * the exact number cycles that were actually executed. This should give us instruction-granular checksums + * at precise intervals that are 100% repeatable. + * + * @this {CPUPDP11} + * @param {number} nCycles + */ +CPUPDP11.prototype.updateChecksum = function(nCycles) +{ + if (this.flags.fChecksum) { + /* + * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum + */ + var fDisplay = false; + this.nChecksum = (this.nChecksum + this.getChecksum())|0; + this.nCyclesChecksumNext -= nCycles; + if (this.nCyclesChecksumNext <= 0) { + this.nCyclesChecksumNext += this.nCyclesChecksumInterval; + fDisplay = true; + } + if (this.nCyclesChecksumStop >= 0) { + if (this.nCyclesChecksumStop <= this.getCycles()) { + this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1; + this.resetChecksum(); + this.stopCPU(); + fDisplay = true; + } + } + if (fDisplay) this.displayChecksum(); + } +}; + +/** + * displayChecksum() + * + * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all + * checksums generated at the specified cycle intervals, as specified by the "csStart" and "csInterval" parmsCPU + * properties). + * + * @this {CPUPDP11} + */ +CPUPDP11.prototype.displayChecksum = function() +{ + this.println(this.getCycles() + " cycles: " + "checksum=" + str.toHex(this.nChecksum)); +}; + +/** + * displayValue(sLabel, nValue, cch) + * + * This is principally for displaying register values, but in reality, it can be used to display any + * numeric (hex) value bound to the given label. + * + * @this {CPUPDP11} + * @param {string} sLabel + * @param {number} nValue + * @param {number} cch + */ +CPUPDP11.prototype.displayValue = function(sLabel, nValue, cch) +{ + if (this.bindings[sLabel]) { + if (nValue === undefined) { + this.setError("Value for " + sLabel + " is invalid"); + this.stopCPU(); + } + var sVal; + if (!this.flags.fRunning || this.flags.fDisplayLiveRegs) { + sVal = str.toHex(nValue, cch); + } else { + sVal = "--------".substr(0, cch); + } + /* + * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if + * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary + * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being + * too obsessive. + */ + if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal; + } +}; + +/** + * setBinding(sHTMLType, sBinding, control, sValue) + * + * @this {CPUPDP11} + * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") + * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) + * @param {string} [sValue] optional data value + * @return {boolean} true if binding was successful, false if unrecognized binding request + */ +CPUPDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) +{ + var cpu = this; + var fBound = false; + + switch (sBinding) { + case "power": + case "reset": + /* + * The "power" and "reset" buttons are functions of the entire computer, not just the CPU, + * but it's not always convenient to stick a power button in the Computer component definition, + * so we record those bindings here and pass them on to the Computer component in initBus(). + */ + this.bindings[sBinding] = control; + fBound = true; + break; + + case "run": + this.bindings[sBinding] = control; + control.onclick = function onClickRun() { + if (!cpu.cmp || !cpu.cmp.checkPower()) return; + /* + * We no longer pass true to these runCPU()/stopCPU() calls, on the theory that if the "run" + * control is visible, then the computer is probably sufficiently visible as well; the problem + * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways. + */ + if (!cpu.flags.fRunning) + cpu.runCPU(); + else + cpu.stopCPU(); + }; + fBound = true; + break; + + case "speed": + this.bindings[sBinding] = control; + fBound = true; + break; + + case "setSpeed": + this.bindings[sBinding] = control; + control.onclick = function onClickSetSpeed() { + cpu.setSpeed(cpu.nCyclesMultiplier << 1, true); + }; + control.textContent = this.getSpeedTarget(); + fBound = true; + break; + + default: + break; + } + return fBound; +}; + +/** + * setBurstCycles(nCycles) + * + * This function is used by the ChipSet component whenever a very low timer count is set, + * in anticipation of the timer requiring an update sooner than the normal nCyclesPerYield + * period in runCPU() would normally provide. + * + * NOTE: In this context, "timer" refers to a timer chip (eg, an Intel 8253) being emulated by + * by the ChipSet component, not the timers managed by the CPU (eg, addTimer(), setTimer(), etc). + * + * @this {CPUPDP11} + * @param {number} nCycles is the target number of cycles to drop the current burst to + * @return {boolean} + */ +CPUPDP11.prototype.setBurstCycles = function(nCycles) +{ + if (this.flags.fRunning) { + var nDelta = this.nStepCycles - nCycles; + /* + * NOTE: If nDelta is negative, we will actually be increasing nStepCycles and nBurstCycles. + * Which is OK, but if we're also taking snapshots of the cycle counts, to make sure that instruction + * costs are being properly assessed, then we need to update nSnapCycles as well. + * + * TODO: If the delta is negative, we could simply ignore the request, but we must first carefully + * consider the impact on the ChipSet timers, if any. + */ + // if (DEBUG) this.nSnapCycles -= nDelta; + this.nStepCycles -= nDelta; + this.nBurstCycles -= nDelta; + return true; + } + return false; +}; + +/** + * addCycles(nCycles, fEndStep) + * + * @this {CPUPDP11} + * @param {number} nCycles + * @param {boolean} [fEndStep] + */ +CPUPDP11.prototype.addCycles = function(nCycles, fEndStep) +{ + this.nTotalCycles += nCycles; + if (fEndStep) { + this.nBurstCycles = this.nStepCycles = 0; + } +}; + +/** + * calcCycles(fRecalc) + * + * Calculate the number of cycles to process for each "burst" of CPU activity. The size of a burst + * is driven by YIELDS_PER_SECOND (eg, 30). + * + * At the end of each burst, we subtract burst cycles from the yield cycle "threshold" counter. + * Whenever the "next yield" cycle counter goes to (or below) zero, we compare elapsed time to the time + * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining, + * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU(). + * + * @this {CPUPDP11} + * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent + * speed calculation (see calcSpeed). + */ +CPUPDP11.prototype.calcCycles = function(fRecalc) +{ + /* + * Calculate "per" yield values. + */ + var vMultiplier = 1; + if (fRecalc) { + if (this.nCyclesMultiplier > 1 && this.mhz) { + vMultiplier = (this.mhz / this.mhzDefault); + } + } + + this.msPerYield = Math.round(1000 / CPUPDP11.YIELDS_PER_SECOND); + this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPUPDP11.YIELDS_PER_SECOND * vMultiplier); + + /* + * And initialize "next" yield values to the "per" values. + */ + if (!fRecalc) { + this.nCyclesNextYield = this.nCyclesPerYield; + } + this.nCyclesRecalc = 0; +}; + +/** + * getCycles(fScaled) + * + * getCycles() returns the number of cycles executed so far. Note that we can be called after + * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(), + * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles), + * less the number of cycles it has yet to run (nStepCycles). + * + * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also + * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and + * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on + * getCycles() returning steadily increasing values should also be prepared for a reset at any time. + * + * @this {CPUPDP11} + * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1 + * @return {number} + */ +CPUPDP11.prototype.getCycles = function(fScaled) +{ + var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles; + if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) { + /* + * We could scale the current cycle count by the current effective speed (this.mhz); eg: + * + * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault)); + * + * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller + * fluctuations after each burst of instructions that runCPU() executes. + * + * Alternatively, we can scale the cycle count by the multiplier, which is good in that the + * multiplier doesn't vary once the user changes it, but a potential downside is that the + * multiplier might be set too high, resulting in a target speed that's higher than the effective + * speed is able to reach. + * + * Also, if multipliers were always limited to a power-of-two, then this could be calculated + * with a simple shift. However, only the "setSpeed" UI binding limits it that way; the Debugger + * interface allows any value, as does the CPU "multiplier" parmsCPU property (from the machine's + * XML file). + */ + nCycles = Math.round(nCycles / this.nCyclesMultiplier); + } + return nCycles; +}; + +/** + * getCyclesPerSecond() + * + * This returns the CPU's "base" speed (ie, the original cycles per second defined for the machine) + * + * @this {CPUPDP11} + * @return {number} + */ +CPUPDP11.prototype.getCyclesPerSecond = function() +{ + return this.nCyclesPerSecond; +}; + +/** + * resetCycles() + * + * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp(). + * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(), + * which in turn assumes that all the cycle counts have been initialized to sensible values. + * + * @this {CPUPDP11} + */ +CPUPDP11.prototype.resetCycles = function() +{ + this.mhz = 0; + this.nYieldsSinceStatusUpdate = 0; + this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0; + this.resetChecksum(); + this.setSpeed(1); +}; + +/** + * getSpeed() + * + * @this {CPUPDP11} + * @return {number} the current speed multiplier + */ +CPUPDP11.prototype.getSpeed = function() +{ + return this.nCyclesMultiplier; +}; + +/** + * getSpeedCurrent() + * + * @this {CPUPDP11} + * @return {string} the current speed, in mhz, as a string formatted to two decimal places + */ +CPUPDP11.prototype.getSpeedCurrent = function() +{ + /* + * TODO: Has toFixed() been "fixed" in all browsers (eg, IE) to return a rounded value now? + */ + return ((this.flags.fRunning && this.mhz)? (this.mhz.toFixed(2) + "Mhz") : "Stopped"); +}; + +/** + * getSpeedTarget() + * + * @this {CPUPDP11} + * @return {string} the target speed, in mhz, as a string formatted to two decimal places + */ +CPUPDP11.prototype.getSpeedTarget = function() +{ + /* + * TODO: Has toFixed() been "fixed" in all browsers (eg, IE) to return a rounded value now? + */ + return this.mhzTarget.toFixed(2) + "Mhz"; +}; + +/** + * setSpeed(nMultiplier, fUpdateFocus) + * + * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point. + * + * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset, + * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls + * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting). + * + * @this {CPUPDP11} + * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high) + * @param {boolean} [fUpdateFocus] is true to update Computer focus + * @return {boolean} true if successful, false if not + */ +CPUPDP11.prototype.setSpeed = function(nMultiplier, fUpdateFocus) +{ + var fSuccess = false; + if (nMultiplier !== undefined) { + /* + * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1). + */ + if (this.mhz / this.mhzTarget < 0.8) { + nMultiplier = 1; + } else { + fSuccess = true; + } + this.nCyclesMultiplier = nMultiplier; + var mhz = this.mhzDefault * this.nCyclesMultiplier; + if (this.mhzTarget != mhz) { + this.mhzTarget = mhz; + var sSpeed = this.getSpeedTarget(); + var controlSpeed = this.bindings["setSpeed"]; + if (controlSpeed) controlSpeed.textContent = sSpeed; + this.println("target speed: " + sSpeed); + } + if (fUpdateFocus && this.cmp) this.cmp.updateFocus(); + } + this.addCycles(this.nRunCycles); + this.nRunCycles = 0; + this.msStartRun = usr.getTime(); + this.msEndThisRun = 0; + this.calcCycles(); + return fSuccess; +}; + +/** + * calcSpeed(nCycles, msElapsed) + * + * @this {CPUPDP11} + * @param {number} nCycles + * @param {number} msElapsed + */ +CPUPDP11.prototype.calcSpeed = function(nCycles, msElapsed) +{ + if (msElapsed) { + this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100; + if (msElapsed >= 86400000) { + this.nTotalCycles = 0; + this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow + } + } +}; + +/** + * calcStartTime() + * + * @this {CPUPDP11} + */ +CPUPDP11.prototype.calcStartTime = function() +{ + if (this.nCyclesRecalc >= this.nCyclesPerSecond) { + this.calcCycles(true); + } + this.nCyclesThisRun = 0; + this.msStartThisRun = usr.getTime(); + + /* + * Try to detect situations where the browser may have throttled us, such as when the user switches + * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks + * to roughly one per second. + * + * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled, + * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably + * erratic if we don't compensate for it here. + * + * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the + * previous run and includes any requested sleep time) is comparable to the current msStartThisRun; + * if the delta is significant, we compensate by bumping msStartRun forward by that delta. + * + * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called + * whenever the CPU starts running again -- zeroes msEndThisRun. + * + * This also won't do anything about other internal delays; for example, Debugger message() calls. + * By the time the message() function has called yieldCPU(), the cost of the message has already been + * incurred, so it will be end up being charged against the instruction(s) that triggered it. + * + * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun + * "snapshot" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability + * to hit its target speed, since you would expect any instruction that displays a message to be an + * EXTREMELY slow instruction. + */ + if (this.msEndThisRun) { + var msDelta = this.msStartThisRun - this.msEndThisRun; + if (msDelta > this.msPerYield) { + if (MAXDEBUG) this.println("large time delay: " + msDelta + "ms"); + this.msStartRun += msDelta; + /* + * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just + * in case, I make absolutely sure it cannot happen, since doing so could result in negative + * speed calculations. + */ + this.assert(this.msStartRun <= this.msStartThisRun); + if (this.msStartRun > this.msStartThisRun) { + this.msStartRun = this.msStartThisRun; + } + } + } +}; + +/** + * calcRemainingTime() + * + * @this {CPUPDP11} + * @return {number} + */ +CPUPDP11.prototype.calcRemainingTime = function() +{ + this.msEndThisRun = usr.getTime(); + + var msYield = this.msPerYield; + if (this.nCyclesThisRun) { + /* + * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU + * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then + * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed, + * and so applying that percentage to msPerYield should give us a better estimate of work vs. time. + */ + msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield); + } + + var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun; + var msRemainsThisRun = msYield - msElapsedThisRun; + + /* + * We could pass only "this run" results to calcSpeed(): + * + * nCycles = this.nCyclesThisRun; + * msElapsed = msElapsedThisRun; + * + * but it seems preferable to use longer time periods and hopefully get a more accurate speed. + * + * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead: + * + * nCycles = this.nCyclesThisRun; + * msElapsed = this.msPerYield; + * + * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations. + */ + var nCycles = this.nRunCycles; + var msElapsed = this.msEndThisRun - this.msStartRun; + + if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) { + this.println("warning: updates @" + msElapsedThisRun + "ms (prefer " + Math.round(msYield) + "ms)"); + } + + this.calcSpeed(nCycles, msElapsed); + + if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) { + /* + * Try "throwing out" the effects of large anomalies, by moving the overall run start time up; + * ordinarily, this should only happen when the someone is using an external Debugger or some other + * tool or feature that is interfering with our overall execution. + */ + if (msRemainsThisRun < -1000) { + this.msStartRun -= msRemainsThisRun; + } + /* + * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate + * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the + * simulation is at least usable. + */ + msRemainsThisRun = 0; + } + + /* + * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(), + * it'll be ready to decide if calcCycles() should be called again. + */ + this.nCyclesRecalc += this.nCyclesThisRun; + + if (DEBUG && this.messageEnabled(MessagesPDP11.LOG) && msRemainsThisRun) { + this.log("calcRemainingTime: " + msRemainsThisRun + "ms to sleep after " + this.msEndThisRun + "ms"); + } + + this.msEndThisRun += msRemainsThisRun; + return msRemainsThisRun; +}; + +/** + * addTimer(callBack) + * + * Components that want to have timers that periodically fire after some number of milliseconds call + * addTimer() to create the timer, and then setTimer() every time they want to arm it. There is currently + * no removeTimer() because these are generally used for the entire lifetime of a component. + * + * Internally, each timer entry is a preallocated Array with two entries: a cycle countdown in element [0] + * and a callback function in element [1]. A timer is initially dormant; dormant timers have a countdown + * value of -1 (although any negative number will suffice) and active timers have a non-negative value. + * + * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below. + * + * @this {CPUPDP11} + * @param {function()} callBack + * @return {number} timer index + */ +CPUPDP11.prototype.addTimer = function(callBack) +{ + var iTimer = this.aTimers.length; + this.aTimers.push([-1, callBack]); + return iTimer; +}; + +/** + * setTimer(iTimer, ms) + * + * Using the timer index from a previous addTimer() call, this sets that timer to fire after the + * specified number of milliseconds. + * + * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when + * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after + * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate + * interrupts at 9600 baud). + * + * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components + * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness, + * that's currently not the case. TODO: Fix. + * + * @this {CPUPDP11} + * @param {number} iTimer + * @param {number} ms (converted into a cycle countdown internally) + * @return {number} (number of cycles used to arm timer, or -1 if error) + */ +CPUPDP11.prototype.setTimer = function(iTimer, ms) +{ + var nCycles = -1; + if (iTimer >= 0 && iTimer < this.aTimers.length) { + nCycles = this.getMSCycles(ms); + this.aTimers[iTimer][0] = nCycles; + } + return nCycles; +}; + +/** + * getMSCycles(ms) + * + * @this {CPUPDP11} + * @param {number} ms + * @return {number} number of corresponding cycles + */ +CPUPDP11.prototype.getMSCycles = function(ms) +{ + return (this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms; +}; + +/** + * getBurstCycles(nCycles) + * + * Used by runCPU() to get min(nCycles,[timer cycle counts]) + * + * @this {CPUPDP11} + * @param {number} nCycles (number of cycles about to execute) + * @return {number} (either nCycles or less if a timer needs to fire) + */ +CPUPDP11.prototype.getBurstCycles = function(nCycles) +{ + for (var i = this.aTimers.length - 1; i >= 0; i--) { + var timer = this.aTimers[i]; + if (timer[0] < 0) continue; + if (nCycles > timer[0]) { + nCycles = timer[0]; + } + } + return nCycles; +}; + +/** + * updateTimers(nCycles) + * + * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed; + * this is the function that actually "fires" any timer(s) whose countdown has reached (or dropped below) + * zero, invoking their callback function. + * + * @this {CPUPDP11} + * @param {number} nCycles (number of cycles actually executed) + */ +CPUPDP11.prototype.updateTimers = function(nCycles) +{ + for (var i = this.aTimers.length - 1; i >= 0; i--) { + var timer = this.aTimers[i]; + if (timer[0] < 0) continue; + timer[0] -= nCycles; + if (timer[0] <= 0) { + timer[0] = -1; // zero is technically an "active" value, so ensure the timer is dormant now + timer[1](); // safe to invoke the callback function now + } + } +}; + +/** + * runCPU(fUpdateFocus) + * + * @this {CPUPDP11} + * @param {boolean} [fUpdateFocus] is true to update Computer focus + */ +CPUPDP11.prototype.runCPU = function(fUpdateFocus) +{ + if (!this.setBusy(true)) { + this.updateCPU(); + if (this.cmp) this.cmp.stop(usr.getTime(), this.getCycles()); + return; + } + + this.startCPU(fUpdateFocus); + + /* + * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally + * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached. + */ + this.calcStartTime(); + + try { + do { + /* + * nCyclesPerBurst is how many cycles we WANT to run on each iteration of stepCPU(), and may + * be as HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust + * nCyclesPerBurst downward if any CPU timers need to fire during the next burst. + */ + var nCyclesPerBurst = this.getBurstCycles(this.flags.fChecksum? 1 : this.nCyclesPerYield); + + /* + * Execute the burst. + */ + this.stepCPU(nCyclesPerBurst); + + /* + * nCycles is how many cycles stepCPU() actually ran (nBurstCycles less any remaining nStepCycles). + */ + var nCycles = this.nBurstCycles - this.nStepCycles; + + /* + * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero. + */ + this.updateTimers(nCycles); + + /* + * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU first started). + */ + this.nCyclesThisRun += nCycles; + this.nRunCycles += nCycles; + this.addCycles(0, true); + this.updateChecksum(nCycles); + + this.nCyclesNextYield -= nCycles; + if (this.nCyclesNextYield <= 0) { + this.nCyclesNextYield += this.nCyclesPerYield; + if (++this.nYieldsSinceStatusUpdate >= CPUPDP11.YIELDS_PER_STATUS) { + if (this.cmp) this.cmp.updateStatus(); + this.nYieldsSinceStatusUpdate = 0; + } + break; + } + } while (this.flags.fRunning); + } + catch (e) { + this.stopCPU(); + this.updateCPU(); + if (this.cmp) this.cmp.stop(usr.getTime(), this.getCycles()); + this.setBusy(false); + this.setError(e.stack || e.message); + return; + } + + setTimeout(this.onRunTimeout, this.calcRemainingTime()); +}; + +/** + * startCPU(fUpdateFocus) + * + * WARNING: Other components must use runCPU() to get the CPU running; this is a runCPU() helper function only. + * + * @param {boolean} [fUpdateFocus] + */ +CPUPDP11.prototype.startCPU = function(fUpdateFocus) +{ + if (!this.flags.fRunning) { + /* + * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the + * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number + * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc + * threshold counter. + */ + this.setSpeed(); + if (this.cmp) this.cmp.start(this.msStartRun, this.getCycles()); + this.flags.fRunning = true; + this.flags.fStarting = true; + if (this.chipset) this.chipset.start(); + var controlRun = this.bindings["run"]; + if (controlRun) controlRun.textContent = "Halt"; + if (this.cmp) { + this.cmp.updateStatus(true); + if (fUpdateFocus) this.cmp.updateFocus(true); + } + } +}; + +/** + * stepCPU(nMinCycles) + * + * This will be implemented by the CPUStatePDP11 component. + * + * @this {CPUPDP11} + * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored) + * @return {number} of cycles executed; 0 indicates that the last instruction was not executed + */ +CPUPDP11.prototype.stepCPU = function(nMinCycles) +{ + return 0; +}; + +/** + * stopCPU(fComplete) + * + * For use by any component that wants to stop the CPU. + * + * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU(); + * it simply needs to clear fRunning (well, "simply" may be oversimplifying a bit....) + * + * @this {CPUPDP11} + * @param {boolean} [fComplete] + */ +CPUPDP11.prototype.stopCPU = function(fComplete) +{ + this.isBusy(true); + this.nBurstCycles -= this.nStepCycles; + this.nStepCycles = 0; + this.addCycles(this.nRunCycles); + this.nRunCycles = 0; + if (this.flags.fRunning) { + this.flags.fRunning = false; + if (this.chipset) this.chipset.stop(); + var controlRun = this.bindings["run"]; + if (controlRun) controlRun.textContent = "Run"; + } + this.flags.fComplete = fComplete; +}; + +/** + * updateCPU(fForce) + * + * This used to be performed at the end of every stepCPU(), but runCPU() -- which relies upon + * stepCPU() -- needed to have more control over when these updates are performed. However, for + * other callers of stepCPU(), such as the Debugger, the combination of stepCPU() + updateCPU() + * provides the old behavior. + * + * @this {CPUPDP11} + * @param {boolean} [fForce] (true to force a video update; used by the Debugger) + */ +CPUPDP11.prototype.updateCPU = function(fForce) +{ + if (this.cmp) { + this.cmp.updateStatus(fForce); + } +}; + +/** + * yieldCPU() + * + * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU + * remains in a "running" state. + * + * @this {CPUPDP11} + */ +CPUPDP11.prototype.yieldCPU = function() +{ + this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU() + this.nBurstCycles -= this.nStepCycles; + this.nStepCycles = 0; // this will break us out of stepCPU() + // if (DEBUG) this.nSnapCycles = this.nBurstCycles; + /* + * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks + * odd for those messages to show CPU state changes but for the CPU's own status display to not (ditto + * for the Video display), so I've added this call to try to keep things looking synchronized. + */ + this.updateCPU(); +}; + +if (NODE) module.exports = CPUPDP11; diff --git a/modules/pdp11/lib/cpudef.js b/modules/pdp11/lib/cpudef.js new file mode 100644 index 000000000..1a2a0939f --- /dev/null +++ b/modules/pdp11/lib/cpudef.js @@ -0,0 +1,115 @@ +/** + * @fileoverview Defines PDP11 CPU constants. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +var CPUDefPDP11 = { + /* + * CPU model numbers (supported) + */ + MODEL_1145: 1145, + MODEL_1170: 1170, + + /* + * This constant is used to mark points in the code where the physical address being returned + * is invalid and should not be used. + * + * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing + * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality + * operators). + * + * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers + * (specifically, values outside the range of signed 32-bit integers), performance may suffer. + * + * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the + * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to + * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY + * certain that this file is included BEFORE the first reference to any of these properties, that + * automatic inlining will no longer occur. + */ + ADDR_INVALID: -1, + + /* + * Processor Status flag definitions (stored in regPS) + */ + PS: { + CF: 0x0001, // bit 0: Carry Flag + BIT1: 0x0002, // bit 1: reserved, always set + PF: 0x0004, // bit 2: Parity Flag + BIT3: 0x0008, // bit 3: reserved, always clear + AF: 0x0010, // bit 4: Auxiliary Carry Flag + BIT5: 0x0020, // bit 5: reserved, always clear + ZF: 0x0040, // bit 6: Zero Flag + SF: 0x0080, // bit 7: Sign Flag + ALL: 0x00D5, // all "arithmetic" flags (CF, PF, AF, ZF, SF) + MASK: 0x00FF, // + IF: 0x0200 // bit 9: Interrupt Flag (set if interrupts enabled; Intel calls this the INTE bit) + }, + /* + * Interrupt-related flags (stored in intFlags) + */ + INTFLAG: { + NONE: 0x0000, + INTR: 0x00ff, // mask for 8 bits, representing interrupt levels 0-7 + HALT: 0x0100 // halt requested; see opHLT() + }, + /* + * Opcode definitions + */ + OPCODE: { + HLT: 0x76, // Halt + ACI: 0xCE, // Add with Carry Immediate (affects PS.ALL) + CALL: 0xCD, // Call + RST0: 0xC7 + // to be continued.... + } +}; + +/* + * These are the internal PS bits (outside of PS.MASK) that getPS() and setPS() can get and set, + * but which cannot be seen with any of the documented instructions. + */ +CPUDefPDP11.PS.INTERNAL = (CPUDefPDP11.PS.IF); + +/* + * PS "arithmetic" flags are NOT stored in regPS; they are maintained across separate result registers, + * hence the RESULT designation. + */ +CPUDefPDP11.PS.RESULT = (CPUDefPDP11.PS.CF | CPUDefPDP11.PS.PF | CPUDefPDP11.PS.AF | CPUDefPDP11.PS.ZF | CPUDefPDP11.PS.SF); + +/* + * These are the "always set" PS bits for the PDP11. + */ +CPUDefPDP11.PS.SET = (CPUDefPDP11.PS.BIT1); + +if (NODE) module.exports = CPUDefPDP11; diff --git a/modules/pdp11/lib/cpuops.js b/modules/pdp11/lib/cpuops.js new file mode 100644 index 000000000..886e74a29 --- /dev/null +++ b/modules/pdp11/lib/cpuops.js @@ -0,0 +1,124 @@ +/** + * @fileoverview Implements PDP11 opcode handlers. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var CPUDefPDP11 = require("./CPUDef"); + var MessagesPDP11 = require("./messages"); +} + +/** + * op=0x00 (NOP) + * + * @this {CPUStatePDP11} + */ +CPUDefPDP11.opNOP = function() +{ + this.nStepCycles -= 4; +}; + +/* + * This 256-entry array of opcode functions is at the heart of the CPU engine: stepCPU(n). + * + * It might be worth trying a switch() statement instead, to see how the performance compares, + * but I suspect that would vary quite a bit across JavaScript engines; for now, I'm putting my + * money on array lookup. + */ +CPUDefPDP11.aOpsPDP1170 = [ + /* 0x00-0x03 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x04-0x07 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x08-0x0B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x0C-0x0F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x10-0x13 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x14-0x17 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x18-0x1B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x1C-0x1F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x20-0x23 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x24-0x27 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x28-0x2B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x2C-0x2F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x30-0x33 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x34-0x37 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x38-0x3B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x3C-0x3F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x40-0x43 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x44-0x47 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x48-0x4B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x4C-0x4F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x50-0x53 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x54-0x57 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x58-0x5B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x5C-0x5F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x60-0x63 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x64-0x67 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x68-0x6B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x6C-0x6F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x70-0x73 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x74-0x77 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x78-0x7B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x7C-0x7F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x80-0x83 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x84-0x87 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x88-0x8B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x8C-0x8F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x90-0x93 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x94-0x97 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x98-0x9B */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0x9C-0x9F */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xA0-0xA3 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xA4-0xA7 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xA8-0xAB */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xAC-0xAF */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xB0-0xB3 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xB4-0xB7 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xB8-0xBB */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xBC-0xBF */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xC0-0xC3 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xC4-0xC7 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xC8-0xCB */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xCC-0xCF */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xD0-0xD3 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xD4-0xD7 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xD8-0xDB */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xDC-0xDF */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xE0-0xE3 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xE4-0xE7 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xE8-0xEB */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xEC-0xEF */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xF0-0xF3 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xF4-0xF7 */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xF8-0xFB */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, + /* 0xFC-0xFF */ CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP, CPUDefPDP11.opNOP +]; diff --git a/modules/pdp11/lib/cpustate.js b/modules/pdp11/lib/cpustate.js new file mode 100644 index 000000000..745e7bb8d --- /dev/null +++ b/modules/pdp11/lib/cpustate.js @@ -0,0 +1,1053 @@ +/** + * @fileoverview Implements the PDP11 CPU component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var web = require("../../shared/lib/weblib"); + var Component = require("../../shared/lib/component"); + var State = require("../../shared/lib/state"); + var PDP11 = require("./defines"); + var CPUDefPDP11 = require("./cpudef"); + var CPUPDP11 = require("./cpu"); + var MessagesPDP11 = require("./messages"); + var MemoryPDP11 = require("./memory"); +} + +/** + * CPUStatePDP11(parmsCPU) + * + * The CPUStatePDP11 class uses the following (parmsCPU) properties: + * + * model: a number (eg, 1170) that should match one of the CPUDefPDP11.MODEL_* values + * + * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class + * constructor, along with a default speed (cycles per second) based on the specified (or default) + * CPU model number. + * + * @constructor + * @extends CPUPDP11 + * @param {Object} parmsCPU + */ +function CPUStatePDP11(parmsCPU) +{ + this.model = +parmsCPU['model'] || CPUDefPDP11.MODEL_1170; + + var nCyclesDefault = 0; + switch(this.model) { + case CPUDefPDP11.MODEL_1170: + default: + nCyclesDefault = 1000000; + break; + } + + 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; + + /* + * Array of halt handlers, if any (see addHaltCheck) + */ + this.afnHalt = []; + this.addrReset = 0x0000; + + /* + * This initial resetRegs() call is important to create all the registers, so that if/when we call restore(), + * it will have something to fill in. + */ + this.resetRegs(); +} + +Component.subclass(CPUStatePDP11, CPUPDP11); + +/** + * addHaltCheck(fn) + * + * Records a function that will be called during HLT opcode processing. + * + * @this {CPUStatePDP11} + * @param {function(number)} fn + */ +CPUStatePDP11.prototype.addHaltCheck = function(fn) +{ + this.afnHalt.push(fn); +}; + +/** + * initProcessor() + * + * Interestingly, if I dynamically generate aOps as an array of functions bound to "this", using the bind() + * method, overall performance is worse. You would think that eliminating the need to use the call() method + * on every opcode function invocation would be helpful, but it's not. I'm not sure exactly why yet; perhaps + * a Closure Compiler optimization is defeated when generating the function array at run-time instead of at + * compile-time. + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.initProcessor = function() +{ + this.aOps = CPUDefPDP11.aOpsPDP1170; +}; + +/** + * reset() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.reset = function() +{ + if (this.flags.fRunning) this.stopCPU(); + this.resetRegs(); + this.resetCycles(); + this.clearError(); // clear any fatal error/exception that setError() may have flagged + this.parent.reset.call(this); +}; + +/** + * resetRegs() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.resetRegs = function() +{ + this.regA = 0; + this.regB = 0; + this.regC = 0; + this.regD = 0; + this.regE = 0; + this.regH = 0; + this.regL = 0; + this.setSP(0); + this.setPC(this.addrReset); + + /* + * This resets the Processor Status flags (regPS), along with all the internal "result registers". + */ + this.setPS(0); + + /* + * intFlags contains some internal states we use to indicate whether a hardware interrupt (INTFLAG.INTR) or + * Trap software interrupt (INTR.TRAP) has been requested, as well as when we're in a "HLT" state (INTFLAG.HALT) + * that requires us to wait for a hardware interrupt (INTFLAG.INTR) before continuing execution. + */ + this.intFlags = CPUDefPDP11.INTFLAG.NONE; +}; + +/** + * setReset(addr) + * + * @this {CPUStatePDP11} + * @param {number} addr + */ +CPUStatePDP11.prototype.setReset = function(addr) +{ + this.addrReset = addr; + this.setPC(addr); +}; + +/** + * getChecksum() + * + * @this {CPUStatePDP11} + * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code) + */ +CPUStatePDP11.prototype.getChecksum = function() +{ + var sum = (this.regA + this.regB + this.regC + this.regD + this.regE + this.regH + this.regL)|0; + sum = (sum + this.getSP() + this.getPC() + this.getPS())|0; + return sum; +}; + +/** + * save() + * + * This implements save support for the CPUStatePDP11 component. + * + * @this {CPUStatePDP11} + * @return {Object|null} + */ +CPUStatePDP11.prototype.save = function() +{ + var state = new State(this); + state.set(0, [this.regA, this.regB, this.regC, this.regD, this.regE, this.regH, this.regL, this.getSP(), this.getPC(), this.getPS()]); + state.set(1, [this.intFlags, this.nTotalCycles, this.getSpeed()]); + state.set(2, this.bus.saveMemory()); + return state.data(); +}; + +/** + * restore(data) + * + * This implements restore support for the CPUStatePDP11 component. + * + * @this {CPUStatePDP11} + * @param {Object} data + * @return {boolean} true if restore successful, false if not + */ +CPUStatePDP11.prototype.restore = function(data) +{ + var a = data[0]; + this.regA = a[0]; + this.regB = a[1]; + this.regC = a[2]; + this.regD = a[3]; + this.regE = a[4]; + this.regH = a[5]; + this.regL = a[6]; + this.setSP(a[7]); + this.setPC(a[8]); + this.setPS(a[9]); + a = data[1]; + this.intFlags = a[0]; + this.nTotalCycles = a[1]; + this.setSpeed(a[3]); + return this.bus.restoreMemory(data[2]); +}; + +/** + * setBinding(sHTMLType, sBinding, control, sValue) + * + * @this {CPUStatePDP11} + * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "AX") + * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) + * @param {string} [sValue] optional data value + * @return {boolean} true if binding was successful, false if unrecognized binding request + */ +CPUStatePDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) +{ + var fBound = false; + switch (sBinding) { + case "PC": + case "PSW": + case "IF": + case "SF": + case "ZF": + case "CF": + this.bindings[sBinding] = control; + this.cLiveRegs++; + fBound = true; + break; + default: + fBound = this.parent.setBinding.call(this, sHTMLType, sBinding, control); + break; + } + return fBound; +}; + +/** + * getBC() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getBC = function() +{ + return (this.regB << 8) | this.regC; +}; + +/** + * setBC(w) + * + * @this {CPUStatePDP11} + * @param {number} w + */ +CPUStatePDP11.prototype.setBC = function(w) +{ + this.regB = (w >> 8) & 0xff; + this.regC = w & 0xff; +}; + +/** + * getDE() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getDE = function() +{ + return (this.regD << 8) | this.regE; +}; + +/** + * setDE(w) + * + * @this {CPUStatePDP11} + * @param {number} w + */ +CPUStatePDP11.prototype.setDE = function(w) +{ + this.regD = (w >> 8) & 0xff; + this.regE = w & 0xff; +}; + +/** + * getHL() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getHL = function() +{ + return (this.regH << 8) | this.regL; +}; + +/** + * setHL(w) + * + * @this {CPUStatePDP11} + * @param {number} w + */ +CPUStatePDP11.prototype.setHL = function(w) +{ + this.regH = (w >> 8) & 0xff; + this.regL = w & 0xff; +}; + +/** + * getSP() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getSP = function() +{ + return this.regSP; +}; + +/** + * setSP(off) + * + * @this {CPUStatePDP11} + * @param {number} off + */ +CPUStatePDP11.prototype.setSP = function(off) +{ + this.regSP = off & 0xffff; +}; + +/** + * getPC() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getPC = function() +{ + return this.regPC; +}; + +/** + * offPC() + * + * @this {CPUStatePDP11} + * @param {number} off + * @return {number} + */ +CPUStatePDP11.prototype.offPC = function(off) +{ + return (this.regPC + off) & 0xffff; +}; + +/** + * setPC(off) + * + * @this {CPUStatePDP11} + * @param {number} off + */ +CPUStatePDP11.prototype.setPC = function(off) +{ + this.regPC = off & 0xffff; +}; + +/** + * clearCF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.clearCF = function() +{ + this.resultZeroCarry &= 0xff; +}; + +/** + * getCF() + * + * @this {CPUStatePDP11} + * @return {number} 0 or 1 (CPUDefPDP11.PS.CF) + */ +CPUStatePDP11.prototype.getCF = function() +{ + return (this.resultZeroCarry & 0x100)? CPUDefPDP11.PS.CF : 0; +}; + +/** + * setCF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.setCF = function() +{ + this.resultZeroCarry |= 0x100; +}; + +/** + * updateCF(CF) + * + * @this {CPUStatePDP11} + * @param {number} CF (0x000 or 0x100) + */ +CPUStatePDP11.prototype.updateCF = function(CF) +{ + this.resultZeroCarry = (this.resultZeroCarry & 0xff) | CF; +}; + +/** + * clearZF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.clearZF = function() +{ + this.resultZeroCarry |= 0xff; +}; + +/** + * getZF() + * + * @this {CPUStatePDP11} + * @return {number} 0 or CPUDefPDP11.PS.ZF + */ +CPUStatePDP11.prototype.getZF = function() +{ + return (this.resultZeroCarry & 0xff)? 0 : CPUDefPDP11.PS.ZF; +}; + +/** + * setZF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.setZF = function() +{ + this.resultZeroCarry &= ~0xff; +}; + +/** + * clearSF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.clearSF = function() +{ + if (this.getSF()) this.resultParitySign ^= 0xc0; +}; + +/** + * getSF() + * + * @this {CPUStatePDP11} + * @return {number} 0 or CPUDefPDP11.PS.SF + */ +CPUStatePDP11.prototype.getSF = function() +{ + return (this.resultParitySign & 0x80)? CPUDefPDP11.PS.SF : 0; +}; + +/** + * setSF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.setSF = function() +{ + if (!this.getSF()) this.resultParitySign ^= 0xc0; +}; + +/** + * clearIF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.clearIF = function() +{ + this.regPS &= ~CPUDefPDP11.PS.IF; +}; + +/** + * getIF() + * + * @this {CPUStatePDP11} + * @return {number} 0 or CPUDefPDP11.PS.IF + */ +CPUStatePDP11.prototype.getIF = function() +{ + return (this.regPS & CPUDefPDP11.PS.IF); +}; + +/** + * setIF() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.setIF = function() +{ + this.regPS |= CPUDefPDP11.PS.IF; +}; + +/** + * getPS() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getPS = function() +{ + return (this.regPS & ~CPUDefPDP11.PS.RESULT) | (this.getSF() | this.getZF() | this.getCF()); +}; + +/** + * setPS(regPS) + * + * @this {CPUStatePDP11} + * @param {number} regPS + */ +CPUStatePDP11.prototype.setPS = function(regPS) +{ + this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = 0; + if (regPS & CPUDefPDP11.PS.CF) this.resultZeroCarry |= 0x100; + if (!(regPS & CPUDefPDP11.PS.PF)) this.resultParitySign |= 0x01; + if (regPS & CPUDefPDP11.PS.AF) this.resultAuxOverflow |= 0x10; + if (!(regPS & CPUDefPDP11.PS.ZF)) this.resultZeroCarry |= 0xff; + if (regPS & CPUDefPDP11.PS.SF) this.resultParitySign ^= 0xc0; + this.regPS = (this.regPS & ~(CPUDefPDP11.PS.RESULT | CPUDefPDP11.PS.INTERNAL)) | (regPS & CPUDefPDP11.PS.INTERNAL) | CPUDefPDP11.PS.SET; + Component.assert((regPS & CPUDefPDP11.PS.RESULT) == (this.getPS() & CPUDefPDP11.PS.RESULT)); +}; + +/** + * getPSW() + * + * @this {CPUStatePDP11} + * @return {number} + */ +CPUStatePDP11.prototype.getPSW = function() +{ + return (this.getPS() & CPUDefPDP11.PS.MASK) | (this.regA << 8); +}; + +/** + * setPSW(w) + * + * @this {CPUStatePDP11} + * @param {number} w + */ +CPUStatePDP11.prototype.setPSW = function(w) +{ + this.setPS((w & CPUDefPDP11.PS.MASK) | (this.regPS & ~CPUDefPDP11.PS.MASK)); + this.regA = w >> 8; +}; + +/** + * addByte(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA + src + */ +CPUStatePDP11.prototype.addByte = function(src) +{ + this.resultAuxOverflow = this.regA ^ src; + return this.resultParitySign = (this.resultZeroCarry = this.regA + src) & 0xff; +}; + +/** + * addByteCarry(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA + src + carry + */ +CPUStatePDP11.prototype.addByteCarry = function(src) +{ + this.resultAuxOverflow = this.regA ^ src; + return this.resultParitySign = (this.resultZeroCarry = this.regA + src + ((this.resultZeroCarry & 0x100)? 1 : 0)) & 0xff; +}; + +/** + * andByte(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA & src + */ +CPUStatePDP11.prototype.andByte = function(src) +{ + this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = this.regA & src; + if ((this.regA | src) & 0x8) this.resultAuxOverflow ^= 0x10; // set AF by inverting bit 4 in resultAuxOverflow + return this.resultZeroCarry; +}; + +/** + * decByte(b) + * + * We perform this operation using 8-bit two's complement arithmetic, by negating and then adding + * the implied src of 1. This appears to mimic how the PDP11 manages the Auxiliary Carry flag (AF). + * + * @this {CPUStatePDP11} + * @param {number} b + * @return {number} + */ +CPUStatePDP11.prototype.decByte = function(b) +{ + this.resultAuxOverflow = b ^ 0xff; + b = this.resultParitySign = (b + 0xff) & 0xff; + this.resultZeroCarry = (this.resultZeroCarry & ~0xff) | b; + return b; +}; + +/** + * incByte(b) + * + * @this {CPUStatePDP11} + * @param {number} b + * @return {number} + */ +CPUStatePDP11.prototype.incByte = function(b) +{ + this.resultAuxOverflow = b; + b = this.resultParitySign = (b + 1) & 0xff; + this.resultZeroCarry = (this.resultZeroCarry & ~0xff) | b; + return b; +}; + +/** + * orByte(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA | src + */ +CPUStatePDP11.prototype.orByte = function(src) +{ + return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA | src; +}; + +/** + * subByte(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA - src + */ +CPUStatePDP11.prototype.subByte = function(src) +{ + src ^= 0xff; + this.resultAuxOverflow = this.regA ^ src; + return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + 1) ^ 0x100) & 0xff; +}; + +/** + * subByteBorrow(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA - src - carry + */ +CPUStatePDP11.prototype.subByteBorrow = function(src) +{ + src ^= 0xff; + this.resultAuxOverflow = this.regA ^ src; + return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + ((this.resultZeroCarry & 0x100)? 0 : 1)) ^ 0x100) & 0xff; +}; + +/** + * xorByte(src) + * + * @this {CPUStatePDP11} + * @param {number} src + * @return {number} regA ^ src + */ +CPUStatePDP11.prototype.xorByte = function(src) +{ + return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA ^ src; +}; + +/** + * getByte(addr) + * + * @this {CPUStatePDP11} + * @param {number} addr is a linear address + * @return {number} byte (8-bit) value at that address + */ +CPUStatePDP11.prototype.getByte = function(addr) +{ + return this.bus.getByte(addr); +}; + +/** + * getWord(addr) + * + * @this {CPUStatePDP11} + * @param {number} addr is a linear address + * @return {number} word (16-bit) value at that address + */ +CPUStatePDP11.prototype.getWord = function(addr) +{ + return this.bus.getShort(addr); +}; + +/** + * setByte(addr, b) + * + * @this {CPUStatePDP11} + * @param {number} addr is a linear address + * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb) + */ +CPUStatePDP11.prototype.setByte = function(addr, b) +{ + this.bus.setByte(addr, b); +}; + +/** + * setWord(addr, w) + * + * @this {CPUStatePDP11} + * @param {number} addr is a linear address + * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe) + */ +CPUStatePDP11.prototype.setWord = function(addr, w) +{ + this.bus.setShort(addr, w); +}; + +/** + * getPCByte() + * + * @this {CPUStatePDP11} + * @return {number} byte at the current PC; PC advanced by 1 + */ +CPUStatePDP11.prototype.getPCByte = function() +{ + var b = this.getByte(this.regPC); + this.setPC(this.regPC + 1); + return b; +}; + +/** + * getPCWord() + * + * @this {CPUStatePDP11} + * @return {number} word at the current PC; PC advanced by 2 + */ +CPUStatePDP11.prototype.getPCWord = function() +{ + var w = this.getWord(this.regPC); + this.setPC(this.regPC + 2); + return w; +}; + +/** + * popWord() + * + * @this {CPUStatePDP11} + * @return {number} word popped from the current SP; SP increased by 2 + */ +CPUStatePDP11.prototype.popWord = function() +{ + var w = this.getWord(this.regSP); + this.setSP(this.regSP + 2); + return w; +}; + +/** + * pushWord(w) + * + * @this {CPUStatePDP11} + * @param {number} w is the word (16-bit) value to push at current SP; SP decreased by 2 + */ +CPUStatePDP11.prototype.pushWord = function(w) +{ + this.setSP(this.regSP - 2); + this.setWord(this.regSP, w); +}; + +/** + * checkINTR() + * + * @this {CPUStatePDP11} + * @return {boolean} true if execution may proceed, false if not + */ +CPUStatePDP11.prototype.checkINTR = function() +{ + /* + * If the Debugger is single-stepping, this.nStepCycles will always be zero, which we take + * advantage of here to avoid processing interrupts. The Debugger will have to issue a "g" + * command (or "p" command on a call instruction) if you want interrupts to be processed. + */ + if (this.nStepCycles) { + if ((this.intFlags & CPUDefPDP11.INTFLAG.INTR) && this.getIF()) { + for (var nLevel = 0; nLevel < 8; nLevel++) { + if (this.intFlags & (1 << nLevel)) break; + } + this.clearINTR(nLevel); + this.clearIF(); + this.intFlags &= ~CPUDefPDP11.INTFLAG.HALT; + this.aOps[CPUDefPDP11.OPCODE.RST0 | (nLevel << 3)].call(this); + } + } + if (this.intFlags & CPUDefPDP11.INTFLAG.HALT) { + /* + * As discussed in opHLT(), the CPU is never REALLY halted by a HLT instruction; instead, opHLT() + * calls requestHALT(), which sets INTFLAG.HALT and signals to stepCPU() that it's free to end the + * current burst AND that it should not execute any more instructions until checkINTR() indicates + * that a hardware interrupt has been requested. + */ + this.nBurstCycles -= this.nStepCycles; + this.nStepCycles = 0; + return false; + } + return true; +}; + +/** + * clearINTR(nLevel) + * + * Clear the corresponding interrupt level. + * + * nLevel can either be a valid interrupt level (0-7), or -1 to clear all pending interrupts + * (eg, in the event of a system-wide reset). + * + * @this {CPUStatePDP11} + * @param {number} nLevel (0-7, or -1 for all) + */ +CPUStatePDP11.prototype.clearINTR = function(nLevel) +{ + var bitsClear = nLevel < 0? 0xff : (1 << nLevel); + this.intFlags &= ~bitsClear; +}; + + +/** + * requestHALT() + * + * @this {CPUStatePDP11} + */ +CPUStatePDP11.prototype.requestHALT = function() +{ + this.intFlags |= CPUDefPDP11.INTFLAG.HALT; + this.nBurstCycles -= this.nStepCycles; + this.nStepCycles = 0; +}; + +/** + * requestINTR(nLevel) + * + * Request the corresponding interrupt level. + * + * Each interrupt level (0-7) has its own intFlags bit (0-7). If the Interrupt Flag (IF) is also + * set, then we know that checkINTR() will want to issue the interrupt, so we end the current burst + * by setting nStepCycles to zero. But before we do, we subtract nStepCycles from nBurstCycles, + * so that the calculation of how many cycles were actually executed on this burst is correct. + * + * @this {CPUStatePDP11} + * @param {number} nLevel (0-7) + */ +CPUStatePDP11.prototype.requestINTR = function(nLevel) +{ + this.intFlags |= (1 << nLevel); + if (this.getIF()) { + this.nBurstCycles -= this.nStepCycles; + this.nStepCycles = 0; + } +}; + +/** + * updateReg(sReg, nValue, cch) + * + * This function helps updateStatus() by massaging the register names and values according to + * CPU type before passing the call to displayValue(); in the "old days", updateStatus() called + * displayValue() directly (although then it was called displayReg()). + * + * @this {CPUStatePDP11} + * @param {string} sReg + * @param {number} nValue + * @param {number} [cch] (default is 2 hex digits) + */ +CPUStatePDP11.prototype.updateReg = function(sReg, nValue, cch) +{ + this.displayValue(sReg, nValue, cch || 2); +}; + +/** + * updateStatus(fForce) + * + * This provides periodic Control Panel updates (eg, a few times per second; see YIELDS_PER_STATUS). + * this is where we take care of any DOM updates (eg, register values) while the CPU is running. + * + * @this {CPUStatePDP11} + * @param {boolean} [fForce] (true will display registers even if the CPU is running and "live" registers are not enabled) + */ +CPUStatePDP11.prototype.updateStatus = function(fForce) +{ + if (this.cLiveRegs) { + if (fForce || !this.flags.fRunning || this.flags.fDisplayLiveRegs) { + this.updateReg("PC", this.getPC(), 4); + var regPS = this.getPS(); + this.updateReg("PSW", regPS, 4); + this.updateReg("IF", (regPS & CPUDefPDP11.PS.IF)? 1 : 0, 1); + this.updateReg("SF", (regPS & CPUDefPDP11.PS.SF)? 1 : 0, 1); + this.updateReg("ZF", (regPS & CPUDefPDP11.PS.ZF)? 1 : 0, 1); + this.updateReg("CF", (regPS & CPUDefPDP11.PS.CF)? 1 : 0, 1); + } + } + var controlSpeed = this.bindings["speed"]; + if (controlSpeed) controlSpeed.textContent = this.getSpeedCurrent(); +}; + +/** + * stepCPU(nMinCycles) + * + * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger + * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode, + * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective, + * they're all one continuous stream of instructions that can be stepped or run at will. Moreover, + * stepping vs. running should never change the behavior of the simulation. + * + * As a result, the Debugger's complete independence means you can run other 8086/8088 debuggers + * (eg, DEBUG) inside the simulation without interference; you can even "debug" them with the Debugger. + * + * @this {CPUStatePDP11} + * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored) + * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint + * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive + * number indicates successful completion of that many cycles (which should always be >= nMinCycles). + */ +CPUStatePDP11.prototype.stepCPU = function(nMinCycles) +{ + /* + * The Debugger uses fComplete to determine if the instruction completed (true) or was interrupted + * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript + * exceptions, which stepCPU() expects the caller to catch using its own exception handler. + * + * The CPU relies on the use of stopCPU() rather than fComplete, because the CPU never single-steps + * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the + * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set, + * so stopCPU() would have no effect as far as the Debugger is concerned. + */ + this.flags.fComplete = true; + + /* + * fDebugCheck is true if we need to "check" every instruction with the Debugger. + */ + var fDebugCheck = this.flags.fDebugCheck = (DEBUGGER && this.dbg && this.dbg.checksEnabled()); + + /* + * nDebugState is checked only when fDebugCheck is true, and its sole purpose is to tell the first call + * to checkInstruction() that it can skip breakpoint checks, and that will be true ONLY when fStarting is + * true OR nMinCycles is zero (the latter means the Debugger is single-stepping). + * + * Once we snap fStarting, we clear it, because technically, we've moved beyond "starting" and have + * officially "started" now. + */ + var nDebugState = (!nMinCycles)? -1 : (this.flags.fStarting? 0 : 1); + this.flags.fStarting = false; + + /* + * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other + * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check + * any other criteria to determine whether we should continue stepping or not. + */ + this.nBurstCycles = this.nStepCycles = nMinCycles; + + /* + * NOTE: If checkINTR() returns false, INTFLAG.HALT must be set, so no instructions should be executed. + */ + if (this.checkINTR()) { + do { + if (DEBUGGER && fDebugCheck) { + if (this.dbg.checkInstruction(this.regPC, nDebugState)) { + this.stopCPU(); + break; + } + nDebugState = 1; + } + this.aOps[this.getPCByte()].call(this); + + } while (this.nStepCycles > 0); + } + + return (this.flags.fComplete? this.nBurstCycles - this.nStepCycles : (this.flags.fComplete === undefined? 0 : -1)); +}; + +/** + * CPUStatePDP11.init() + * + * This function operates on every HTML element of class "cpu", extracting the + * JSON-encoded parameters for the CPUStatePDP11 constructor from the element's "data-value" + * attribute, invoking the constructor (which in turn invokes the CPU constructor) + * to create a CPUStatePDP11 component, and then binding any associated HTML controls to the + * new component. + */ +CPUStatePDP11.init = function() +{ + var aeCPUs = Component.getElementsByClass(document, PDP11.APPCLASS, "cpu"); + for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) { + var eCPU = aeCPUs[iCPU]; + var parmsCPU = Component.getComponentParms(eCPU); + var cpu = new CPUStatePDP11(parmsCPU); + Component.bindComponentControls(cpu, eCPU, PDP11.APPCLASS); + } +}; + +/* + * Initialize every CPU module on the page + */ +web.onInit(CPUStatePDP11.init); + +if (NODE) module.exports = CPUStatePDP11; diff --git a/modules/pdp11/lib/debugger.js b/modules/pdp11/lib/debugger.js new file mode 100644 index 000000000..ee24a5032 --- /dev/null +++ b/modules/pdp11/lib/debugger.js @@ -0,0 +1,4219 @@ +/** + * @fileoverview Implements the PDP11 Debugger component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (DEBUGGER) { + if (NODE) { + var str = require("../../shared/lib/strlib"); + var usr = require("../../shared/lib/usrlib"); + var web = require("../../shared/lib/weblib"); + var Component = require("../../shared/lib/component"); + var State = require("../../shared/lib/state"); + var PDP11 = require("./defines"); + var CPUDefPDP11 = require("./cpudef"); + var CPUPDP11 = require("./cpu"); + var KeyboardPDP11 = require("./keyboard"); + var MessagesPDP11 = require("./messages"); + var MemoryPDP11 = require("./memory"); + } +} + +/** + * DebuggerPDP11 Address Object + * + * addr address + * fTemporary true if this is a temporary breakpoint address + * sCmd set for breakpoint addresses if there's an associated command string + * aCmds preprocessed commands (from sCmd) + * + * @typedef {{ + * addr:(number|undefined), + * fTemporary:(boolean|undefined), + * sCmd:(string|undefined), + * aCmds:(Array.|undefined) + * }} + */ +var DbgAddrPDP11; + +/** + * DebuggerPDP11(parmsDbg) + * + * @constructor + * @extends Component + * @param {Object} parmsDbg + * + * The DebuggerPDP11 component supports the following optional (parmsDbg) properties: + * + * commands: string containing zero or more commands, separated by ';' + * + * messages: string containing zero or more message categories to enable; + * multiple categories must be separated by '|' or ';'. Parsed by messageInit(). + * + * The DebuggerPDP11 component is an optional component that implements a variety of user + * commands for controlling the CPU, dumping and editing memory, etc. + */ +function DebuggerPDP11(parmsDbg) +{ + if (DEBUGGER) { + + Component.call(this, "Debugger", parmsDbg, DebuggerPDP11); + + /* + * These keep track of instruction activity, but only when tracing or when DebuggerPDP11 checks + * have been enabled (eg, one or more breakpoints have been set). + * + * They are zeroed by the reset() notification handler. cInstructions is advanced by + * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop() + * call and simply represents the number of cycles performed by the last run of instructions. + */ + this.nCycles = 0; + this.cOpcodes = this.cOpcodesStart = 0; + + /* + * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode + * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn, + * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done. + * + * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically + * cleared when they're hit. + */ + this.dbgAddrNextCode = this.newAddr(); + this.dbgAddrNextData = this.newAddr(); + + /* + * This maintains command history. New commands are inserted at index 0 of the array. + * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0]. + */ + this.iPrevCmd = -1; + this.aPrevCmds = []; + + /* + * fAssemble is true when "assemble mode" is active, false when not. + */ + this.fAssemble = false; + this.dbgAddrAssemble = this.newAddr(); + + /* + * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space, + * where each object contains the following properties: + * + * sModule + * addr (physical address, if any; eg, symbols for a ROM) + * len + * aSymbols + * aOffsets + * + * See addSymbols() for more details, since that's how callers add sets of symbols to the table. + */ + this.aSymbolTable = []; + + /* + * aVariables is an object with properties that grows as setVariable() assigns more variables; + * each property corresponds to one variable, where the property name is the variable name (ie, + * a string beginning with a letter or underscore, followed by zero or more additional letters, + * digits, or underscores) and the property value is the variable's numeric value. See doVar() + * and setVariable() for details. + * + * Note that parseValue(), through its reliance on str.parseInt(), assumes a default base of 16 + * if no base is explicitly indicated (eg, a trailing decimal period), and if you define variable + * names containing exclusively hex alpha characters (a-f), those variables will take precedence + * over the corresponding hex values. In other words, if you define variables "a" and "b", you + * will no longer be able to simply type "a" or "b" to specify the decimal values 10 or 11. + */ + this.aVariables = {}; + + /* + * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses + * to halt on whenever attempting to execute an instruction at the corresponding address, + * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write, + * respectively, occurs at the corresponding address. + * + * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609, + * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead + * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've + * explicitly initialized all the properties that clearBreakpoints() (re)initializes. + */ + this.aBreakExec = this.aBreakRead = this.aBreakWrite = []; + this.clearBreakpoints(); + + /* + * The new "bn" command allows you to specify a number of instructions to execute and then stop; + * "bn 0" disables any outstanding count. + */ + this.nBreakIns = 0; + + /* + * Execution history is allocated by historyInit() whenever checksEnabled() conditions change. + * Execution history is updated whenever the CPU calls checkInstruction(), which will happen + * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set). + * This ensures that, by default, the CPU runs as fast as possible. + */ + this.historyInit(); + + /* + * Initialize DebuggerPDP11 message support + */ + this.afnDumpers = []; + this.messageInit(parmsDbg['messages']); + + this.sInitCommands = parmsDbg['commands']; + + /* + * Make it easier to access DebuggerPDP11 commands from an external REPL (eg, the WebStorm + * "live" console window); eg: + * + * pdp11('r') + * pdp11('dw 0:0') + * pdp11('h') + * ... + */ + var dbg = this; + if (window) { + if (window[PDP11.APPCLASS] === undefined) { + window[PDP11.APPCLASS] = function(s) { return dbg.doCommands(s); }; + } + } else { + if (global[PDP11.APPCLASS] === undefined) { + global[PDP11.APPCLASS] = function(s) { return dbg.doCommands(s); }; + } + } + + } // endif DEBUGGER +} + +if (DEBUGGER) { + + Component.subclass(DebuggerPDP11); + + /* + * NOTE: Every DebuggerPDP11 property from here to the first prototype function definition (initBus()) is a + * considered a "class constant"; most of them use our "all-caps" convention (and all of them SHOULD, but + * that wouldn't help us catch any bugs). + * + * Technically, all of them should ALSO be preceded by a "@const" annotation, but that's a lot of work and it + * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given + * section with a single annotation.... + * + * Bugs can slip through the cracks without those annotations; for example, I unthinkingly redefined TYPE_SI + * at one point, and if all the definitions had been preceded by an "@const", that mistake would have been + * caught at compile-time. + */ + + DebuggerPDP11.COMMANDS = { + '?': "help/print", + 'a [#]': "assemble", // TODO: Implement this command someday + 'b [#]': "breakpoint", // multiple variations (use b? to list them) + 'c': "clear output", + 'd [#]': "dump memory", // additional syntax: d [#] [l#], where l# is a number of bytes to dump + 'e [#]': "edit memory", + 'f': "frequencies", + 'g [#]': "go [to #]", + 'h': "halt", + 'if': "eval expression", + 'int [#]': "request interrupt", + 'k': "stack trace", + "ln": "list nearest symbol(s)", + 'm': "messages", + 'p': "step over", // other variations: pr (step and dump registers) + 'print': "print expression", + 'r': "dump/set registers", + 'reset': "reset machine", + 's': "set options", + 't [#]': "trace", // other variations: tr (trace and dump registers) + 'u [#]': "unassemble", + 'v': "print version", + 'var': "assign variable" + }; + + /* + * CPU instruction ordinals + */ + DebuggerPDP11.INS = { + NONE: 0 + }; + + /* + * CPU instruction names (mnemonics), indexed by CPU instruction ordinal (above) + */ + DebuggerPDP11.INS_NAMES = [ + "NONE" + ]; + + DebuggerPDP11.REG_PC = 0x0C; + DebuggerPDP11.REG_PSW = 0x0E; + + DebuggerPDP11.REGS = [ + "PC", "PSW" + ]; + + /* + * Operand type descriptor masks and definitions + */ + DebuggerPDP11.TYPE_SIZE = 0x000F; // size field + DebuggerPDP11.TYPE_MODE = 0x00F0; // mode field + DebuggerPDP11.TYPE_IREG = 0x0F00; // implied register field + DebuggerPDP11.TYPE_OTHER = 0xF000; // "other" field + + /* + * TYPE_SIZE values + */ + DebuggerPDP11.TYPE_NONE = 0x0000; // (all other TYPE fields ignored) + DebuggerPDP11.TYPE_BYTE = 0x0001; // byte, regardless of operand size + DebuggerPDP11.TYPE_SBYTE = 0x0002; // byte sign-extended to word + DebuggerPDP11.TYPE_WORD = 0x0003; // word (16-bit value) + + /* + * TYPE_MODE values + */ + DebuggerPDP11.TYPE_REG = 0x0010; // register + DebuggerPDP11.TYPE_IMM = 0x0020; // immediate data + DebuggerPDP11.TYPE_ADDR = 0x0033; // immediate (word) address + DebuggerPDP11.TYPE_MEM = 0x0040; // memory reference + DebuggerPDP11.TYPE_INT = 0x0080; // interrupt level encoded in instruction (bits 3-5) + + /* + * TYPE_IREG values, based on the REG_* constants. + * + * Note that TYPE_M isn't really a register, just an alternative form of TYPE_HL | TYPE_MEM. + */ + DebuggerPDP11.TYPE_PC = (DebuggerPDP11.REG_PC << 8 | DebuggerPDP11.TYPE_REG | DebuggerPDP11.TYPE_WORD); + DebuggerPDP11.TYPE_PSW = (DebuggerPDP11.REG_PSW<< 8 | DebuggerPDP11.TYPE_REG | DebuggerPDP11.TYPE_WORD); + + /* + * TYPE_OTHER bit definitions + */ + DebuggerPDP11.TYPE_IN = 0x1000; // operand is input + DebuggerPDP11.TYPE_OUT = 0x2000; // operand is output + DebuggerPDP11.TYPE_BOTH = (DebuggerPDP11.TYPE_IN | DebuggerPDP11.TYPE_OUT); + DebuggerPDP11.TYPE_UNDOC = 0x8000; // opcode is an undocumented alternative encoding + + /* + * The aaOpDescs array is indexed by opcode, and each element is a sub-array (aOpDesc) that describes + * the corresponding opcode. The sub-elements are as follows: + * + * [0]: {number} of the opcode name (see INS.*) + * [1]: {number} containing the destination operand descriptor bit(s), if any + * [2]: {number} containing the source operand descriptor bit(s), if any + * [3]: {number} containing the occasional third operand descriptor bit(s), if any + * + * These sub-elements are all optional. If [0] is not present, the opcode is undefined; if [1] is not + * present (or contains zero), the opcode has no (or only implied) operands; if [2] is not present, the + * opcode has only a single operand. And so on. + * + * Additional default rules: + * + * 1) If no TYPE_OTHER bits are specified for the first (destination) operand, TYPE_OUT is assumed; + * 2) If no TYPE_OTHER bits are specified for the second (source) operand, TYPE_IN is assumed; + * 3) If no size is specified for the second operand, the size is assumed to match the first operand. + */ + DebuggerPDP11.aaOpDescs = [ + ]; + + DebuggerPDP11.HISTORY_LIMIT = DEBUG? 100000 : 1000; + + /** + * initBus(bus, cpu, dbg) + * + * @this {DebuggerPDP11} + * @param {ComputerPDP11} cmp + * @param {BusPDP11} bus + * @param {CPUStatePDP11} cpu + * @param {DebuggerPDP11} dbg + */ + DebuggerPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) + { + this.bus = bus; + this.cpu = cpu; + this.cmp = cmp; + + /* + * Re-initialize Debugger message support if necessary + */ + var sMessages = cmp.getMachineParm('messages'); + if (sMessages) this.messageInit(sMessages); + + this.aaOpDescs = DebuggerPDP11.aaOpDescs; + + this.messageDump(MessagesPDP11.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); }); + + this.setReady(); + }; + + /** + * setBinding(sHTMLType, sBinding, control, sValue) + * + * @this {DebuggerPDP11} + * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "debugInput") + * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) + * @param {string} [sValue] optional data value + * @return {boolean} true if binding was successful, false if unrecognized binding request + */ + DebuggerPDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) + { + var dbg = this; + switch (sBinding) { + + case "debugInput": + this.bindings[sBinding] = control; + this.controlDebug = control; + /* + * For halted machines, this is fine, but for auto-start machines, it can be annoying. + * + * control.focus(); + */ + control.onkeydown = function onKeyDownDebugInput(event) { + var sCmds; + if (event.keyCode == KeyboardPDP11.KEYCODE.CR) { + sCmds = control.value; + control.value = ""; + dbg.doCommands(sCmds, true); + } + else if (event.keyCode == KeyboardPDP11.KEYCODE.ESC) { + control.value = sCmds = ""; + } + else { + if (event.keyCode == KeyboardPDP11.KEYCODE.UP) { + if (dbg.iPrevCmd < dbg.aPrevCmds.length - 1) { + sCmds = dbg.aPrevCmds[++dbg.iPrevCmd]; + } + } + else if (event.keyCode == KeyboardPDP11.KEYCODE.DOWN) { + if (dbg.iPrevCmd > 0) { + sCmds = dbg.aPrevCmds[--dbg.iPrevCmd]; + } else { + sCmds = ""; + dbg.iPrevCmd = -1; + } + } + if (sCmds != null) { + var cch = sCmds.length; + control.value = sCmds; + control.setSelectionRange(cch, cch); + } + } + if (sCmds != null && event.preventDefault) event.preventDefault(); + }; + return true; + + case "debugEnter": + this.bindings[sBinding] = control; + web.onClickRepeat( + control, + 500, 100, + function onClickDebugEnter(fRepeat) { + if (dbg.controlDebug) { + var sCmds = dbg.controlDebug.value; + dbg.controlDebug.value = ""; + dbg.doCommands(sCmds, true); + return true; + } + if (DEBUG) dbg.log("no debugger input buffer"); + return false; + } + ); + return true; + + case "step": + this.bindings[sBinding] = control; + web.onClickRepeat( + control, + 500, 100, + function onClickStep(fRepeat) { + var fCompleted = false; + if (!dbg.isBusy(true)) { + dbg.setBusy(true); + fCompleted = dbg.stepCPU(fRepeat? 1 : 0); + dbg.setBusy(false); + } + return fCompleted; + } + ); + return true; + + default: + break; + } + return false; + }; + + /** + * updateFocus() + * + * @this {DebuggerPDP11} + */ + DebuggerPDP11.prototype.updateFocus = function() + { + if (this.controlDebug) this.controlDebug.focus(); + }; + + /** + * getAddr(dbgAddr, fWrite, nb) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11|null|undefined} dbgAddr + * @param {boolean} [fWrite] + * @param {number} [nb] number of bytes to check (1 or 2); default is 1 + * @return {number} is the corresponding linear address, or CPUDefPDP11.ADDR_INVALID + */ + DebuggerPDP11.prototype.getAddr = function(dbgAddr, fWrite, nb) + { + var addr = dbgAddr && dbgAddr.addr; + if (addr == null) { + addr = CPUDefPDP11.ADDR_INVALID; + } + return addr; + }; + + /** + * getByte(dbgAddr, inc) + * + * We must route all our memory requests through the CPU now, in case paging is enabled. + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} [inc] + * @return {number} + */ + DebuggerPDP11.prototype.getByte = function(dbgAddr, inc) + { + var b = 0xff; + var addr = this.getAddr(dbgAddr, false, 1); + if (addr !== CPUDefPDP11.ADDR_INVALID) { + b = this.bus.getByteDirect(addr); + if (inc) this.incAddr(dbgAddr, inc); + } + return b; + }; + + /** + * getWord(dbgAddr, fAdvance) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {boolean} [fAdvance] + * @return {number} + */ + DebuggerPDP11.prototype.getWord = function(dbgAddr, fAdvance) + { + return this.getShort(dbgAddr, fAdvance? 2 : 0); + }; + + /** + * getShort(dbgAddr, inc) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} [inc] + * @return {number} + */ + DebuggerPDP11.prototype.getShort = function(dbgAddr, inc) + { + var w = 0xffff; + var addr = this.getAddr(dbgAddr, false, 2); + if (addr !== CPUDefPDP11.ADDR_INVALID) { + w = this.bus.getShortDirect(addr); + if (inc) this.incAddr(dbgAddr, inc); + } + return w; + }; + + /** + * setByte(dbgAddr, b, inc) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} b + * @param {number} [inc] + */ + DebuggerPDP11.prototype.setByte = function(dbgAddr, b, inc) + { + var addr = this.getAddr(dbgAddr, true, 1); + if (addr !== CPUDefPDP11.ADDR_INVALID) { + this.bus.setByteDirect(addr, b); + if (inc) this.incAddr(dbgAddr, inc); + this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target + } + }; + + /** + * setShort(dbgAddr, w, inc) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} w + * @param {number} [inc] + */ + DebuggerPDP11.prototype.setShort = function(dbgAddr, w, inc) + { + var addr = this.getAddr(dbgAddr, true, 2); + if (addr !== CPUDefPDP11.ADDR_INVALID) { + this.bus.setShortDirect(addr, w); + if (inc) this.incAddr(dbgAddr, inc); + this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target + } + }; + + /** + * newAddr(addr) + * + * Returns a NEW DbgAddrPDP11 object, initialized with specified values and/or defaults. + * + * @this {DebuggerPDP11} + * @param {number} [addr] + * @return {DbgAddrPDP11} + */ + DebuggerPDP11.prototype.newAddr = function(addr) + { + return {addr: addr, fTemporary: false}; + }; + + /** + * setAddr(dbgAddr, addr) + * + * Updates an EXISTING DbgAddrPDP11 object, initialized with specified values and/or defaults. + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} addr + * @return {DbgAddrPDP11} + */ + DebuggerPDP11.prototype.setAddr = function(dbgAddr, addr) + { + dbgAddr.addr = addr; + dbgAddr.fTemporary = false; + return dbgAddr; + }; + + /** + * packAddr(dbgAddr) + * + * Packs a DbgAddrPDP11 object into an Array suitable for saving in a machine state object. + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @return {Array} + */ + DebuggerPDP11.prototype.packAddr = function(dbgAddr) + { + return [dbgAddr.addr, dbgAddr.fTemporary]; + }; + + /** + * unpackAddr(aAddr) + * + * Unpacks a DbgAddrPDP11 object from an Array created by packAddr() and restored from a saved machine state. + * + * @this {DebuggerPDP11} + * @param {Array} aAddr + * @return {DbgAddrPDP11} + */ + DebuggerPDP11.prototype.unpackAddr = function(aAddr) + { + return {addr: aAddr[0], fTemporary: aAddr[1]}; + }; + + /** + * parseAddr(sAddr, fCode, fNoChecks, fPrint) + * + * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's + * done later, by getAddr(), which returns CPUDefPDP11.ADDR_INVALID for invalid segments, out-of-range offsets, + * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an + * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with + * BusPDP11.nBusLimit; in the case of CPUDefPDP11.ADDR_INVALID, that will generally refer to the top of the physical + * address space. + * + * @this {DebuggerPDP11} + * @param {string|undefined} sAddr + * @param {boolean} [fCode] (true if target is code, false if target is data) + * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later) + * @param {boolean} [fPrint] + * @return {DbgAddrPDP11|null|undefined} + */ + DebuggerPDP11.prototype.parseAddr = function(sAddr, fCode, fNoChecks, fPrint) + { + var dbgAddr; + var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData); + var addr = dbgAddrNext.addr; + if (sAddr !== undefined) { + sAddr = this.parseReference(sAddr); + dbgAddr = this.findSymbolAddr(sAddr); + if (dbgAddr) return dbgAddr; + addr = this.parseExpression(sAddr, fPrint); + } + if (addr != null) { + dbgAddr = this.newAddr(addr); + } + return dbgAddr; + }; + + /** + * parseAddrOptions(dbdAddr, sOptions) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {string} [sOptions] + */ + DebuggerPDP11.prototype.parseAddrOptions = function(dbgAddr, sOptions) + { + if (sOptions) { + var a = sOptions.match(/(['"])(.*?)\1/); + if (a) { + dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]); + } + } + }; + + /** + * incAddr(dbgAddr, inc) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} [inc] contains value to increment dbgAddr by (default is 1) + */ + DebuggerPDP11.prototype.incAddr = function(dbgAddr, inc) + { + if (dbgAddr.addr != null) { + dbgAddr.addr += (inc || 1); + } + }; + + /** + * toHexOffset(off) + * + * @this {DebuggerPDP11} + * @param {number|null|undefined} [off] + * @return {string} the hex representation of off + */ + DebuggerPDP11.prototype.toHexOffset = function(off) + { + return str.toHex(off, 4); + }; + + /** + * toHexAddr(dbgAddr) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @return {string} the hex representation of the address + */ + DebuggerPDP11.prototype.toHexAddr = function(dbgAddr) + { + return this.toHexOffset(dbgAddr.addr); + }; + + /** + * getSZ(dbgAddr, cchMax) + * + * Gets zero-terminated (aka "ASCIIZ") string from dbgAddr. It also stops at the first '$', in case this is + * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function. + * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care. + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {number} [cchMax] (default is 256) + * @return {string} (and dbgAddr advanced past the terminating zero) + */ + DebuggerPDP11.prototype.getSZ = function(dbgAddr, cchMax) + { + var s = ""; + cchMax = cchMax || 256; + while (s.length < cchMax) { + var b = this.getByte(dbgAddr, 1); + if (!b || b == 0x24 || b >= 127) break; + s += (b >= 32? String.fromCharCode(b) : '.'); + } + return s; + }; + + /** + * dumpBlocks(aBlocks, sAddr) + * + * @this {DebuggerPDP11} + * @param {Array} aBlocks + * @param {string} [sAddr] (optional block address) + */ + DebuggerPDP11.prototype.dumpBlocks = function(aBlocks, sAddr) + { + var addr = 0, i = 0, n = aBlocks.length; + + if (sAddr) { + addr = this.getAddr(this.parseAddr(sAddr)); + if (addr === CPUDefPDP11.ADDR_INVALID) { + this.println("invalid address: " + sAddr); + return; + } + i = addr >>> this.bus.nBlockShift; + n = 1; + } + + this.println("blockid physical blockaddr used size type"); + this.println("-------- --------- ---------- ------ ------ ----"); + + var typePrev = -1, cPrev = 0; + while (n--) { + var block = aBlocks[i]; + if (block.type == typePrev) { + if (!cPrev++) this.println("..."); + } else { + typePrev = block.type; + var sType = MemoryPDP11.TYPE.NAMES[typePrev]; + if (block) { + this.println(str.toHex(block.id) + " %" + str.toHex(i << this.bus.nBlockShift) + " %%" + str.toHex(block.addr) + " " + str.toHexWord(block.used) + " " + str.toHexWord(block.size) + " " + sType); + } + if (typePrev != MemoryPDP11.TYPE.NONE) typePrev = -1; + cPrev = 0; + } + addr += this.bus.nBlockSize; + i++; + } + }; + + /** + * dumpBus(asArgs) + * + * Dumps Bus allocations. + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs (asArgs[0] is an optional block address) + */ + DebuggerPDP11.prototype.dumpBus = function(asArgs) + { + this.dumpBlocks(this.bus.aMemBlocks, asArgs[0]); + }; + + /** + * dumpHistory(sPrev, sLines) + * + * If sLines is not a number, it can be a instruction filter. However, for the moment, the only + * supported filter is "call", which filters the history buffer for all CALL and RET instructions + * from the specified previous point forward. + * + * @this {DebuggerPDP11} + * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10) + * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10) + */ + DebuggerPDP11.prototype.dumpHistory = function(sPrev, sLines) + { + var sMore = ""; + var cHistory = 0; + var iHistory = this.iOpcodeHistory; + var aHistory = this.aOpcodeHistory; + + if (aHistory.length) { + var nPrev = +sPrev || this.nextHistory; + var nLines = +sLines || 10; + + if (isNaN(nPrev)) { + nPrev = nLines; + } else { + sMore = "more "; + } + + if (nPrev > aHistory.length) { + this.println("note: only " + aHistory.length + " available"); + nPrev = aHistory.length; + } + + iHistory -= nPrev; + if (iHistory < 0) { + /* + * If the dbgAddr of the last aHistory element contains a valid selector, wrap around. + */ + if (aHistory[aHistory.length - 1].addr == null) { + nPrev = iHistory + nPrev; + iHistory = 0; + } else { + iHistory += aHistory.length; + } + } + + var aFilters = []; + if (sLines == "call") { + nLines = 100000; + aFilters = ["CALL"]; + } + + if (sPrev !== undefined) { + this.println(nPrev + " instructions earlier:"); + } + + /* + * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive) + * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically + * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction + * bytes alongside the execution addresses). + * + * For now, we're living dangerously, so that our history dumps actually work. + * + * this.nSuppressBreaks++; + * + * If you re-enable this protection, be sure to re-enable the decrement below, too. + */ + while (nLines > 0 && iHistory != this.iOpcodeHistory) { + + var dbgAddr = aHistory[iHistory++]; + if (dbgAddr.addr == null) break; + + /* + * We must create a new dbgAddr from the address in aHistory, because dbgAddr was + * a reference, not a copy, and we don't want getInstruction() modifying the original. + */ + var dbgAddrNew = this.newAddr(dbgAddr.addr); + + var sComment = "history"; + var nSequence = nPrev--; + if (DEBUG && dbgAddr.cycleCount != null) { + sComment = "cycles"; + nSequence = dbgAddr.cycleCount; + } + + var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence); + + if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) { + this.println(sInstruction); + } + + /* + * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction() + * will have automatically disassembled additional bytes, so skip additional history entries. + */ + if (dbgAddrNew.cOverrides) { + iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides; + } + + if (iHistory >= aHistory.length) iHistory = 0; + this.nextHistory = nPrev; + cHistory++; + nLines--; + } + /* + * See comments above. + * + * this.nSuppressBreaks--; + */ + } + + if (!cHistory) { + this.println("no " + sMore + "history available"); + this.nextHistory = undefined; + } + }; + + /** + * messageInit(sEnable) + * + * @this {DebuggerPDP11} + * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|' + */ + DebuggerPDP11.prototype.messageInit = function(sEnable) + { + this.dbg = this; + this.bitsMessage = this.bitsWarning = MessagesPDP11.WARN; + this.sMessagePrev = null; + this.aMessageBuffer = []; + /* + * Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects, + * but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard". + */ + var aEnable = this.parseCommand(sEnable.replace("keys","key").replace("kbd","keyboard"), false, '|'); + if (aEnable.length) { + for (var m in MessagesPDP11.CATEGORIES) { + if (usr.indexOf(aEnable, m) >= 0) { + this.bitsMessage |= MessagesPDP11.CATEGORIES[m]; + this.println(m + " messages enabled"); + } + } + } + }; + + /** + * messageDump(bitMessage, fnDumper) + * + * @this {DebuggerPDP11} + * @param {number} bitMessage is one Messages category flag + * @param {function(Array.)} fnDumper is a function the Debugger can use to dump data for that category + * @return {boolean} true if successfully registered, false if not + */ + DebuggerPDP11.prototype.messageDump = function(bitMessage, fnDumper) + { + for (var m in MessagesPDP11.CATEGORIES) { + if (bitMessage == MessagesPDP11.CATEGORIES[m]) { + this.afnDumpers[m] = fnDumper; + return true; + } + } + return false; + }; + + /** + * getRegIndex(sReg, off) + * + * @this {DebuggerPDP11} + * @param {string} sReg + * @param {number} [off] optional offset into sReg + * @return {number} register index, or -1 if not found + */ + DebuggerPDP11.prototype.getRegIndex = function(sReg, off) + { + var i; + sReg = sReg.toUpperCase(); + if (off == null) { + i = usr.indexOf(DebuggerPDP11.REGS, sReg); + } else { + i = usr.indexOf(DebuggerPDP11.REGS, sReg.substr(off, 2)); + if (i < 0) i = usr.indexOf(DebuggerPDP11.REGS, sReg.substr(off, 1)); + } + return i; + }; + + /** + * getRegString(iReg) + * + * @this {DebuggerPDP11} + * @param {number} iReg + * @return {string} + */ + DebuggerPDP11.prototype.getRegString = function(iReg) + { + var cch = 0; + var n = this.getRegValue(iReg); + if (n !== undefined) { + switch(iReg) { + case DebuggerPDP11.REG_PC: + case DebuggerPDP11.REG_PSW: + cch = 4; + break; + } + } + return cch? str.toHex(n, cch) : "??"; + }; + + /** + * getRegValue(iReg) + * + * @this {DebuggerPDP11} + * @param {number} iReg + * @return {number|undefined} + */ + DebuggerPDP11.prototype.getRegValue = function(iReg) + { + var n; + if (iReg >= 0) { + var cpu = this.cpu; + switch(iReg) { + case DebuggerPDP11.REG_PC: + n = cpu.getPC(); + break; + case DebuggerPDP11.REG_PSW: + n = cpu.getPSW(); + break; + default: + break; + } + } + return n; + }; + + /** + * replaceRegs(s) + * + * @this {DebuggerPDP11} + * @param {string} s + * @return {string} + */ + DebuggerPDP11.prototype.replaceRegs = function(s) + { + /* + * Replace any references first; this means that register references inside the reference + * do NOT need to be prefixed with '@'. + */ + s = this.parseReference(s); + + /* + * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value. + */ + var i = 0; + var b, sChar, sAddr, dbgAddr, sReplace; + while ((i = s.indexOf('@', i)) >= 0) { + var iReg = this.getRegIndex(s, i + 1); + if (iReg >= 0) { + s = s.substr(0, i) + this.getRegString(iReg) + s.substr(i + 1 + DebuggerPDP11.REGS[iReg].length); + } + i++; + } + /* + * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable). + */ + i = 0; + while ((i = s.indexOf('#', i)) >= 0) { + sChar = s.substr(i+1, 2); + b = str.parseInt(sChar, 16); + if (b != null && b >= 32 && b < 128) { + sReplace = sChar + " '" + String.fromCharCode(b) + "'"; + s = s.replace('#' + sChar, sReplace); + i += sReplace.length; + continue; + } + i++; + } + /* + * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address. + */ + i = 0; + while ((i = s.indexOf('$', i)) >= 0) { + sAddr = s.substr(i+1, 9); + dbgAddr = this.parseAddr(sAddr); + if (dbgAddr) { + sReplace = sAddr + ' "' + this.getSZ(dbgAddr) + '"'; + s = s.replace('$' + sAddr, sReplace); + i += sReplace.length; + continue; + } + i++; + } + /* + * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address. + */ + i = 0; + while ((i = s.indexOf('^', i)) >= 0) { + sAddr = s.substr(i+1, 9); + dbgAddr = this.parseAddr(sAddr); + if (dbgAddr) { + this.incAddr(dbgAddr); + sReplace = sAddr + ' "' + this.getSZ(dbgAddr, 11) + '"'; + s = s.replace('^' + sAddr, sReplace); + i += sReplace.length; + continue; + } + i++; + } + return s; + }; + + /** + * message(sMessage, fAddress) + * + * @this {DebuggerPDP11} + * @param {string} sMessage is any caller-defined message string + * @param {boolean} [fAddress] is true to display the current CS:IP + */ + DebuggerPDP11.prototype.message = function(sMessage, fAddress) + { + if (fAddress) { + sMessage += " at " + this.toHexAddr(this.newAddr(this.cpu.getPC())); + } + + if (this.bitsMessage & MessagesPDP11.BUFFER) { + this.aMessageBuffer.push(sMessage); + return; + } + + if (this.sMessagePrev && sMessage == this.sMessagePrev) return; + this.sMessagePrev = sMessage; + + if (this.bitsMessage & MessagesPDP11.HALT) { + this.stopCPU(); + sMessage += " (cpu halted)"; + } + + this.println(sMessage); // + " (" + this.cpu.getCycles() + " cycles)" + + /* + * We have no idea what the frequency of println() calls might be; all we know is that they easily + * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every + * message, to effectively end the current burst and start fresh. + * + * TODO: See CPUPDP11.calcStartTime() for a discussion of why we might want to call yieldCPU() *before* + * we display the message. + */ + if (this.cpu) this.cpu.yieldCPU(); + }; + + /** + * init() + * + * @this {DebuggerPDP11} + */ + DebuggerPDP11.prototype.init = function() + { + this.println("Type ? for help with PDP11 Debugger commands"); + this.updateStatus(); + if (this.sInitCommands) { + var sCmds = this.sInitCommands; + this.sInitCommands = null; + this.doCommands(sCmds); + } + }; + + /** + * historyInit(fQuiet) + * + * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint() + * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction() + * should be called. + * + * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them, + * and if the arrays are no longer needed, then deallocate them. + * + * @this {DebuggerPDP11} + * @param {boolean} [fQuiet] + */ + DebuggerPDP11.prototype.historyInit = function(fQuiet) + { + var i; + if (!this.checksEnabled()) { + if (this.aOpcodeHistory && this.aOpcodeHistory.length && !fQuiet) { + this.println("instruction history buffer freed"); + } + this.iOpcodeHistory = 0; + this.aOpcodeHistory = []; + this.aaOpcodeCounts = []; + return; + } + if (!this.aOpcodeHistory || !this.aOpcodeHistory.length) { + this.aOpcodeHistory = new Array(DebuggerPDP11.HISTORY_LIMIT); + for (i = 0; i < this.aOpcodeHistory.length; i++) { + /* + * Preallocate dummy Addr (Array) objects in every history slot, so that + * checkInstruction() doesn't need to call newAddr() on every slot update. + */ + this.aOpcodeHistory[i] = this.newAddr(); + } + this.iOpcodeHistory = 0; + if (!fQuiet) { + this.println("instruction history buffer allocated"); + } + } + if (!this.aaOpcodeCounts || !this.aaOpcodeCounts.length) { + this.aaOpcodeCounts = new Array(256); + for (i = 0; i < this.aaOpcodeCounts.length; i++) { + this.aaOpcodeCounts[i] = [i, 0]; + } + } + }; + + /** + * runCPU(fUpdateFocus) + * + * @this {DebuggerPDP11} + * @param {boolean} [fUpdateFocus] is true to update focus + * @return {boolean} true if run request successful, false if not + */ + DebuggerPDP11.prototype.runCPU = function(fUpdateFocus) + { + if (!this.isCPUAvail()) return false; + this.cpu.runCPU(fUpdateFocus); + return true; + }; + + /** + * stepCPU(nCycles, fRegs, fUpdateCPU) + * + * @this {DebuggerPDP11} + * @param {number} nCycles (0 for one instruction without checking breakpoints) + * @param {boolean} [fRegs] is true to display registers after step (default is false) + * @param {boolean} [fUpdateCPU] is false to disable calls to updateCPU() (default is true) + * @return {boolean} + */ + DebuggerPDP11.prototype.stepCPU = function(nCycles, fRegs, fUpdateCPU) + { + if (!this.isCPUAvail()) return false; + + this.nCycles = 0; + + if (!nCycles) { + /* + * When single-stepping, the CPU won't call checkInstruction(), which is good for + * avoiding breakpoints, but bad for instruction data collection if checks are enabled. + * So we call checkInstruction() ourselves. + */ + if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0); + } + try { + var nCyclesStep = this.cpu.stepCPU(nCycles); + if (nCyclesStep > 0) { + this.nCycles += nCyclesStep; + this.cpu.addCycles(nCyclesStep, true); + this.cpu.updateChecksum(nCyclesStep); + this.cOpcodes++; + } + } + catch(exception) { + if (typeof exception != "number") { + var e = exception; + this.nCycles = 0; + this.cpu.setError(e.stack || e.message); + } + } + + /* + * Because we called cpu.stepCPU() and not cpu.runCPU(), we must nudge the cpu's update code, + * and then update our own state. Normally, the only time fUpdateCPU will be false is when doTrace() + * is calling us in a loop, in which case it will perform its own updateCPU() when it's done. + */ + if (fUpdateCPU !== false) this.cpu.updateCPU(); + + this.updateStatus(fRegs || false); + return (this.nCycles > 0); + }; + + /** + * stopCPU() + * + * @this {DebuggerPDP11} + * @param {boolean} [fComplete] + */ + DebuggerPDP11.prototype.stopCPU = function(fComplete) + { + if (this.cpu) this.cpu.stopCPU(fComplete); + }; + + /** + * updateStatus(fRegs) + * + * @this {DebuggerPDP11} + * @param {boolean} [fRegs] (default is true) + */ + DebuggerPDP11.prototype.updateStatus = function(fRegs) + { + if (fRegs === undefined) fRegs = true; + + this.dbgAddrNextCode = this.newAddr(this.cpu.getPC()); + /* + * this.nStep used to be a simple boolean, but now it's 0 (or undefined) + * if inactive, 1 if stepping over an instruction without a register dump, or 2 + * if stepping over an instruction with a register dump. + */ + if (!fRegs || this.nStep == 1) + this.doUnassemble(); + else { + this.doRegisters(); + } + }; + + /** + * isCPUAvail() + * + * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state. + * + * @this {DebuggerPDP11} + * @return {boolean} + */ + DebuggerPDP11.prototype.isCPUAvail = function() + { + if (!this.cpu) + return false; + if (!this.cpu.isReady()) + return false; + if (!this.cpu.isPowered()) + return false; + if (this.cpu.isBusy()) + return false; + return !this.cpu.isError(); + }; + + /** + * powerUp(data, fRepower) + * + * @this {DebuggerPDP11} + * @param {Object|null} data + * @param {boolean} [fRepower] + * @return {boolean} true if successful, false if failure + */ + DebuggerPDP11.prototype.powerUp = function(data, fRepower) + { + if (!fRepower) { + /* + * Because Debugger save/restore support is somewhat limited (and didn't always exist), + * we deviate from the typical save/restore design pattern: instead of reset OR restore, + * we always reset and then perform a (potentially limited) restore. + */ + this.reset(true); + + // this.println(data? "resuming" : "powering up"); + + if (data && this.restore) { + if (!this.restore(data)) return false; + } + } + return true; + }; + + /** + * powerDown(fSave, fShutdown) + * + * @this {DebuggerPDP11} + * @param {boolean} [fSave] + * @param {boolean} [fShutdown] + * @return {Object|boolean} + */ + DebuggerPDP11.prototype.powerDown = function(fSave, fShutdown) + { + if (fShutdown) this.println(fSave? "suspending" : "shutting down"); + return fSave? this.save() : true; + }; + + /** + * reset(fQuiet) + * + * This is a notification handler, called by the Computer, to inform us of a reset. + * + * @this {DebuggerPDP11} + * @param {boolean} fQuiet (true only when called from our own powerUp handler) + */ + DebuggerPDP11.prototype.reset = function(fQuiet) + { + this.historyInit(); + this.cOpcodes = this.cOpcodesStart = 0; + this.sMessagePrev = null; + this.nCycles = 0; + this.dbgAddrNextCode = this.newAddr(this.cpu.getPC()); + /* + * fRunning is set by start() and cleared by stop(). In addition, we clear + * it here, so that if the CPU is reset while running, we can prevent stop() + * from unnecessarily dumping the CPU state. + */ + this.flags.fRunning = false; + this.clearTempBreakpoint(); + if (!fQuiet) this.updateStatus(); + }; + + /** + * save() + * + * This implements (very rudimentary) save support for the Debugger component. + * + * @this {DebuggerPDP11} + * @return {Object} + */ + DebuggerPDP11.prototype.save = function() + { + var state = new State(this); + state.set(0, this.packAddr(this.dbgAddrNextCode)); + state.set(1, this.packAddr(this.dbgAddrAssemble)); + state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessage]); + state.set(3, this.aSymbolTable); + return state.data(); + }; + + /** + * restore(data) + * + * This implements (very rudimentary) restore support for the Debugger component. + * + * @this {DebuggerPDP11} + * @param {Object} data + * @return {boolean} true if successful, false if failure + */ + DebuggerPDP11.prototype.restore = function(data) + { + var i = 0; + if (data[2] !== undefined) { + this.dbgAddrNextCode = this.unpackAddr(data[i++]); + this.dbgAddrAssemble = this.unpackAddr(data[i++]); + this.aPrevCmds = data[i][0]; + if (typeof this.aPrevCmds == "string") this.aPrevCmds = [this.aPrevCmds]; + this.fAssemble = data[i][1]; + this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply "add" any extra bits defined by the saved state + } + if (data[3]) this.aSymbolTable = data[3]; + return true; + }; + + /** + * start(ms, nCycles) + * + * This is a notification handler, called by the Computer, to inform us the CPU has started. + * + * @this {DebuggerPDP11} + * @param {number} ms + * @param {number} nCycles + */ + DebuggerPDP11.prototype.start = function(ms, nCycles) + { + if (!this.nStep) this.println("running"); + this.flags.fRunning = true; + this.msStart = ms; + this.nCyclesStart = nCycles; + }; + + /** + * stop(ms, nCycles) + * + * This is a notification handler, called by the Computer, to inform us the CPU has now stopped. + * + * @this {DebuggerPDP11} + * @param {number} ms + * @param {number} nCycles + */ + DebuggerPDP11.prototype.stop = function(ms, nCycles) + { + if (this.flags.fRunning) { + this.flags.fRunning = false; + this.nCycles = nCycles - this.nCyclesStart; + if (!this.nStep) { + var sStopped = "stopped"; + if (this.nCycles) { + var msTotal = ms - this.msStart; + var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0); + sStopped += " ("; + if (this.checksEnabled()) { + sStopped += this.cOpcodes + " opcodes, "; + /* + * $ops displays progress by calculating cOpcodes - cOpcodesStart, so before + * zeroing cOpcodes, we should subtract cOpcodes from cOpcodesStart (since we're + * effectively subtracting cOpcodes from cOpcodes as well). + */ + this.cOpcodesStart -= this.cOpcodes; + this.cOpcodes = 0; + } + sStopped += this.nCycles + " cycles, " + msTotal + " ms, " + nCyclesPerSecond + " hz)"; + } else { + if (this.messageEnabled(MessagesPDP11.HALT)) { + /* + * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault() + * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful + * message (another helpful tip would be to simply turn off the "halt" message category). + */ + sStopped += " (use the 't' command to execute blocked faults)"; + } + } + this.println(sStopped); + } + this.updateStatus(true); + this.updateFocus(); + this.clearTempBreakpoint(this.cpu.getPC()); + } + }; + + /** + * checksEnabled(fRelease) + * + * This "check" function is called by the CPU; we indicate whether or not every instruction needs to be checked. + * + * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints + * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate + * "checked" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've + * simplified the test below. + * + * @this {DebuggerPDP11} + * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria) + * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not + */ + DebuggerPDP11.prototype.checksEnabled = function(fRelease) + { + return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakIns)); + }; + + /** + * checkInstruction(addr, nState) + * + * This "check" function is called by the CPU to inform us about the next instruction to be executed, + * giving us an opportunity to look for "exec" breakpoints and update opcode frequencies and instruction history. + * + * @this {DebuggerPDP11} + * @param {number} addr + * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running + * @return {boolean} true if breakpoint hit, false if not + */ + DebuggerPDP11.prototype.checkInstruction = function(addr, nState) + { + var cpu = this.cpu; + + if (nState > 0) { + if (this.nBreakIns && !--this.nBreakIns) { + return true; + } + if (this.checkBreakpoint(addr, 1, this.aBreakExec)) { + return true; + } + } + + /* + * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the + * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than + * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction(); + * well, OK, and a few other things now, like enabling MessagesPDP11.INT messages. + */ + if (nState >= 0 && this.aaOpcodeCounts.length) { + this.cOpcodes++; + var bOpcode = this.bus.getByteDirect(addr); + if (bOpcode != null) { + this.aaOpcodeCounts[bOpcode][1]++; + var dbgAddr = this.aOpcodeHistory[this.iOpcodeHistory]; + this.setAddr(dbgAddr, cpu.getPC()); + if (DEBUG) dbgAddr.cycleCount = cpu.getCycles(); + if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0; + } + } + return false; + }; + + /** + * checkMemoryRead(addr, nb) + * + * This "check" function is called by a Memory block to inform us that a memory read occurred, giving us an + * opportunity to track the read if we want, and look for a matching "read" breakpoint, if any. + * + * In the "old days", it would be an error for this call to fail to find a matching Debugger breakpoint, but now + * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this "checked" read. + * + * If we return true, we "trump" the machine's Debug register(s); false allows normal Debug register processing. + * + * @this {DebuggerPDP11} + * @param {number} addr + * @param {number} [nb] (# of bytes; default is 1) + * @return {boolean} true if breakpoint hit, false if not + */ + DebuggerPDP11.prototype.checkMemoryRead = function(addr, nb) + { + if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) { + this.stopCPU(true); + return true; + } + return false; + }; + + /** + * checkMemoryWrite(addr, nb) + * + * This "check" function is called by a Memory block to inform us that a memory write occurred, giving us an + * opportunity to track the write if we want, and look for a matching "write" breakpoint, if any. + * + * In the "old days", it would be an error for this call to fail to find a matching Debugger breakpoint, but now + * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this "checked" write. + * + * If we return true, we "trump" the machine's Debug register(s); false allows normal Debug register processing. + * + * @this {DebuggerPDP11} + * @param {number} addr + * @param {number} [nb] (# of bytes; default is 1) + * @return {boolean} true if breakpoint hit, false if not + */ + DebuggerPDP11.prototype.checkMemoryWrite = function(addr, nb) + { + if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) { + this.stopCPU(true); + return true; + } + return false; + }; + + /** + * clearBreakpoints() + * + * @this {DebuggerPDP11} + */ + DebuggerPDP11.prototype.clearBreakpoints = function() + { + var i, dbgAddr; + this.aBreakExec = ["bp"]; + if (this.aBreakRead !== undefined) { + for (i = 1; i < this.aBreakRead.length; i++) { + dbgAddr = this.aBreakRead[i]; + this.bus.removeMemBreak(this.getAddr(dbgAddr), false); + } + } + this.aBreakRead = ["br"]; + if (this.aBreakWrite !== undefined) { + for (i = 1; i < this.aBreakWrite.length; i++) { + dbgAddr = this.aBreakWrite[i]; + this.bus.removeMemBreak(this.getAddr(dbgAddr), true); + } + } + this.aBreakWrite = ["bw"]; + /* + * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup requires + * reading a segment descriptor via getSegment(), and that triggers more memory reads, which triggers + * more breakpoint checks. + */ + this.nSuppressBreaks = 0; + }; + + /** + * addBreakpoint(aBreak, dbgAddr, fTemporary) + * + * In case you haven't already figured this out, all our breakpoint commands use the address + * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers; + * see doBreak() for details. + * + * This has a few implications, one being that you CANNOT set more than one kind of breakpoint + * on a single address. In practice, that's rarely a problem, because you can almost always set + * a different breakpoint on a neighboring address. + * + * Also, there is one exception to the "one address, one breakpoint" rule, and that involves + * temporary breakpoints (ie, one-time execution breakpoints that either a "p" or "g" command + * may create to step over a chunk of code). Those breakpoints automatically clear themselves, + * so there usually isn't any need to refer to them using breakpoint commands. + * + * TODO: Consider supporting the more "traditional" breakpoint index syntax; the current + * address-based syntax was implemented solely for expediency and consistency. At the same time, + * also consider a more WDEB386-like syntax, where "br" is used to set a variety of access-specific + * breakpoints, using modifiers like "r1", "r2", "w1", "w2, etc. + * + * @this {DebuggerPDP11} + * @param {Array} aBreak + * @param {DbgAddrPDP11} dbgAddr + * @param {boolean} [fTemporary] + * @return {boolean} true if breakpoint added, false if already exists + */ + DebuggerPDP11.prototype.addBreakpoint = function(aBreak, dbgAddr, fTemporary) + { + var fSuccess = true; + + // this.nSuppressBreaks++; + + /* + * Instead of complaining that a breakpoint already exists (as we used to do), we now + * allow breakpoints to be re-set; this makes it easier to update any commands that may + * be associated with the breakpoint. + * + * The only exception: we DO allow a temporary breakpoint at an address where there may + * already be a breakpoint, so that you can easily step ("p" or "g") over such addresses. + */ + if (!fTemporary) { + this.findBreakpoint(aBreak, dbgAddr, true, false, true); + } + + if (aBreak != this.aBreakExec) { + var addr = this.getAddr(dbgAddr); + if (addr === CPUDefPDP11.ADDR_INVALID) { + this.println("invalid address: " + this.toHexAddr(dbgAddr)); + fSuccess = false; + } else { + this.bus.addMemBreak(addr, aBreak == this.aBreakWrite); + } + } + + if (fSuccess) { + aBreak.push(dbgAddr); + if (fTemporary) { + dbgAddr.fTemporary = true; + } + else { + this.printBreakpoint(aBreak, aBreak.length-1, "set"); + this.historyInit(); + } + } + + // this.nSuppressBreaks--; + + return fSuccess; + }; + + /** + * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet) + * + * @this {DebuggerPDP11} + * @param {Array} aBreak + * @param {DbgAddrPDP11} dbgAddr + * @param {boolean} [fRemove] + * @param {boolean} [fTemporary] + * @param {boolean} [fQuiet] + * @return {boolean} true if found, false if not + */ + DebuggerPDP11.prototype.findBreakpoint = function(aBreak, dbgAddr, fRemove, fTemporary, fQuiet) + { + var fFound = false; + var addr = this.getAddr(dbgAddr); + for (var i = 1; i < aBreak.length; i++) { + var dbgAddrBreak = aBreak[i]; + if (addr == this.getAddr(dbgAddrBreak)) { + if (!fTemporary || dbgAddrBreak.fTemporary) { + fFound = true; + if (fRemove) { + if (!dbgAddrBreak.fTemporary && !fQuiet) { + this.printBreakpoint(aBreak, i, "cleared"); + } + aBreak.splice(i, 1); + if (aBreak != this.aBreakExec) { + this.bus.removeMemBreak(addr, aBreak == this.aBreakWrite); + } + /* + * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this + * was a temporary breakpoint. + */ + if (!dbgAddrBreak.fTemporary) { + this.historyInit(); + } + break; + } + if (!fQuiet) this.printBreakpoint(aBreak, i, "exists"); + break; + } + } + } + return fFound; + }; + + /** + * listBreakpoints(aBreak) + * + * @this {DebuggerPDP11} + * @param {Array} aBreak + * @return {number} of breakpoints listed, 0 if none + */ + DebuggerPDP11.prototype.listBreakpoints = function(aBreak) + { + for (var i = 1; i < aBreak.length; i++) { + this.printBreakpoint(aBreak, i); + } + return aBreak.length - 1; + }; + + /** + * printBreakpoint(aBreak, i, sAction) + * + * @this {DebuggerPDP11} + * @param {Array} aBreak + * @param {number} i + * @param {string} [sAction] + */ + DebuggerPDP11.prototype.printBreakpoint = function(aBreak, i, sAction) + { + var dbgAddr = aBreak[i]; + this.println(aBreak[0] + ' ' + this.toHexAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' "' + dbgAddr.sCmd + '"') : ''))); + }; + + /** + * setTempBreakpoint(dbgAddr) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr of new temp breakpoint + */ + DebuggerPDP11.prototype.setTempBreakpoint = function(dbgAddr) + { + this.addBreakpoint(this.aBreakExec, dbgAddr, true); + }; + + /** + * clearTempBreakpoint(addr) + * + * @this {DebuggerPDP11} + * @param {number|undefined} [addr] clear all temp breakpoints if no address specified + */ + DebuggerPDP11.prototype.clearTempBreakpoint = function(addr) + { + if (addr !== undefined) { + this.checkBreakpoint(addr, 1, this.aBreakExec, true); + this.nStep = 0; + } else { + for (var i = 1; i < this.aBreakExec.length; i++) { + var dbgAddrBreak = this.aBreakExec[i]; + if (dbgAddrBreak.fTemporary) { + if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break; + i = 0; + } + } + } + }; + + /** + * checkBreakpoint(addr, nb, aBreak, fTemporary) + * + * @this {DebuggerPDP11} + * @param {number} addr + * @param {number} nb (# of bytes) + * @param {Array} aBreak + * @param {boolean} [fTemporary] + * @return {boolean} true if breakpoint has been hit, false if not + */ + DebuggerPDP11.prototype.checkBreakpoint = function(addr, nb, aBreak, fTemporary) + { + /* + * Time to check for execution breakpoints; note that this should be done BEFORE updating frequency + * or history data (see checkInstruction), since we might not actually execute the current instruction. + */ + var fBreak = false; + + if (!this.nSuppressBreaks++) { + + for (var i = 1; !fBreak && i < aBreak.length; i++) { + + var dbgAddrBreak = aBreak[i]; + + if (fTemporary && !dbgAddrBreak.fTemporary) continue; + + /* + * We used to calculate the linear address of the breakpoint at the time the + * breakpoint was added, so that a breakpoint set in one mode (eg, in real-mode) + * would still work as intended if the mode changed later (eg, to protected-mode). + * + * However, that created difficulties setting protected-mode breakpoints in segments + * that might not be defined yet, or that could move in physical memory. + * + * If you want to create a real-mode breakpoint that will break regardless of mode, + * use the physical address of the real-mode memory location instead. + */ + var addrBreak = this.getAddr(dbgAddrBreak); + for (var n = 0; n < nb; n++) { + if (addr + n == addrBreak) { + var a; + fBreak = true; + if (dbgAddrBreak.fTemporary) { + this.findBreakpoint(aBreak, dbgAddrBreak, true, true); + fTemporary = true; + } + if (a = dbgAddrBreak.aCmds) { + /* + * When one or more commands are attached to a breakpoint, we don't halt by default. + * Instead, we set fBreak to true only if, at the completion of all the commands, the + * CPU is halted; in other words, you should include "h" as one of the breakpoint commands + * if you want the breakpoint to stop execution. + * + * Another useful command is "if", which will return false if the expression is false, + * at which point we'll jump ahead to the next "else" command, and if there isn't an "else", + * we abort. + */ + fBreak = false; + for (var j = 0; j < a.length; j++) { + if (!this.doCommand(a[j], true)) { + if (a[j].indexOf("if")) { + fBreak = true; // the failed command wasn't "if", so abort + break; + } + var k = j + 1; + for (; k < a.length; k++) { + if (!a[k].indexOf("else")) break; + j++; + } + if (k == a.length) { // couldn't find an "else" after the "if", so abort + fBreak = true; + break; + } + /* + * If we're still here, we'll execute the "else" command (which is just a no-op), + * followed by any remaining commands. + */ + } + } + if (!this.cpu.isRunning()) fBreak = true; + } + if (fBreak) { + if (!fTemporary) this.printBreakpoint(aBreak, i, "hit"); + break; + } + } + } + } + } + + this.nSuppressBreaks--; + + return fBreak; + }; + + /** + * getInstruction(dbgAddr, sComment, nSequence) + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {string} [sComment] is an associated comment + * @param {number} [nSequence] is an associated sequence number, undefined if none + * @return {string} (and dbgAddr is updated to the next instruction) + */ + DebuggerPDP11.prototype.getInstruction = function(dbgAddr, sComment, nSequence) + { + var dbgAddrIns = this.newAddr(dbgAddr.addr); + + var bOpcode = this.getByte(dbgAddr, 1); + + var asOpcodes = DebuggerPDP11.INS_NAMES; + var aOpDesc = this.aaOpDescs[bOpcode] || [DebuggerPDP11.INS.NONE]; + var iIns = aOpDesc[0]; + + var sOperands = ""; + var sOpcode = asOpcodes[iIns]; + var cOperands = aOpDesc.length - 1; + var typeSizeDefault = DebuggerPDP11.TYPE_NONE, type; + + for (var iOperand = 1; iOperand <= cOperands; iOperand++) { + + var disp, off, cch; + var sOperand = ""; + + type = aOpDesc[iOperand]; + if (type === undefined) continue; + + var typeMode = type & DebuggerPDP11.TYPE_MODE; + if (!typeMode) continue; + + var typeSize = type & DebuggerPDP11.TYPE_SIZE; + if (!typeSize) { + type |= typeSizeDefault; + } else { + typeSizeDefault = typeSize; + } + + var typeOther = type & DebuggerPDP11.TYPE_OTHER; + if (!typeOther) { + type |= (iOperand == 1? DebuggerPDP11.TYPE_OUT : DebuggerPDP11.TYPE_IN); + } + + if (typeMode & DebuggerPDP11.TYPE_IMM) { + sOperand = this.getImmOperand(type, dbgAddr); + } + else if (typeMode & DebuggerPDP11.TYPE_REG) { + sOperand = this.getRegOperand((type & DebuggerPDP11.TYPE_IREG) >> 8, type, dbgAddr); + } + else if (typeMode & DebuggerPDP11.TYPE_INT) { + sOperand = ((bOpcode >> 3) & 0x7).toString(); + } + + if (!sOperand || !sOperand.length) { + sOperands = "INVALID"; + break; + } + if (sOperands.length > 0) sOperands += ','; + sOperands += (sOperand || "???"); + } + + var sBytes = ""; + var sLine = this.toHexAddr(dbgAddrIns) + ' '; + if (dbgAddrIns.addr !== CPUDefPDP11.ADDR_INVALID && dbgAddr.addr !== CPUDefPDP11.ADDR_INVALID) { + do { + sBytes += str.toHex(this.getByte(dbgAddrIns, 1), 2); + if (dbgAddrIns.addr == null) break; + } while (dbgAddrIns.addr != dbgAddr.addr); + } + + sLine += str.pad(sBytes, 10); + sLine += (type & DebuggerPDP11.TYPE_UNDOC)? '*' : ' '; + sLine += str.pad(sOpcode, 7); + if (sOperands) sLine += ' ' + sOperands; + + if (sComment) { + sLine = str.pad(sLine, 40) + ';' + sComment; + if (!this.cpu.flags.fChecksum) { + sLine += (nSequence != null? '=' + nSequence.toString() : ""); + } else { + var nCycles = this.cpu.getCycles(); + sLine += "cycles=" + nCycles.toString() + " cs=" + str.toHex(this.cpu.nChecksum); + } + } + return sLine; + }; + + /** + * getImmOperand(type, dbgAddr) + * + * @this {DebuggerPDP11} + * @param {number} type + * @param {DbgAddrPDP11} dbgAddr + * @return {string} operand + */ + DebuggerPDP11.prototype.getImmOperand = function(type, dbgAddr) + { + var sOperand = ' '; + var typeSize = type & DebuggerPDP11.TYPE_SIZE; + + switch (typeSize) { + case DebuggerPDP11.TYPE_BYTE: + sOperand = str.toHex(this.getByte(dbgAddr, 1), 2); + break; + case DebuggerPDP11.TYPE_SBYTE: + sOperand = str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, 4); + break; + case DebuggerPDP11.TYPE_WORD: + sOperand = str.toHex(this.getShort(dbgAddr, 2), 4); + break; + default: + return "imm(" + str.toHexWord(type) + ')'; + } + if (type & DebuggerPDP11.TYPE_MEM) { + sOperand = '[' + sOperand + ']'; + } else if (!(type & DebuggerPDP11.TYPE_REG)) { + sOperand = "0x" + sOperand; + } + return sOperand; + }; + + /** + * getRegOperand(iReg, type, dbgAddr) + * + * @this {DebuggerPDP11} + * @param {number} iReg + * @param {number} type + * @param {DbgAddrPDP11} dbgAddr + * @return {string} operand + */ + DebuggerPDP11.prototype.getRegOperand = function(iReg, type, dbgAddr) + { + return DebuggerPDP11.REGS[iReg]; + }; + + /** + * parseInstruction(sOp, sOperand, addr) + * + * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a working implementation. + * + * @this {DebuggerPDP11} + * @param {string} sOp + * @param {string|undefined} sOperand + * @param {DbgAddrPDP11} dbgAddr of memory where this instruction is being assembled + * @return {Array.} of opcode bytes; if the instruction can't be parsed, the array will be empty + */ + DebuggerPDP11.prototype.parseInstruction = function(sOp, sOperand, dbgAddr) + { + var aOpBytes = []; + this.println("not supported yet"); + return aOpBytes; + }; + + /** + * getFlagOutput(sFlag) + * + * @this {DebuggerPDP11} + * @param {string} sFlag + * @return {string} value of flag + */ + DebuggerPDP11.prototype.getFlagOutput = function(sFlag) + { + var b; + switch (sFlag) { + case "IF": + b = this.cpu.getIF(); + break; + case "SF": + b = this.cpu.getSF(); + break; + case "ZF": + b = this.cpu.getZF(); + break; + case "CF": + b = this.cpu.getCF(); + break; + default: + b = 0; + break; + } + return sFlag.charAt(0) + (b? '1' : '0') + ' '; + }; + + /** + * getRegOutput(iReg) + * + * @this {DebuggerPDP11} + * @param {number} iReg + * @return {string} + */ + DebuggerPDP11.prototype.getRegOutput = function(iReg) + { + var sReg = DebuggerPDP11.REGS[iReg]; + return sReg + '=' + this.getRegString(iReg) + ' '; + }; + + /** + * getRegDump() + * + * @this {DebuggerPDP11} + * @return {string} + */ + DebuggerPDP11.prototype.getRegDump = function() + { + return "no regs"; + }; + + DebuggerPDP11.aBinOpPrecedence = { + '||': 0, // logical OR + '&&': 1, // logical AND + '|': 2, // bitwise OR + '^': 3, // bitwise XOR + '&': 4, // bitwise AND + '!=': 5, // inequality + '==': 5, // equality + '>=': 6, // greater than or equal to + '>': 6, // greater than + '<=': 6, // less than or equal to + '<': 6, // less than + '>>>': 7, // unsigned bitwise right shift + '>>': 7, // bitwise right shift + '<<': 7, // bitwise left shift + '-': 8, // subtraction + '+': 8, // addition + '%': 9, // remainder + '/': 9, // division + '*': 9 // multiplication + }; + + /** + * evalExpression(aVals, aOps, cOps) + * + * In Node, if you set a variable to 0x80000001; ie: + * + * foo=0x80000001|0 + * + * and then calculate foo*foo using "(foo*foo).toString(2)", the result is: + * + * '11111111111111111111111111111100000000000000000000000000000000' + * + * which is slightly incorrect because it has overflowed JavaScript's floating-point precision. + * + * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001. + * + * @this {DebuggerPDP11} + * @param {Array.} aVals + * @param {Array.} aOps + * @param {number} [cOps] (default is all) + * @return {boolean} true if successful, false if error + */ + DebuggerPDP11.prototype.evalExpression = function(aVals, aOps, cOps) + { + cOps = cOps || -1; + while (cOps-- && aOps.length) { + var chOp = aOps.pop(); + if (aVals.length < 2) return false; + var valNew; + var val2 = aVals.pop(); + var val1 = aVals.pop(); + switch(chOp) { + case '*': + valNew = val1 * val2; + break; + case '/': + if (!val2) return false; + valNew = val1 / val2; + break; + case '%': + if (!val2) return false; + valNew = val1 % val2; + break; + case '+': + valNew = val1 + val2; + break; + case '-': + valNew = val1 - val2; + break; + case '<<': + valNew = val1 << val2; + break; + case '>>': + valNew = val1 >> val2; + break; + case '>>>': + valNew = val1 >>> val2; + break; + case '<': + valNew = (val1 < val2? 1 : 0); + break; + case '<=': + valNew = (val1 <= val2? 1 : 0); + break; + case '>': + valNew = (val1 > val2? 1 : 0); + break; + case '>=': + valNew = (val1 >= val2? 1 : 0); + break; + case '==': + valNew = (val1 == val2? 1 : 0); + break; + case '!=': + valNew = (val1 != val2? 1 : 0); + break; + case '&': + valNew = val1 & val2; + break; + case '^': + valNew = val1 ^ val2; + break; + case '|': + valNew = val1 | val2; + break; + case '&&': + valNew = (val1 && val2? 1 : 0); + break; + case '||': + valNew = (val1 || val2? 1 : 0); + break; + default: + return false; + } + aVals.push(valNew|0); + } + return true; + }; + + /** + * parseExpression(sExp, fPrint) + * + * A quick-and-dirty expression parser. It takes an expression like: + * + * EDX+EDX*4+12345678 + * + * and builds a value stack in aVals and a "binop" (binary operator) stack in aOps: + * + * aVals aOps + * ----- ---- + * EDX + + * EDX * + * 4 + + * ... + * + * We pop 1 "binop" from aOps and 2 values from aVals whenever a "binop" of lower priority than its + * predecessor is encountered, evaluate, and push the result back onto aVals. + * + * Unary operators like '~' and ternary operators like '?:' are not supported; neither are parentheses. + * + * However, parseReference() now makes it possible to write parenthetical-style sub-expressions by using + * {...} (braces), as well as address references by using [...] (brackets). + * + * Why am I using braces instead of parentheses for sub-expressions? Because parseReference() serves + * multiple purposes, the other being reference replacement in message strings passing through replaceRegs(), + * and I didn't want parentheses taking on a new meaning in message strings. + * + * @this {DebuggerPDP11} + * @param {string|undefined} sExp + * @param {boolean} [fPrint] is true to print all resolved values, false for quiet parsing + * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values + */ + DebuggerPDP11.prototype.parseExpression = function(sExp, fPrint) + { + var value; + + if (sExp) { + /* + * First process (and eliminate) any references, aka sub-expressions. + */ + sExp = this.parseReference(sExp); + + var i = 0; + var fError = false; + var sExpOrig = sExp; + var aVals = [], aOps = []; + /* + * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a regexp split(): + * when the regexp uses a capturing pattern, the resulting array will include entries for all the pattern + * matches along with the non-matches. This effectively means that, in the set of expressions that we + * support, all even entries in asValues will contain "values" and all odd entries will contain "operators". + * + * And although I tried to list the supported operators in "precedential" order, bitwise operators must + * be out-of-order so that we don't mistakenly match either '>' or '<' when they're part of '>>' or '<<'. + */ + var regExp = /(\|\||&&|\||^|&|!=|==|>=|>>>|>>|>|<=|<<|<|-|\+|%|\/|\*)/; + var asValues = sExp.split(regExp); + while (i < asValues.length) { + var sValue = asValues[i++]; + var cchValue = sValue.length; + var s = str.trim(sValue); + if (!s) { + fError = true; + break; + } + var v = this.parseValue(s, null, fPrint === false); + if (v === undefined) { + fError = true; + fPrint = false; + break; + } + aVals.push(v); + if (i == asValues.length) break; + var sOp = asValues[i++], cchOp = sOp.length; + this.assert(DebuggerPDP11.aBinOpPrecedence[sOp] != null); + if (aOps.length && DebuggerPDP11.aBinOpPrecedence[sOp] < DebuggerPDP11.aBinOpPrecedence[aOps[aOps.length-1]]) { + this.evalExpression(aVals, aOps, 1); + } + aOps.push(sOp); + sExp = sExp.substr(cchValue + cchOp); + } + if (!this.evalExpression(aVals, aOps) || aVals.length != 1) { + fError = true; + } + if (!fError) { + value = aVals.pop(); + if (fPrint) this.printValue(null, value); + } else { + if (fPrint) this.println("error parsing '" + sExpOrig + "' at character " + (sExpOrig.length - sExp.length)); + } + } + return value; + }; + + /** + * parseReference(s) + * + * Returns the given string with any "{expression}" sequences replaced with the value of the expression, + * and any "[address]" references replaced with the contents of the address. Expressions are parsed BEFORE + * addresses. Owing to this function's simplistic parsing, nested braces/brackets are not supported + * (define intermediate variables if needed). + * + * @this {DebuggerPDP11} + * @param {string} s + * @return {string} + */ + DebuggerPDP11.prototype.parseReference = function(s) + { + var a; + while (a = s.match(/\{(.*?)}/)) { + if (a[1].indexOf('{') >= 0) break; // unsupported nested brace(s) + var value = this.parseExpression(a[1]); + s = s.replace('{' + a[1] + '}', value != null? str.toHex(value) : "undefined"); + } + while (a = s.match(/\[(.*?)]/)) { + if (a[1].indexOf('[') >= 0) break; // unsupported nested bracket(s) + var dbgAddr = this.parseAddr(a[1]); + s = s.replace('[' + a[1] + ']', dbgAddr? str.toHex(this.getWord(dbgAddr), 4) : "undefined"); + } + return this.parseSysVars(s); + }; + + /** + * parseSysVars(s) + * + * Returns the given string with any recognized "$var" replaced with its value; eg: + * + * $ops: the number of opcodes executed since the last time it was displayed (or reset) + * + * @this {DebuggerPDP11} + * @param {string} s + * @return {string} + */ + DebuggerPDP11.prototype.parseSysVars = function(s) + { + var a; + while (a = s.match(/\$([a-z]+)/i)) { + var v = null; + switch(a[1].toLowerCase()) { + case "ops": + v = this.cOpcodes - this.cOpcodesStart; + break; + } + if (v == null) break; + s = s.replace(a[0], v.toString()); + } + return s; + }; + + /** + * parseValue(sValue, sName, fQuiet) + * + * @this {DebuggerPDP11} + * @param {string|undefined} sValue + * @param {string|null} [sName] is the name of the value, if any + * @param {boolean} [fQuiet] + * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid + */ + DebuggerPDP11.prototype.parseValue = function(sValue, sName, fQuiet) + { + var value; + if (sValue !== undefined) { + var iReg = this.getRegIndex(sValue); + if (iReg >= 0) { + value = this.getRegValue(iReg); + } else { + value = this.getVariable(sValue); + if (value === undefined) value = str.parseInt(sValue); + } + if (value === undefined && !fQuiet) this.println("invalid " + (sName? sName : "value") + ": " + sValue); + } else { + if (!fQuiet) this.println("missing " + (sName || "value")); + } + return value; + }; + + /** + * printValue(sVar, value) + * + * @this {DebuggerPDP11} + * @param {string|null} sVar + * @param {number|undefined} value + * @return {boolean} true if value defined, false if not + */ + DebuggerPDP11.prototype.printValue = function(sVar, value) + { + var sValue; + var fDefined = false; + if (value !== undefined) { + fDefined = true; + sValue = str.toHexLong(value) + " " + value + ". (" + str.toBinBytes(value) + ")"; + } + sVar = (sVar != null? (sVar + ": ") : ""); + this.println(sVar + sValue); + return fDefined; + }; + + /** + * printVariable(sVar) + * + * @this {DebuggerPDP11} + * @param {string} [sVar] + * @return {boolean} true if all value(s) defined, false if not + */ + DebuggerPDP11.prototype.printVariable = function(sVar) + { + if (sVar) { + return this.printValue(sVar, this.aVariables[sVar]); + } + var cVariables = 0; + for (sVar in this.aVariables) { + this.printValue(sVar, this.aVariables[sVar]); + cVariables++; + } + return cVariables > 0; + }; + + /** + * delVariable(sVar) + * + * @this {DebuggerPDP11} + * @param {string} sVar + */ + DebuggerPDP11.prototype.delVariable = function(sVar) + { + delete this.aVariables[sVar]; + }; + + /** + * getVariable(sVar) + * + * @this {DebuggerPDP11} + * @param {string} sVar + * @return {number|undefined} + */ + DebuggerPDP11.prototype.getVariable = function(sVar) + { + return this.aVariables[sVar]; + }; + + /** + * setVariable(sVar, value) + * + * @this {DebuggerPDP11} + * @param {string} sVar + * @param {number} value + */ + DebuggerPDP11.prototype.setVariable = function(sVar, value) + { + this.aVariables[sVar] = value; + }; + + /** + * comparePairs(p1, p2) + * + * @this {DebuggerPDP11} + * @param {number|string|Array|Object} p1 + * @param {number|string|Array|Object} p2 + * @return {number} + */ + DebuggerPDP11.prototype.comparePairs = function(p1, p2) + { + return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0; + }; + + /** + * addSymbols(sModule, addr, len, aSymbols) + * + * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist + * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of + * the following properties: + * + * 'v': the value of an absolute (unsized) value + * 'b': either 1, 2, 4 or undefined if an unsized value + * 's': either a hard-coded segment or undefined + * 'o': the offset of the symbol within the associated address space + * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case + * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment + * + * To that list of properties, we also add: + * + * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined) + * + * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values + * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original + * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for + * converting them back to individual double-quotes. + * + * For example: + * { + * 'HF_PORT': { + * 'v':800 + * }, + * 'HDISK_INT': { + * 'b':4, 's':0, 'o':52 + * }, + * 'ORG_VECTOR': { + * 'b':4, 's':0, 'o':76 + * }, + * 'CMD_BLOCK': { + * 'b':1, 's':64, 'o':66 + * }, + * 'DISK_SETUP': { + * 'o':3 + * }, + * '.40': { + * 'o':40, 'a':"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR" + * } + * } + * + * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly: + * + * 'DISK_SETUP': 3 + * + * The last property is an example of an "anonymous" entry, for offsets where there is no associated symbol. + * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and + * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading + * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols. + * + * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which + * look like: + * + * [addr, len, aSymbols, aOffsets] + * + * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any, + * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous + * symbol with a matching offset ('o') property. + * + * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs + * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space. + * + * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert(); + * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're + * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates + * properly. + * + * @this {DebuggerPDP11} + * @param {string|null} sModule + * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM) + * @param {number} len (the size of the region, in bytes) + * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below) + */ + DebuggerPDP11.prototype.addSymbols = function(sModule, addr, len, aSymbols) + { + var dbgAddr = {}; + var aOffsets = []; + for (var sSymbol in aSymbols) { + var symbol = aSymbols[sSymbol]; + if (typeof symbol == "number") { + aSymbols[sSymbol] = symbol = {'o': symbol}; + } + var offSymbol = symbol['o']; + var sAnnotation = symbol['a']; + if (offSymbol !== undefined) { + usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs); + } + if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, "\""); + } + var symbolTable = { + sModule: sModule, + addr: addr, + len: len, + aSymbols: aSymbols, + aOffsets: aOffsets + }; + this.aSymbolTable.push(symbolTable); + }; + + /** + * dumpSymbols() + * + * TODO: Add "numerical" and "alphabetical" dump options. This is simply dumping them in whatever + * order they appeared in the original MAP file. + * + * @this {DebuggerPDP11} + */ + DebuggerPDP11.prototype.dumpSymbols = function() + { + for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) { + var symbolTable = this.aSymbolTable[iTable]; + for (var sSymbol in symbolTable.aSymbols) { + if (sSymbol.charAt(0) == '.') continue; + var symbol = symbolTable.aSymbols[sSymbol]; + var offSymbol = symbol['o']; + if (offSymbol === undefined) continue; + var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l']; + if (sSymbolOrig) sSymbol = sSymbolOrig; + this.println(this.toHexOffset(offSymbol) + ' ' + sSymbol); + } + } + }; + + /** + * findSymbol(dbgAddr, fNearest) + * + * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found). + * + * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of + * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol. + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @param {boolean} [fNearest] + * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment + */ + DebuggerPDP11.prototype.findSymbol = function(dbgAddr, fNearest) + { + var aSymbol = []; + var addrSymbol = this.getAddr(dbgAddr) >>> 0; + for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) { + var symbolTable = this.aSymbolTable[iTable]; + var addr = symbolTable.addr >>> 0; + var len = symbolTable.len; + if (addrSymbol >= addr && addrSymbol < addr + len) { + var offSymbol = addrSymbol - addr; + var result = usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs); + if (result >= 0) { + this.returnSymbol(iTable, result, aSymbol); + } + else if (fNearest) { + result = ~result; + this.returnSymbol(iTable, result-1, aSymbol); + this.returnSymbol(iTable, result, aSymbol); + } + break; + } + } + return aSymbol; + }; + + /** + * findSymbolAddr(sSymbol) + * + * Search aSymbolTable for sSymbol, and if found, return a dbgAddr (same as parseAddr()) + * + * @this {DebuggerPDP11} + * @param {string} sSymbol + * @return {DbgAddrPDP11|undefined} + */ + DebuggerPDP11.prototype.findSymbolAddr = function(sSymbol) + { + var dbgAddr; + if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) { + var sUpperCase = sSymbol.toUpperCase(); + for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) { + var symbolTable = this.aSymbolTable[iTable]; + var symbol = symbolTable.aSymbols[sUpperCase]; + if (symbol !== undefined) { + var offSymbol = symbol['o']; + if (offSymbol !== undefined) { + /* + * We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an + * explicitly-defined segment, we return the segment associated with the entire group; for + * a ROM, that segment is normally "addrROM >>> 4". Down the road, we may want/need to + * support a special symbol entry (eg, ".ORG") that defines an alternate origin. + */ + dbgAddr = this.newAddr(offSymbol); + } + /* + * The symbol matched, but it wasn't for an address (no 'o' offset), and there's no point + * looking any farther, since each symbol appears only once, so we indicate it's an unknown symbol. + */ + break; + } + } + } + return dbgAddr; + }; + + /** + * returnSymbol(iTable, iOffset, aSymbol) + * + * Helper function for findSymbol(). + * + * @param {number} iTable + * @param {number} iOffset + * @param {Array} aSymbol is updated with the specified symbol, if it exists + */ + DebuggerPDP11.prototype.returnSymbol = function(iTable, iOffset, aSymbol) + { + var symbol = {}; + var aOffsets = this.aSymbolTable[iTable].aOffsets; + var offset = 0, sSymbol = null; + if (iOffset >= 0 && iOffset < aOffsets.length) { + offset = aOffsets[iOffset][0]; + sSymbol = aOffsets[iOffset][1]; + } + if (sSymbol) { + symbol = this.aSymbolTable[iTable].aSymbols[sSymbol]; + sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol)); + } + aSymbol.push(sSymbol); + aSymbol.push(offset); + aSymbol.push(symbol['a']); + aSymbol.push(symbol['c']); + }; + + /** + * doHelp() + * + * @this {DebuggerPDP11} + */ + DebuggerPDP11.prototype.doHelp = function() + { + var s = "commands:"; + for (var sCommand in DebuggerPDP11.COMMANDS) { + s += '\n' + str.pad(sCommand, 9) + DebuggerPDP11.COMMANDS[sCommand]; + } + if (!this.checksEnabled()) s += "\nnote: frequency/history disabled if no exec breakpoints"; + this.println(s); + }; + + /** + * doAssemble(asArgs) + * + * This always receives the complete argument array, where the order of the arguments is: + * + * [0]: the assemble command (assumed to be "a") + * [1]: the target address (eg, "200") + * [2]: the operation code, aka instruction name (eg, "adc") + * [3]: the operation mode operand, if any (eg, "14", "[1234]", etc) + * + * The Debugger enters "assemble mode" whenever only the first (or first and second) arguments are present. + * As long as "assemble mode is active, the user can omit the first two arguments on all later assemble commands + * until "assemble mode" is cancelled with an empty command line; the command processor automatically prepends "a" + * and the next available target address to the argument array. + * + * Entering "assemble mode" is optional; one could enter a series of fully-qualified assemble commands; eg: + * + * a ff00 cld + * a ff01 ldx 28 + * ... + * + * without ever entering "assemble mode", but of course, that requires more typing and doesn't take advantage + * of automatic target address advancement (see dbgAddrAssemble). + * + * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space; + * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU. + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs is the complete argument array, beginning with the "a" command in asArgs[0] + */ + DebuggerPDP11.prototype.doAssemble = function(asArgs) + { + var dbgAddr = this.parseAddr(asArgs[1], true); + if (!dbgAddr) return; + + this.dbgAddrAssemble = dbgAddr; + if (asArgs[2] === undefined) { + this.println("begin assemble at " + this.toHexAddr(dbgAddr)); + this.fAssemble = true; + this.cpu.updateCPU(); + return; + } + + var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr); + if (aOpBytes.length) { + for (var i = 0; i < aOpBytes.length; i++) { + this.setByte(dbgAddr, aOpBytes[i], 1); + } + /* + * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced. + */ + this.println(this.getInstruction(this.dbgAddrAssemble)); + } + }; + + /** + * doBreak(sCmd, sAddr, sOptions) + * + * As the "help" output below indicates, the following breakpoint commands are supported: + * + * bp [a] set exec breakpoint on linear addr [a] + * br [a] set read breakpoint on linear addr [a] + * bw [a] set write breakpoint on linear addr [a] + * bc [a] clear breakpoint on linear addr [a] (use "*" for all breakpoints) + * bl list breakpoints + * + * to which we have recently added the following I/O breakpoint commands: + * + * bi [p] toggle input breakpoint on port [p] (use "*" for all input ports) + * bo [p] toggle output breakpoint on port [p] (use "*" for all output ports) + * + * These two new commands operate as toggles so that if "*" is used to trap all input (or output), + * you can also use these commands to NOT trap specific ports. + * + * bn [n] break after [n] instructions + * + * TODO: Update the "bl" command to include any/all I/O breakpoints, and the "bc" command to + * clear them. Because "bi" and "bo" commands are piggy-backing on Bus functions, those breakpoints + * are currently outside the realm of what the "bl" and "bc" commands are aware of. + * + * @this {DebuggerPDP11} + * @param {string} sCmd + * @param {string|undefined} [sAddr] + * @param {string} [sOptions] (the rest of the breakpoint command-line) + */ + DebuggerPDP11.prototype.doBreak = function(sCmd, sAddr, sOptions) + { + if (sAddr == '?') { + this.println("breakpoint commands:"); + this.println("\tbp [a]\tset exec breakpoint at addr [a]"); + this.println("\tbr [a]\tset read breakpoint at addr [a]"); + this.println("\tbw [a]\tset write breakpoint at addr [a]"); + this.println("\tbc [a]\tclear breakpoint at addr [a]"); + this.println("\tbl\tlist all breakpoints"); + this.println("\tbn [n]\tbreak after [n] instruction(s)"); + return; + } + + var sParm = sCmd.charAt(1); + if (sParm == 'l') { + var cBreaks = 0; + cBreaks += this.listBreakpoints(this.aBreakExec); + cBreaks += this.listBreakpoints(this.aBreakRead); + cBreaks += this.listBreakpoints(this.aBreakWrite); + if (!cBreaks) this.println("no breakpoints"); + return; + } + + if (sParm == 'n') { + this.nBreakIns = this.parseValue(sAddr); + this.println("break after " + this.nBreakIns + " instruction(s)"); + return; + } + + if (sAddr === undefined) { + this.println("missing breakpoint address"); + return; + } + + var dbgAddr = this.newAddr(); + if (sAddr != '*') { + dbgAddr = this.parseAddr(sAddr, true, true); + if (!dbgAddr) return; + } + + if (sParm == 'c') { + if (dbgAddr.addr == null) { + this.clearBreakpoints(); + this.println("all breakpoints cleared"); + return; + } + if (this.findBreakpoint(this.aBreakExec, dbgAddr, true)) + return; + if (this.findBreakpoint(this.aBreakRead, dbgAddr, true)) + return; + if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true)) + return; + this.println("breakpoint missing: " + this.toHexAddr(dbgAddr)); + return; + } + + if (dbgAddr.addr == null) return; + + this.parseAddrOptions(dbgAddr, sOptions); + + if (sParm == 'p') { + this.addBreakpoint(this.aBreakExec, dbgAddr); + return; + } + if (sParm == 'r') { + this.addBreakpoint(this.aBreakRead, dbgAddr); + return; + } + if (sParm == 'w') { + this.addBreakpoint(this.aBreakWrite, dbgAddr); + return; + } + this.println("unknown breakpoint command: " + sParm); + }; + + /** + * doClear(sCmd) + * + * @this {DebuggerPDP11} + * @param {string} [sCmd] (eg, "cls" or "clear") + */ + DebuggerPDP11.prototype.doClear = function(sCmd) + { + /* + * TODO: There should be a clear() component method that the Control Panel overrides to perform this function. + */ + if (this.controlPrint) this.controlPrint.value = ""; + }; + + /** + * doDump(asArgs) + * + * The length parameter is interpreted as a number of bytes, in hex, which we convert to the appropriate number + * of lines, because we always display whole lines. If the length is omitted/undefined, it defaults to 0x80 (128.) + * bytes, which normally translates to 8 lines. + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes]) + */ + DebuggerPDP11.prototype.doDump = function(asArgs) + { + var m; + var sCmd = asArgs[0]; + var sAddr = asArgs[1]; + var sLen = asArgs[2]; + var sBytes = asArgs[3]; + + if (sAddr == '?') { + var sDumpers = ""; + for (m in MessagesPDP11.CATEGORIES) { + if (this.afnDumpers[m]) { + if (sDumpers) sDumpers += ','; + sDumpers = sDumpers + m; + } + } + sDumpers += ",state,symbols"; + this.println("dump memory commands:"); + this.println("\tdb [a] [#] dump # bytes at address a"); + this.println("\tdw [a] [#] dump # words at address a"); + this.println("\tdd [a] [#] dump # dwords at address a"); + this.println("\tdh [#] [#] dump # instructions from history"); + if (sDumpers.length) this.println("dump extension commands:\n\t" + sDumpers); + return; + } + + if (sAddr == "state") { + var sState = this.cmp.powerOff(true); + if (sLen == "console") { + /* + * Console buffers are notoriously small, and even the following code, which breaks the + * data into parts (eg, "d state console 1", "d state console 2", etc) just isn't that helpful. + * + * var nPart = +sBytes; + * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000); + * + * So, the best way to capture a large machine state is to use the new "Save Machine" link + * that downloads a machine's entire state. Alternatively, run your own local server and use + * server-side storage. Take a look at the "Save" binding in computer.js, which binds an HTML + * control to the computer.powerOff() and computer.saveServerState() functions. + */ + console.log(sState); + } else { + this.doClear(); + this.println(sState); + } + return; + } + + if (sAddr == "symbols") { + this.dumpSymbols(); + return; + } + + if (sCmd == "d") { + for (m in MessagesPDP11.CATEGORIES) { + if (asArgs[1] == m) { + var fnDumper = this.afnDumpers[m]; + if (fnDumper) { + asArgs.shift(); + asArgs.shift(); + fnDumper(asArgs); + } else { + this.println("no dump registered for " + sAddr); + } + return; + } + } + if (!sAddr) sCmd = this.sCmdDumpPrev || "db"; + } else { + this.sCmdDumpPrev = sCmd; + } + + if (sCmd == "dh") { + this.dumpHistory(sAddr, sLen); + return; + } + + var dbgAddr = this.parseAddr(sAddr); + if (!dbgAddr) return; + + var len = 0; // 0 is not a default; it triggers the appropriate default below + if (sLen) { + if (sLen.charAt(0) == 'l') { + sLen = sLen.substr(1) || sBytes; + } + len = this.parseValue(sLen) >>> 0; // negative lengths not allowed + if (len > 0x10000) len = 0x10000; // prevent bad user (or variable) input from producing excessive output + } + + var sDump = ""; + var size = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1)); + var cb = (size * len) || 128; + var cLines = ((cb + 15) >> 4) || 1; + + while (cLines-- && cb > 0) { + var data = 0, iByte = 0, i; + var sData = "", sChars = ""; + sAddr = this.toHexAddr(dbgAddr); + for (i = 16; i > 0 && cb > 0; i--) { + var b = this.getByte(dbgAddr, 1); + data |= (b << (iByte++ << 3)); + if (iByte == size) { + sData += str.toHex(data, size * 2); + sData += (size == 1? (i == 9? '-' : ' ') : " "); + data = iByte = 0; + } + sChars += (b >= 32 && b < 128? String.fromCharCode(b) : '.'); + cb--; + } + if (sDump) sDump += '\n'; + sDump += sAddr + " " + sData + ((i == 0)? (' ' + sChars) : ""); + } + + if (sDump) this.println(sDump); + this.dbgAddrNextData = dbgAddr; + }; + + /** + * doEdit(asArgs) + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs + */ + DebuggerPDP11.prototype.doEdit = function(asArgs) + { + var size = 1; + var mask = 0xff; + var fnGet = this.getByte; + var fnSet = this.setByte; + if (asArgs[0] == "ew") { + size = 2; + mask = 0xffff; + fnGet = this.getShort; + fnSet = this.setShort; + } + var cch = size << 1; + + var sAddr = asArgs[1]; + if (sAddr == null) { + this.println("edit memory commands:"); + this.println("\teb [a] [...] edit bytes at address a"); + this.println("\tew [a] [...] edit words at address a"); + return; + } + + var dbgAddr = this.parseAddr(sAddr); + if (!dbgAddr) return; + + for (var i = 2; i < asArgs.length; i++) { + var vNew = this.parseExpression(asArgs[i]); + if (vNew === undefined) { + this.println("unrecognized value: " + asArgs[i]); + break; + } + if (vNew & ~mask) { + this.println("warning: " + str.toHex(vNew) + " exceeds " + size + "-byte value"); + } + var vOld = fnGet.call(this, dbgAddr); + this.println("changing " + this.toHexAddr(dbgAddr) + " from 0x" + str.toHex(vOld, cch) + " to 0x" + str.toHex(vNew, cch)); + fnSet.call(this, dbgAddr, vNew, size); + } + }; + + /** + * doFreqs(sParm) + * + * @this {DebuggerPDP11} + * @param {string|undefined} sParm + */ + DebuggerPDP11.prototype.doFreqs = function(sParm) + { + if (sParm == '?') { + this.println("frequency commands:"); + this.println("\tclear\tclear all frequency counts"); + return; + } + var i; + var cData = 0; + if (this.aaOpcodeCounts) { + if (sParm == "clear") { + for (i = 0; i < this.aaOpcodeCounts.length; i++) + this.aaOpcodeCounts[i] = [i, 0]; + this.println("frequency data cleared"); + cData++; + } + else if (sParm !== undefined) { + this.println("unknown frequency command: " + sParm); + cData++; + } + else { + var aaSortedOpcodeCounts = this.aaOpcodeCounts.slice(); + aaSortedOpcodeCounts.sort(function(p, q) { + return q[1] - p[1]; + }); + var asOpcodes = DebuggerPDP11.INS_NAMES; + for (i = 0; i < aaSortedOpcodeCounts.length; i++) { + var bOpcode = aaSortedOpcodeCounts[i][0]; + var cFreq = aaSortedOpcodeCounts[i][1]; + if (cFreq) { + this.println((asOpcodes[this.aaOpDescs[bOpcode][0]] + " ").substr(0, 5) + " (" + str.toHexByte(bOpcode) + "): " + cFreq + " times"); + cData++; + } + } + } + } + if (!cData) { + this.println("no frequency data available"); + } + }; + + /** + * doHalt(fQuiet) + * + * @this {DebuggerPDP11} + * @param {boolean} [fQuiet] + */ + DebuggerPDP11.prototype.doHalt = function(fQuiet) + { + var sMsg; + if (this.flags.fRunning) { + sMsg = "halting"; + this.stopCPU(); + } else { + if (this.isBusy(true)) return; + sMsg = "already halted"; + } + if (!fQuiet) this.println(sMsg); + }; + + /** + * doIf(sCmd, fQuiet) + * + * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate + * an expression like "a==10", it will compare the value of the variable "a" to 0x10; use a trailing period + * (eg, "10.") if you really intend decimal. + * + * Also, if no variable named "a" exists, "a" will evaluate to 0x0A, so the expression "a==10" becomes + * "0x0A==0x10" (false), whereas the expression "a==10." becomes "0x0A==0x0A" (true). + * + * @this {DebuggerPDP11} + * @param {string} sCmd + * @param {boolean} [fQuiet] + * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error) + */ + DebuggerPDP11.prototype.doIf = function(sCmd, fQuiet) + { + sCmd = str.trim(sCmd); + if (!this.parseExpression(sCmd)) { + if (!fQuiet) this.println("false: " + sCmd); + return false; + } + if (!fQuiet) this.println("true: " + sCmd); + return true; + }; + + /** + * doInfo(asArgs) + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs + * @return {boolean} true only if the instruction info command ("n") is supported + */ + DebuggerPDP11.prototype.doInfo = function(asArgs) + { + if (DEBUG) { + this.println("msPerYield: " + this.cpu.msPerYield); + this.println("nCyclesPerYield: " + this.cpu.nCyclesPerYield); + return true; + } + return false; + }; + + /** + * doInt(sLevel) + * + * @this {DebuggerPDP11} + * @param {string} sLevel + * @return {boolean} true if success, false if error + */ + DebuggerPDP11.prototype.doInt = function(sLevel) + { + if (!this.cpu.getIF()) { + this.println("interrupts disabled (use rif=1 to enable)"); + return false; + } + var nLevel = this.parseExpression(sLevel); + if (nLevel == null) return false; + this.println("requesting interrupt level " + nLevel); + this.cpu.requestINTR(nLevel); + return true; + }; + + /** + * doVar(sCmd) + * + * The command must be of the form "{variable} = [{expression}]", where expression may contain constants, + * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if + * any, is deleted. + * + * Other supported shorthand: "var" with no parameters prints the values of all variables, and "var {variable}" + * prints the value of the specified variable. + * + * @this {DebuggerPDP11} + * @param {string} sCmd + * @return {boolean} true if valid "var" assignment, false if not + */ + DebuggerPDP11.prototype.doVar = function(sCmd) + { + var a = sCmd.match(/^\s*([A-Z_]?[A-Z0-9_]*)\s*(=?)\s*(.*)$/i); + if (a) { + if (!a[1]) { + if (!this.printVariable()) this.println("no variables"); + return true; // it's not considered an error to print an empty list of variables + } + if (!a[2]) { + return this.printVariable(a[1]); + } + if (!a[3]) { + this.delVariable(a[1]); + return true; // it's not considered an error to delete a variable that didn't exist + } + var v = this.parseExpression(a[3]); + if (v !== undefined) { + this.setVariable(a[1], v); + return true; + } + return false; + } + this.println("invalid assignment:" + sCmd); + return false; + }; + + /** + * doList(sAddr, fPrint) + * + * @this {DebuggerPDP11} + * @param {string} sAddr + * @param {boolean} [fPrint] + * @return {string|null} + */ + DebuggerPDP11.prototype.doList = function(sAddr, fPrint) + { + var sSymbol = null; + + var dbgAddr = this.parseAddr(sAddr, true); + if (dbgAddr) { + var addr = this.getAddr(dbgAddr); + var aSymbol = this.findSymbol(dbgAddr, true); + if (aSymbol.length) { + var nDelta, sDelta, s; + if (aSymbol[0]) { + sDelta = ""; + nDelta = dbgAddr.addr - aSymbol[1]; + if (nDelta) sDelta = " + " + str.toHexWord(nDelta); + s = aSymbol[0] + " (" + this.toHexOffset(aSymbol[1]) + ')' + sDelta; + if (fPrint) this.println(s); + sSymbol = s; + } + if (aSymbol.length > 4 && aSymbol[4]) { + sDelta = ""; + nDelta = aSymbol[5] - dbgAddr.addr; + if (nDelta) sDelta = " - " + str.toHexWord(nDelta); + s = aSymbol[4] + " (" + this.toHexOffset(aSymbol[5]) + ')' + sDelta; + if (fPrint) this.println(s); + if (!sSymbol) sSymbol = s; + } + } else { + if (fPrint) this.println("no symbols"); + } + } + return sSymbol; + }; + + /** + * doMessages(asArgs) + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs + */ + DebuggerPDP11.prototype.doMessages = function(asArgs) + { + var m; + var fCriteria = null; + var sCategory = asArgs[1]; + if (sCategory == '?') sCategory = undefined; + + if (sCategory !== undefined) { + var bitsMessage = 0; + if (sCategory == "all") { + bitsMessage = (0xffffffff|0) & ~(MessagesPDP11.HALT | MessagesPDP11.KEYS | MessagesPDP11.LOG); + sCategory = null; + } else if (sCategory == "on") { + fCriteria = true; + sCategory = null; + } else if (sCategory == "off") { + fCriteria = false; + sCategory = null; + } else { + /* + * Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects, + * but externally, we allow the user to specify "keys"; "kbd" is also allowed as shorthand for "keyboard". + */ + if (sCategory == "keys") sCategory = "key"; + if (sCategory == "kbd") sCategory = "keyboard"; + for (m in MessagesPDP11.CATEGORIES) { + if (sCategory == m) { + bitsMessage = MessagesPDP11.CATEGORIES[m]; + fCriteria = !!(this.bitsMessage & bitsMessage); + break; + } + } + if (!bitsMessage) { + this.println("unknown message category: " + sCategory); + return; + } + } + if (bitsMessage) { + if (asArgs[2] == "on") { + this.bitsMessage |= bitsMessage; + fCriteria = true; + } + else if (asArgs[2] == "off") { + this.bitsMessage &= ~bitsMessage; + fCriteria = false; + if (bitsMessage == MessagesPDP11.BUFFER) { + for (var i = 0; i < this.aMessageBuffer.length; i++) { + this.println(this.aMessageBuffer[i]); + } + this.aMessageBuffer = []; + } + } + } + } + + /* + * Display those message categories that match the current criteria (on or off) + */ + var n = 0; + var sCategories = ""; + for (m in MessagesPDP11.CATEGORIES) { + if (!sCategory || sCategory == m) { + var bitMessage = MessagesPDP11.CATEGORIES[m]; + var fEnabled = !!(this.bitsMessage & bitMessage); + if (fCriteria !== null && fCriteria != fEnabled) continue; + if (sCategories) sCategories += ','; + if (!(++n % 10)) sCategories += "\n\t"; // jshint ignore:line + /* + * Internally, we use "key" instead of "keys", since the latter is a method on JavasScript objects, + * but externally, we allow the user to specify "keys". + */ + if (m == "key") m = "keys"; + sCategories += m; + } + } + + if (sCategory === undefined) { + this.println("message commands:\n\tm [category] [on|off]\tturn categories on/off"); + } + + this.println((fCriteria !== null? (fCriteria? "messages on: " : "messages off: ") : "message categories:\n\t") + (sCategories || "none")); + + this.historyInit(); // call this just in case MessagesPDP11.INT was turned on + }; + + /** + * doOptions(asArgs) + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs + */ + DebuggerPDP11.prototype.doOptions = function(asArgs) + { + switch (asArgs[1]) { + case "cs": + var nCycles; + if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion + switch (asArgs[2]) { + case "int": + this.cpu.nCyclesChecksumInterval = nCycles; + break; + case "start": + this.cpu.nCyclesChecksumStart = nCycles; + break; + case "stop": + this.cpu.nCyclesChecksumStop = nCycles; + break; + default: + this.println("unknown cs option"); + return; + } + if (nCycles !== undefined) { + this.cpu.resetChecksum(); + } + this.println("checksums " + (this.cpu.flags.fChecksum? "enabled" : "disabled")); + return; + + case "sp": + if (asArgs[2] !== undefined) { + if (!this.cpu.setSpeed(+asArgs[2])) { + this.println("warning: using 1x multiplier, previous target not reached"); + } + } + this.println("target speed: " + this.cpu.getSpeedTarget() + " (" + this.cpu.getSpeed() + "x)"); + return; + + case "?": + this.println("debugger options:"); + this.println("\tcs int #\tset checksum cycle interval to #"); + this.println("\tcs start #\tset checksum cycle start count to #"); + this.println("\tcs stop #\tset checksum cycle stop count to #"); + this.println("\tsp #\t\tset speed multiplier to #"); + break; + + default: + if (asArgs[1]) { + this.println("unknown option: " + asArgs[1]); + return; + } + break; + } + }; + + /** + * doRegisters(asArgs, fInstruction) + * + * @this {DebuggerPDP11} + * @param {Array.} [asArgs] + * @param {boolean} [fInstruction] (true to include the current instruction; default is true) + */ + DebuggerPDP11.prototype.doRegisters = function(asArgs, fInstruction) + { + if (asArgs && asArgs[1] == '?') { + this.println("register commands:"); + this.println("\tr\tdump registers"); + this.println("\trx [#]\tset flag or register x to [#]"); + return; + } + + var cpu = this.cpu; + if (fInstruction == null) fInstruction = true; + + if (asArgs != null && asArgs.length > 1) { + var sReg = asArgs[1]; + var sValue = null; + var i = sReg.indexOf('='); + if (i > 0) { + sValue = sReg.substr(i + 1); + sReg = sReg.substr(0, i); + } + else if (asArgs.length > 2) { + sValue = asArgs[2]; + } + else { + this.println("missing value for " + asArgs[1]); + return; + } + + var fValid = false; + var w = this.parseExpression(sValue); + + if (w !== undefined) { + fValid = true; + var sRegMatch = sReg.toUpperCase(); + switch (sRegMatch) { + case "A": + cpu.regA = w & 0xff; + break; + case "B": + cpu.regB = w & 0xff; + break; + case "BC": + cpu.regB = ((w >> 8) & 0xff); + /* falls through */ + case "C": + cpu.regC = w & 0xff; + break; + case "D": + cpu.regD = w & 0xff; + break; + case "DE": + cpu.regD = ((w >> 8) & 0xff); + /* falls through */ + case "E": + cpu.regE = w & 0xff; + break; + case "H": + cpu.regH = w & 0xff; + break; + case "HL": + cpu.regH = ((w >> 8) & 0xff); + /* falls through */ + case "L": + cpu.regL = w & 0xff; + break; + case "SP": + cpu.setSP(w); + break; + case "PC": + cpu.setPC(w); + this.dbgAddrNextCode = this.newAddr(cpu.getPC()); + break; + case "PS": + cpu.setPS(w); + break; + case "PSW": + cpu.setPSW(w); + break; + case "CF": + if (w) cpu.setCF(); else cpu.clearCF(); + break; + case "ZF": + if (w) cpu.setZF(); else cpu.clearZF(); + break; + case "SF": + if (w) cpu.setSF(); else cpu.clearSF(); + break; + case "IF": + if (w) cpu.setIF(); else cpu.clearIF(); + break; + default: + this.println("unknown register: " + sReg); + return; + } + } + if (!fValid) { + this.println("invalid value: " + sValue); + return; + } + cpu.updateCPU(); + this.println("updated registers:"); + } + + this.println(this.getRegDump()); + + if (fInstruction) { + this.dbgAddrNextCode = this.newAddr(cpu.getPC()); + this.doUnassemble(this.toHexAddr(this.dbgAddrNextCode)); + } + }; + + /** + * doRun(sCmd, sAddr, sOptions, fQuiet) + * + * @this {DebuggerPDP11} + * @param {string} sCmd + * @param {string|undefined} [sAddr] + * @param {string} [sOptions] (the rest of the breakpoint command-line) + * @param {boolean} [fQuiet] + */ + DebuggerPDP11.prototype.doRun = function(sCmd, sAddr, sOptions, fQuiet) + { + if (sCmd == "gt") { + this.fIgnoreNextCheckFault = true; + } + if (sAddr !== undefined) { + var dbgAddr = this.parseAddr(sAddr, true); + if (!dbgAddr) return; + this.parseAddrOptions(dbgAddr, sOptions); + this.setTempBreakpoint(dbgAddr); + } + if (!this.runCPU(true)) { + if (!fQuiet) this.println("cpu busy or unavailable, run command ignored"); + } + }; + + /** + * doPrint(sCmd) + * + * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that + * you can take advantage of all the special replacement options used for software interrupt logging. + * + * @this {DebuggerPDP11} + * @param {string} sCmd + */ + DebuggerPDP11.prototype.doPrint = function(sCmd) + { + sCmd = str.trim(sCmd); + var a = sCmd.match(/^(['"])(.*?)\1$/); + if (!a) { + this.parseExpression(sCmd, true); + } else { + this.println(this.replaceRegs(a[2])); + } + }; + + /** + * doStep(sCmd) + * + * @this {DebuggerPDP11} + * @param {string} [sCmd] "p" or "pr" + */ + DebuggerPDP11.prototype.doStep = function(sCmd) + { + var fCallStep = true; + var fRegs = (sCmd == "pr"? 1 : 0); + /* + * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants + * a subsequent register dump ("pr") or not ("p"). + */ + var nStep = 1 + fRegs; + if (!this.nStep) { + var dbgAddr = this.newAddr(this.cpu.getPC()); + var bOpcode = this.getByte(dbgAddr); + + switch (bOpcode) { + case CPUDefPDP11.OPCODE.CALL: + if (fCallStep) { + this.nStep = nStep; + this.incAddr(dbgAddr, 3); + } + break; + default: + break; + } + + if (this.nStep) { + this.setTempBreakpoint(dbgAddr); + if (!this.runCPU()) { + if (this.cmp) this.cmp.updateFocus(); + this.nStep = 0; + } + /* + * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(), + * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have + * stopped for reasons unrelated to the temporary breakpoint, but that's OK. + */ + } else { + this.doTrace(fRegs? "tr" : "t"); + } + } else { + this.println("step in progress"); + } + }; + + /** + * getCall(dbgAddr) + * + * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that + * immediately precedes that address. + * + * @this {DebuggerPDP11} + * @param {DbgAddrPDP11} dbgAddr + * @return {string|null} CALL instruction at or near dbgAddr, or null if none + */ + DebuggerPDP11.prototype.getCall = function(dbgAddr) + { + var sCall = null; + var addr = dbgAddr.addr; + var addrOrig = addr; + for (var n = 1; n <= 6 && !!addr; n++) { + if (n > 2) { + dbgAddr.addr = addr; + var s = this.getInstruction(dbgAddr); + if (s.indexOf("CALL") >= 0) { + /* + * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT), + * matches the original return address. We do this by getting the string index of the opcode bytes, + * subtracting that from the string index of the next space, and dividing that difference by two, + * to yield the length of the CALL (or INT) instruction, in bytes. + */ + var i = s.indexOf(' '); + var j = s.indexOf(' ', i+1); + if (addr + (j - i - 1)/2 == addrOrig) { + sCall = s; + break; + } + } + } + addr--; + } + dbgAddr.addr = addrOrig; + return sCall; + }; + + /** + * doStackTrace(sCmd, sAddr) + * + * Use "k" for a normal stack trace and "ks" for a stack trace with symbolic info. + * + * @this {DebuggerPDP11} + * @param {string} [sCmd] + * @param {string} [sAddr] (not used yet) + */ + DebuggerPDP11.prototype.doStackTrace = function(sCmd, sAddr) + { + if (sAddr == '?') { + this.println("stack trace commands:"); + this.println("\tk\tshow frame addresses"); + this.println("\tks\tshow symbol information"); + return; + } + + var nFrames = 10, cFrames = 0; + var dbgAddrCall = this.newAddr(); + var dbgAddrStack = this.newAddr(this.cpu.getSP()); + this.println("stack trace for " + this.toHexAddr(dbgAddrStack)); + + while (cFrames < nFrames) { + var sCall = null, sCallPrev = null, cTests = 256; + while ((dbgAddrStack.addr >>> 0) < 0x10000) { + dbgAddrCall.addr = this.getWord(dbgAddrStack, true); + /* + * Because we're using the auto-increment feature of getWord(), and because that will automatically + * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap. + */ + if (dbgAddrStack.addr == null || !cTests--) break; + sCall = this.getCall(dbgAddrCall); + if (sCall) break; + } + /* + * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always) + * indicative of a false positive, in which case the previous call is probably bogus as well, but + * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion + * being one of them, but it's rare that we're debugging recursive code. + */ + if (!sCall || sCall == sCallPrev) break; + var sSymbol = null; + if (sCmd == "ks") { + var a = sCall.match(/[0-9A-F]+$/); + if (a) sSymbol = this.doList(a[0]); + } + sCall = str.pad(sCall, 50) + " ;" + (sSymbol || "stack=" + this.toHexAddr(dbgAddrStack)); // + " return=" + this.toHexAddr(dbgAddrCall)); + this.println(sCall); + sCallPrev = sCall; + cFrames++; + } + if (!cFrames) this.println("no return addresses found"); + }; + + /** + * doTrace(sCmd, sCount) + * + * The "t" and "tr" commands interpret the count as a number of instructions, and since + * we call the Debugger's stepCPU() for each iteration, a single instruction includes + * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only + * difference between "t" and "tr": the former displays only the next instruction, while + * the latter also displays the (updated) registers. + * + * The "tc" command interprets the count as a number of cycles rather than instructions, + * allowing you to quickly execute large chunks of instructions with a single command; it + * doesn't display anything until the the chunk has finished. + * + * However, generally a more useful command is "bn", which allows you to break after some + * number of instructions have been executed (as opposed to some number of cycles). + * + * @this {DebuggerPDP11} + * @param {string} [sCmd] ("t", "tc", or "tr") + * @param {string} [sCount] # of instructions to step + */ + DebuggerPDP11.prototype.doTrace = function(sCmd, sCount) + { + var dbg = this; + var fRegs = (sCmd != "t"); + var nCount = this.parseValue(sCount, null, true) || 1; + var nCycles = (nCount == 1? 0 : 1); + if (sCmd == "tc") { + nCycles = nCount; + nCount = 1; + } + web.onCountRepeat( + nCount, + function onCountStep() { + return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false); + }, + function onCountStepComplete() { + /* + * We explicitly called stepCPU() with fUpdateCPU === false, because repeatedly + * calling updateCPU() can be very slow, especially when fDisplayLiveRegs is true, + * so once the repeat count has been exhausted, we must perform a final updateCPU(). + */ + dbg.cpu.updateCPU(); + dbg.setBusy(false); + } + ); + }; + + /** + * doUnassemble(sAddr, sAddrEnd, n) + * + * @this {DebuggerPDP11} + * @param {string} [sAddr] + * @param {string} [sAddrEnd] + * @param {number} [n] + */ + DebuggerPDP11.prototype.doUnassemble = function(sAddr, sAddrEnd, n) + { + var dbgAddr = this.parseAddr(sAddr, true); + if (!dbgAddr) return; + + if (n === undefined) n = 1; + + var cb = 0x100; + if (sAddrEnd !== undefined) { + + var dbgAddrEnd = this.parseAddr(sAddrEnd, true); + if (!dbgAddrEnd || dbgAddrEnd.addr < dbgAddr.addr) return; + + cb = dbgAddrEnd.addr - dbgAddr.addr; + if (!DEBUG && cb > 0x100) { + /* + * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to + * prevent the user from wedging the browser by dumping too many lines, but also a recognition + * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway. + */ + this.println("range too large"); + return; + } + n = -1; + } + + var cLines = 0; + var sInstruction; + + while (cb > 0 && n--) { + + var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null; + var sComment = (nSequence != null? "cycles" : null); + var aSymbol = this.findSymbol(dbgAddr); + + var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it + + if (aSymbol[0] && n) { + if (!cLines && n || aSymbol[0].indexOf('+') < 0) { + var sLabel = aSymbol[0] + ':'; + if (aSymbol[2]) sLabel += ' ' + aSymbol[2]; + this.println(sLabel); + } + } + + if (aSymbol[3]) { + sComment = aSymbol[3]; + nSequence = null; + } + + sInstruction = this.getInstruction(dbgAddr, sComment, nSequence); + + this.println(sInstruction); + this.dbgAddrNextCode = dbgAddr; + cb -= dbgAddr.addr - addr; + cLines++; + } + }; + + /** + * parseCommand(sCmd, fSave, chSep) + * + * @this {DebuggerPDP11} + * @param {string|undefined} sCmd + * @param {boolean} [fSave] is true to save the command, false if not + * @param {string} [chSep] is the command separator character (default is ';') + * @return {Array.} + */ + DebuggerPDP11.prototype.parseCommand = function(sCmd, fSave, chSep) + { + if (fSave) { + if (!sCmd) { + if (this.fAssemble) { + sCmd = "end"; + } else { + sCmd = this.aPrevCmds[this.iPrevCmd+1]; + } + } else { + if (this.iPrevCmd < 0 && this.aPrevCmds.length) { + this.iPrevCmd = 0; + } + if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) { + this.aPrevCmds.splice(0, 0, sCmd); + this.iPrevCmd = 0; + } + this.iPrevCmd--; + } + } + var a = []; + if (sCmd) { + /* + * With the introduction of breakpoint commands (ie, quoted command sequences + * associated with a breakpoint), we can no longer perform simplistic splitting. + * + * a = sCmd.split(chSep || ';'); + * for (var i = 0; i < a.length; i++) a[i] = str.trim(a[i]); + * + * We may now split on semi-colons ONLY if they are outside a quoted sequence. + * + * Also, to allow quoted strings *inside* breakpoint commands, we first replace all + * DOUBLE double-quotes with single quotes. + */ + sCmd = sCmd.toLowerCase().replace(/""/g, "'"); + + var iPrev = 0; + var chQuote = null; + chSep = chSep || ';'; + /* + * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking + * advantage of the fact that charAt() with an invalid index returns an empty string, + * allowing us to use the same substring() call to capture the final portion of sCmd. + * + * In a sense, it allows us to pretend that the string ends with a zero terminator. + */ + for (var i = 0; i <= sCmd.length; i++) { + var ch = sCmd.charAt(i); + if (ch == '"' || ch == "'") { + if (!chQuote) { + chQuote = ch; + } else if (ch == chQuote) { + chQuote = null; + } + } + else if (ch == chSep && !chQuote || !ch) { + /* + * Recall that substring() accepts starting (inclusive) and ending (exclusive) + * indexes, whereas substr() accepts a starting index and a length. We need the former. + */ + a.push(str.trim(sCmd.substring(iPrev, i))); + iPrev = i + 1; + } + } + } + return a; + }; + + /** + * shiftArgs(asArgs) + * + * Used with any command (eg, "r") that allows but doesn't require whitespace between command and first argument. + * + * @this {DebuggerPDP11} + * @param {Array.} asArgs + * @return {Array.} + */ + DebuggerPDP11.prototype.shiftArgs = function(asArgs) + { + if (asArgs && asArgs.length) { + var s0 = asArgs[0]; + var ch0 = s0.charAt(0); + for (var i = 1; i < s0.length; i++) { + var ch = s0.charAt(i); + if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') { + asArgs[0] = s0.substr(i); + asArgs.unshift(s0.substr(0, i)); + break; + } + } + } + return asArgs; + }; + + /** + * doCommand(sCmd, fQuiet) + * + * @this {DebuggerPDP11} + * @param {string} sCmd + * @param {boolean} [fQuiet] + * @return {boolean} true if command processed, false if unrecognized + */ + DebuggerPDP11.prototype.doCommand = function(sCmd, fQuiet) + { + var result = true; + + try { + if (!sCmd.length || sCmd == "end") { + if (this.fAssemble) { + this.println("ended assemble at " + this.toHexAddr(this.dbgAddrAssemble)); + this.dbgAddrNextCode = this.dbgAddrAssemble; + this.fAssemble = false; + } + sCmd = ""; + } + else if (!fQuiet) { + var sPrompt = ">> "; + this.println(sPrompt + sCmd); + } + + var ch = sCmd.charAt(0); + if (ch == '"' || ch == "'") return true; + + /* + * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat. + */ + this.sMessagePrev = null; + + /* + * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally. + */ + if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) { + + if (this.fAssemble) { + sCmd = "a " + this.toHexAddr(this.dbgAddrAssemble) + ' ' + sCmd; + } + + var asArgs = this.shiftArgs(sCmd.replace(/ +/g, ' ').split(' ')); + + switch (asArgs[0].charAt(0)) { + case 'a': + this.doAssemble(asArgs); + break; + case 'b': + this.doBreak(asArgs[0], asArgs[1], sCmd); + break; + case 'c': + this.doClear(asArgs[0]); + break; + case 'd': + if (!COMPILED && sCmd == "debug") { + window.DEBUG = true; + this.println("DEBUG checks on"); + break; + } + this.doDump(asArgs); + break; + case 'e': + if (asArgs[0] == "else") break; + this.doEdit(asArgs); + break; + case 'f': + this.doFreqs(asArgs[1]); + break; + case 'g': + this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet); + break; + case 'h': + this.doHalt(fQuiet); + break; + case 'i': + if (asArgs[0] == "if") { + if (!this.doIf(sCmd.substr(2), fQuiet)) { + result = false; + } + break; + } + if (asArgs[0] == "int") { + if (!this.doInt(asArgs[1])) { + result = false; + } + break; + } + break; + case 'k': + this.doStackTrace(asArgs[0], asArgs[1]); + break; + case 'l': + if (asArgs[0] == "ln") { + this.doList(asArgs[1], true); + break; + } + break; + case 'm': + this.doMessages(asArgs); + break; + case 'p': + if (asArgs[0] == "print") { + this.doPrint(sCmd.substr(5)); + break; + } + this.doStep(asArgs[0]); + break; + case 'r': + if (sCmd == "reset") { + if (this.cmp) this.cmp.reset(); + break; + } + this.doRegisters(asArgs); + break; + case 's': + this.doOptions(asArgs); + break; + case 't': + this.doTrace(asArgs[0], asArgs[1]); + break; + case 'u': + this.doUnassemble(asArgs[1], asArgs[2], 8); + break; + case 'v': + if (asArgs[0] == "var") { + if (!this.doVar(sCmd.substr(3))) { + result = false; + } + break; + } + this.println((PDP11.APPNAME || "PDP11") + " version " + (XMLVERSION || PDP11.APPVERSION) + " (" + this.cpu.model + (PDP11.COMPILED? ",RELEASE" : (PDP11.DEBUG? ",DEBUG" : ",NODEBUG")) + (PDP11.TYPEDARRAYS? ",TYPEDARRAYS" : (PDP11.BYTEARRAYS? ",BYTEARRAYS" : ",LONGARRAYS")) + ')'); + this.println(web.getUserAgent()); + break; + case '?': + if (asArgs[1]) { + this.doPrint(sCmd.substr(1)); + break; + } + this.doHelp(); + break; + case 'n': + if (!COMPILED && sCmd == "nodebug") { + window.DEBUG = false; + this.println("DEBUG checks off"); + break; + } + if (this.doInfo(asArgs)) break; + /* falls through */ + default: + this.println("unknown command: " + sCmd); + result = false; + break; + } + } + } catch(e) { + this.println("debugger error: " + (e.stack || e.message)); + result = false; + } + return result; + }; + + /** + * doCommands(sCmds, fSave) + * + * @this {DebuggerPDP11} + * @param {string} sCmds + * @param {boolean} [fSave] + * @return {boolean} true if all commands processed, false if not + */ + DebuggerPDP11.prototype.doCommands = function(sCmds, fSave) + { + var a = this.parseCommand(sCmds, fSave); + for (var s in a) { + if (!this.doCommand(a[s])) return false; + } + return true; + }; + + /** + * DebuggerPDP11.init() + * + * This function operates on every HTML element of class "debugger", extracting the + * JSON-encoded parameters for the Debugger constructor from the element's "data-value" + * attribute, invoking the constructor to create a Debugger component, and then binding + * any associated HTML controls to the new component. + */ + DebuggerPDP11.init = function() + { + var aeDbg = Component.getElementsByClass(document, PDP11.APPCLASS, "debugger"); + for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) { + var eDbg = aeDbg[iDbg]; + var parmsDbg = Component.getComponentParms(eDbg); + var dbg = new DebuggerPDP11(parmsDbg); + Component.bindComponentControls(dbg, eDbg, PDP11.APPCLASS); + } + }; + + /* + * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-)) + */ + web.onInit(DebuggerPDP11.init); + +} // endif DEBUGGER + +if (NODE) module.exports = DebuggerPDP11; diff --git a/modules/pdp11/lib/defines.js b/modules/pdp11/lib/defines.js new file mode 100644 index 000000000..c245eb2db --- /dev/null +++ b/modules/pdp11/lib/defines.js @@ -0,0 +1,108 @@ +/** + * @fileoverview PDP11-specific compile-time definitions. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +/** + * @define {string} + */ +var APPCLASS = "pdp11"; // this @define is the default application class (eg, "pcx86", "c1pjs") + +/** + * @define {string} + */ +var APPNAME = "PDP11"; // 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 + * "type skeleton", which also solves some type-related warnings we would otherwise have if we tried to remove + * debugger.js from the compilation process altogether. + * + * 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*. + */ +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. + */ +var BYTEARRAYS = false; + +/** + * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've + * added Memory access functions for typed arrays (see MemoryPDP11.afnTypedArray), so support can be enabled dynamically now. + * + * See the Memory component for details. + */ +var TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined'); + +/* + * Combine all the shared globals and machine-specific globals into one machine-specific global object, + * which all machine components should start using; eg: "if (PDP11.DEBUG) ..." instead of "if (DEBUG) ...". + */ +var PDP11 = { + APPCLASS: APPCLASS, + APPNAME: APPNAME, + APPVERSION: APPVERSION, // shared + BYTEARRAYS: BYTEARRAYS, + COMPILED: COMPILED, // shared + CSSCLASS: CSSCLASS, // shared + DEBUG: DEBUG, // shared + DEBUGGER: DEBUGGER, + MAXDEBUG: MAXDEBUG, // shared + PRIVATE: PRIVATE, // shared + TYPEDARRAYS: TYPEDARRAYS, + SITEHOST: SITEHOST, // shared + XMLVERSION: XMLVERSION // shared +}; + +if (NODE) { + global.APPCLASS = APPCLASS; + global.APPNAME = APPNAME; + global.DEBUGGER = DEBUGGER; + global.BYTEARRAYS = BYTEARRAYS; + global.TYPEDARRAYS = TYPEDARRAYS; + global.PDP11 = PDP11; + + module.exports = PDP11; +} diff --git a/modules/pdp11/lib/keyboard.js b/modules/pdp11/lib/keyboard.js new file mode 100644 index 000000000..3311e6524 --- /dev/null +++ b/modules/pdp11/lib/keyboard.js @@ -0,0 +1,295 @@ +/** + * @fileoverview Implements the PDP11 Keyboard component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var web = require("../../shared/lib/weblib"); + var Component = require("../../shared/lib/component"); + var PDP11 = require("./defines"); + var MessagesPDP11 = require("./messages"); +} + +/** + * KeyboardPDP11(parmsKbd) + * + * @constructor + * @extends Component + * @param {Object} parmsKbd + */ +function KeyboardPDP11(parmsKbd) +{ + Component.call(this, "Keyboard", parmsKbd, KeyboardPDP11, MessagesPDP11.KEYBOARD); + + this.setReady(); +} + +Component.subclass(KeyboardPDP11); + +/** + * Alphanumeric and other common (printable) ASCII codes. + * + * TODO: Determine what we can do to get ALL constants like these inlined by the Closure Compiler + * (enum doesn't seem to get the job done); the problem seems to be limited to property references + * that use quotes, which is why I've 'unquoted' as many of them as possible. + * + * @enum {number} + */ +KeyboardPDP11.ASCII = { + CTRL_A: 1, CTRL_C: 3, CTRL_Z: 26, + ' ': 32, '!': 33, '"': 34, '#': 35, '$': 36, '%': 37, '&': 38, "'": 39, + '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47, + '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55, + '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63, + '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, + H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, + P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, + X: 88, Y: 89, Z: 90, '[': 91, '\\':92, ']': 93, '^': 94, '_': 95, + '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103, + h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111, + p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119, + x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126 +}; + +/** + * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric + * or function keys, some which may require special treatment (eg, preventDefault() if returning false on + * the initial keyDown event is insufficient). + * + * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above. + * + * Most of these represent non-ASCII characters (eg, the LEFT arrow key), yet for some reason, browsers + * defined them using ASCII codes (eg, the LEFT arrow key uses 37, which is the ASCII code for '%'). + * + * @enum {number} + */ +KeyboardPDP11.KEYCODE = { + /* 0x08 */ BS: 8, + /* 0x09 */ TAB: 9, + /* 0x0A */ LF: 10, // TODO: Determine if any key actually generates this (I suspect there is none) + /* 0x0D */ CR: 13, + /* 0x10 */ SHIFT: 16, + /* 0x11 */ CTRL: 17, + /* 0x12 */ ALT: 18, + /* 0x13 */ PAUSE: 19, // PAUSE/BREAK + /* 0x14 */ CAPSLOCK: 20, + /* 0x1B */ ESC: 27, + /* 0x20 */ SPACE: 32, + /* 0x21 */ PGUP: 33, + /* 0x22 */ PGDN: 34, + /* 0x23 */ END: 35, + /* 0x24 */ HOME: 36, + /* 0x25 */ LEFT: 37, + /* 0x26 */ UP: 38, + /* 0x27 */ RIGHT: 39, + /* 0x27 */ FF_QUOTE: 39, + /* 0x28 */ DOWN: 40, + /* 0x2C */ FF_COMMA: 44, + /* 0x2C */ PRTSC: 44, + /* 0x2D */ INS: 45, + /* 0x2E */ DEL: 46, + /* 0x2E */ FF_PERIOD: 46, + /* 0x2F */ FF_SLASH: 47, + /* 0x30 */ ZERO: 48, + /* 0x31 */ ONE: 49, + /* 0x32 */ TWO: 50, + /* 0x33 */ THREE: 51, + /* 0x34 */ FOUR: 52, + /* 0x35 */ FIVE: 53, + /* 0x36 */ SIX: 54, + /* 0x37 */ SEVEN: 55, + /* 0x38 */ EIGHT: 56, + /* 0x39 */ NINE: 57, + /* 0x3B */ FF_SEMI: 59, + /* 0x3D */ FF_EQUALS: 61, + /* 0x5B */ CMD: 91, // aka WIN + /* 0x5B */ FF_LBRACK: 91, + /* 0x5C */ FF_BSLASH: 92, + /* 0x5D */ RCMD: 93, // aka MENU + /* 0x5D */ FF_RBRACK: 93, + /* 0x60 */ NUM_0: 96, + /* 0x60 */ NUM_INS: 96, + /* 0x60 */ FF_BQUOTE: 96, + /* 0x61 */ NUM_1: 97, + /* 0x61 */ NUM_END: 97, + /* 0x62 */ NUM_2: 98, + /* 0x62 */ NUM_DOWN: 98, + /* 0x63 */ NUM_3: 99, + /* 0x63 */ NUM_PGDN: 99, + /* 0x64 */ NUM_4: 100, + /* 0x64 */ NUM_LEFT: 100, + /* 0x65 */ NUM_5: 101, + /* 0x65 */ NUM_CENTER: 101, + /* 0x66 */ NUM_6: 102, + /* 0x66 */ NUM_RIGHT: 102, + /* 0x67 */ NUM_7: 103, + /* 0x67 */ NUM_HOME: 103, + /* 0x68 */ NUM_8: 104, + /* 0x68 */ NUM_UP: 104, + /* 0x69 */ NUM_9: 105, + /* 0x69 */ NUM_PGUP: 105, + /* 0x6A */ NUM_MUL: 106, + /* 0x6B */ NUM_ADD: 107, + /* 0x6D */ NUM_SUB: 109, + /* 0x6E */ NUM_DEL: 110, // aka PERIOD + /* 0x6F */ NUM_DIV: 111, + /* 0x70 */ F1: 112, + /* 0x71 */ F2: 113, + /* 0x72 */ F3: 114, + /* 0x73 */ F4: 115, + /* 0x74 */ F5: 116, + /* 0x75 */ F6: 117, + /* 0x76 */ F7: 118, + /* 0x77 */ F8: 119, + /* 0x78 */ F9: 120, + /* 0x79 */ F10: 121, + /* 0x7A */ F11: 122, + /* 0x7B */ F12: 123, + /* 0x90 */ NUM_LOCK: 144, + /* 0x91 */ SCROLL_LOCK: 145, + /* 0xAD */ FF_DASH: 173, + /* 0xBA */ SEMI: 186, // Firefox: 59 + /* 0xBB */ EQUALS: 187, // Firefox: 61 + /* 0xBC */ COMMA: 188, // Firefox: 44 + /* 0xBD */ DASH: 189, // Firefox: 173 + /* 0xBE */ PERIOD: 190, // Firefox: 46 + /* 0xBF */ SLASH: 191, // Firefox: 47 + /* 0xC0 */ BQUOTE: 192, // Firefox: 96 + /* 0xDB */ LBRACK: 219, // Firefox: 91 + /* 0xDC */ BSLASH: 220, // Firefox: 92 + /* 0xDD */ RBRACK: 221, // Firefox: 93 + /* 0xDE */ QUOTE: 222, // Firefox: 39 + /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD) + // + // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD), + // where the thousands digit is used to store the sum of "binary" digits 1 and/or 2 and/or 4. + // + // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really + // been called HCD (Hexadecimal Coded Decimal), so if "they" can take liberties, so can I. + // + // ONDOWN is a bias we add to browser keyCodes that we want to handle on "down" rather than on "press". + // + ONDOWN: 1000, + // + // ONRIGHT is a bias we add to browser keyCodes that need to check for a "right" location (default is "left") + // + ONRIGHT: 2000, + // + // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations. + // The actual values are for internal use only and merely need to be unique and used consistently. + // + FAKE: 4000 +}; + +/* + * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys. + */ +KeyboardPDP11.KEYCODE.NUM_CR = KeyboardPDP11.KEYCODE.CR + KeyboardPDP11.KEYCODE.ONRIGHT; + +/* + * Maps "stupid" keyCodes to their "non-stupid" counterparts + */ +KeyboardPDP11.STUPID_KEYCODES = {}; +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.SEMI] = KeyboardPDP11.ASCII[';']; // 186 -> 59 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.EQUALS] = KeyboardPDP11.ASCII['=']; // 187 -> 61 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.COMMA] = KeyboardPDP11.ASCII[',']; // 188 -> 44 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.DASH] = KeyboardPDP11.ASCII['-']; // 189 -> 45 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.PERIOD] = KeyboardPDP11.ASCII['.']; // 190 -> 46 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.SLASH] = KeyboardPDP11.ASCII['/']; // 191 -> 47 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.BQUOTE] = KeyboardPDP11.ASCII['`']; // 192 -> 96 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.LBRACK] = KeyboardPDP11.ASCII['[']; // 219 -> 91 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.BSLASH] = KeyboardPDP11.ASCII['\\']; // 220 -> 92 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.RBRACK] = KeyboardPDP11.ASCII[']']; // 221 -> 93 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.QUOTE] = KeyboardPDP11.ASCII["'"]; // 222 -> 39 +KeyboardPDP11.STUPID_KEYCODES[KeyboardPDP11.KEYCODE.FF_DASH] = KeyboardPDP11.ASCII['-']; + +KeyboardPDP11.MINPRESSTIME = 100; // 100ms + +/** + * setBinding(sHTMLType, sBinding, control, sValue) + * + * @this {KeyboardPDP11} + * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "esc") + * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) + * @param {string} [sValue] optional data value + * @return {boolean} true if binding was successful, false if unrecognized binding request + */ +KeyboardPDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) +{ + return false; +}; + +/** + * initBus(cmp, bus, cpu, dbg) + * + * @this {KeyboardPDP11} + * @param {ComputerPDP11} cmp + * @param {BusPDP11} bus + * @param {CPUStatePDP11} cpu + * @param {DebuggerPDP11} dbg + */ +KeyboardPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) +{ + this.cmp = cmp; + this.cpu = cpu; + this.dbg = dbg; // NOTE: The "dbg" property must be set for the message functions to work + this.chipset = null; // /** @type {ChipSetPDP11} */ (cmp.getMachineComponent("ChipSet")); +}; + +/** + * KeyboardPDP11.init() + * + * This function operates on every HTML element of class "keyboard", extracting the + * JSON-encoded parameters for the Keyboard constructor from the element's "data-value" + * attribute, invoking the constructor to create a Keyboard component, and then binding + * any associated HTML controls to the new component. + */ +KeyboardPDP11.init = function() +{ + var aeKbd = Component.getElementsByClass(document, PDP11.APPCLASS, "keyboard"); + for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) { + var eKbd = aeKbd[iKbd]; + var parmsKbd = Component.getComponentParms(eKbd); + var kbd = new KeyboardPDP11(parmsKbd); + Component.bindComponentControls(kbd, eKbd, PDP11.APPCLASS); + } +}; + +/* + * Initialize every Keyboard module on the page. + */ +web.onInit(KeyboardPDP11.init); + +if (NODE) module.exports = KeyboardPDP11; diff --git a/modules/pdp11/lib/memory.js b/modules/pdp11/lib/memory.js new file mode 100644 index 000000000..42858eca7 --- /dev/null +++ b/modules/pdp11/lib/memory.js @@ -0,0 +1,826 @@ +/** + * @fileoverview Implements the PDP11 Memory component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var Component = require("../../shared/lib/component"); + var CPUDefPDP11 = require("./cpudef"); + var MessagesPDP11 = require("./messages"); +} + +/** + * @class DataView + * @property {function(number,boolean):number} getUint8 + * @property {function(number,number,boolean)} setUint8 + * @property {function(number,boolean):number} getUint16 + * @property {function(number,number,boolean)} setUint16 + * @property {function(number,boolean):number} getInt32 + * @property {function(number,number,boolean)} setInt32 + */ + +var littleEndian = (TYPEDARRAYS? (function() { + var buffer = new ArrayBuffer(2); + new DataView(buffer).setUint16(0, 256, true); + return new Uint16Array(buffer)[0] === 256; +})() : false); + +/** + * MemoryPDP11(addr, used, size, type) + * + * The Bus component allocates MemoryPDP11 objects so that each has a memory buffer with a + * block-granular starting address and an address range equal to bus.nBlockSize; however, + * the size of any given MemoryPDP11 object's underlying buffer can be either zero or bus.nBlockSize; + * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone. + * + * The Bus allocates empty blocks for the entire address space during initialization, so that + * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM + * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate + * as many new blockSize MemoryPDP11 objects as the ranges require. Partial MemoryPDP11 blocks could + * also be supported in theory, but in practice, they're not. + * + * Because MemoryPDP11 blocks now allow us to have a "sparse" address space, we could choose to + * take the memory hit of allocating 4K arrays per block, where each element stores only one byte, + * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords + * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would + * be faster and word accesses somewhat less faster. + * + * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster + * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS + * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform + * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use + * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over + * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably + * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support). + * + * WARNING: Since MemoryPDP11 blocks are low-level objects that have no UI requirements, they + * do not inherit from the Component class, so if you want to use any Component class methods, + * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger + * is available). + * + * @constructor + * @param {number|null} [addr] of lowest used address in block + * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4 + * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4 + * @param {number} [type] is one of the MemoryPDP11.TYPE constants (default is MemoryPDP11.TYPE.NONE) + */ +function MemoryPDP11(addr, used, size, type) +{ + var i; + this.id = (MemoryPDP11.idBlock += 2); + this.adw = null; + this.offset = 0; + this.addr = addr; + this.used = used; + this.size = size || 0; + this.type = type || MemoryPDP11.TYPE.NONE; + this.fReadOnly = (type == MemoryPDP11.TYPE.ROM); + this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize + + /* + * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory() + * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer. + * But the benefit to saveMemory() is minimal, and the Video component has other options; for example, it now + * uses a custom memory controller for all EGA/VGA video modes, which performs its own dirty block tracking, + * and that could easily be extended to the older MDA/CGA video modes, which still use conventional memory blocks. + * Alternatively, we could restrict the use of dirty block tracking to certain memory types (eg, VIDEO memory). + * + * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance, + * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates. + */ + this.fDirty = this.fDirtyEver = false; + + /* + * For empty memory blocks, all we need to do is ensure all access functions are mapped to "none" handlers. + */ + if (!size) { + this.setAccess(); + return; + } + + /* + * This is the normal case: allocate a buffer that provides 8 bits of data per address; + * no controller is required because our default memory access functions (see afnMemory) + * know how to deal with this simple 1-1 mapping of addresses to bytes and words. + * + * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG + * mode; pseudo-random might be best, to help make any bugs reproducible. + */ + if (TYPEDARRAYS) { + this.buffer = new ArrayBuffer(size); + this.dv = new DataView(this.buffer, 0, size); + /* + * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them + * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to + * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32(). + */ + this.ab = new Uint8Array(this.buffer, 0, size); + this.aw = new Uint16Array(this.buffer, 0, size >> 1); + this.adw = new Int32Array(this.buffer, 0, size >> 2); + this.setAccess(littleEndian? MemoryPDP11.afnArrayLE : MemoryPDP11.afnArrayBE); + } else { + if (BYTEARRAYS) { + this.ab = new Array(size); + } else { + /* + * NOTE: This is the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because it + * seems to provide the best performance; and although in theory, that performance might + * come at twice the overhead of TYPEDARRAYS, it's increasingly likely that the JavaScript + * runtime will notice that all we ever store are 32-bit values, and optimize accordingly. + */ + this.adw = new Array(size >> 2); + for (i = 0; i < this.adw.length; i++) this.adw[i] = 0; + } + this.setAccess(MemoryPDP11.afnMemory); + } +} + +/* + * Basic memory types + * + * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie, + * 'little endian") storage. ROM is equally conventional, except that the fReadOnly property is set, + * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and + * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect() + * interface (which in turn uses the MemoryPDP11 writeByteDirect() interface), allowing the ROM component to + * initialize its own memory. The CTRL type is used to identify memory-mapped devices that do not need + * any default storage and always provide their own controller. + * + * Unallocated regions of the address space contain a special memory block of type NONE that contains + * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in + * exactly the same manner, without resorting to any range or processor checks. + * + * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or + * without a custom controller (the original Monochrome and CGA video cards used read/write storage that + * was indistinguishable from RAM), and CTRL memory could be allocated as an empty block of any type, with + * a custom controller. A few types are required for certain features (eg, ROM is required if you want + * read-only memory), but the larger purpose of these types is to help document the caller's intent and to + * provide the Control Panel with the ability to highlight memory regions accordingly. + */ +MemoryPDP11.TYPE = { + NONE: 0, + RAM: 1, + ROM: 2, + VIDEO: 3, + CTRL: 4, + COLORS: ["black", "blue", "green", "cyan"], + NAMES: ["NONE", "RAM", "ROM", "VID", "H/W"] +}; + +/* + * Last used block ID (used for debugging only) + */ +MemoryPDP11.idBlock = 0; + +/** + * adjustEndian(dw) + * + * @param {number} dw + * @return {number} + */ +MemoryPDP11.adjustEndian = function(dw) { + if (TYPEDARRAYS && !littleEndian) { + dw = (dw << 24) | ((dw << 8) & 0x00ff0000) | ((dw >> 8) & 0x0000ff00) | (dw >>> 24); + } + return dw; +}; + +MemoryPDP11.prototype = { + constructor: MemoryPDP11, + parent: null, + /** + * init(addr) + * + * Quick reinitializer when reusing a MemoryPDP11 block. + * + * @this {MemoryPDP11} + * @param {number} addr + */ + init: function(addr) { + this.addr = addr; + }, + /** + * clone(mem, type) + * + * Converts the current MemoryPDP11 block (this) into a clone of the given MemoryPDP11 block (mem), + * and optionally overrides the current block's type with the specified type. + * + * @this {MemoryPDP11} + * @param {MemoryPDP11} mem + * @param {number} [type] + * @param {DebuggerPDP11} [dbg] + */ + clone: function(mem, type, dbg) { + /* + * Original memory block IDs are even; cloned memory block IDs are odd; + * the original ID of the current block is lost, but that's OK, since it was presumably + * produced merely to become a clone. + */ + this.id = mem.id | 0x1; + this.used = mem.used; + this.size = mem.size; + if (type) { + this.type = type; + this.fReadOnly = (type == MemoryPDP11.TYPE.ROM); + } + if (TYPEDARRAYS) { + this.buffer = mem.buffer; + this.dv = mem.dv; + this.ab = mem.ab; + this.aw = mem.aw; + this.adw = mem.adw; + this.setAccess(littleEndian? MemoryPDP11.afnArrayLE : MemoryPDP11.afnArrayBE); + } else { + if (BYTEARRAYS) { + this.ab = mem.ab; + } else { + this.adw = mem.adw; + } + this.setAccess(MemoryPDP11.afnMemory); + } + this.copyBreakpoints(dbg, mem); + }, + /** + * save() + * + * This gets the contents of a MemoryPDP11 block as an array of 32-bit values; used by BusPDP11.saveMemory(), + * which in turn is called by CPUStatePDP11.save(). + * + * MemoryPDP11 blocks with custom memory controllers do NOT save their contents; that's the responsibility + * of the controller component. + * + * @this {MemoryPDP11} + * @return {Array|Int32Array|null} + */ + save: function() { + var adw, i; + if (BYTEARRAYS) { + adw = new Array(this.size >> 2); + var off = 0; + for (i = 0; i < adw.length; i++) { + adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24); + off += 4; + } + } + else if (TYPEDARRAYS) { + /* + * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2), + * but we can't be sure of the "endianness" of an Int32Array -- which would be OK if the array + * was always saved/restored on the same machine, but there's no guarantee of that, either. + * So we use getInt32() and require little-endian values. + * + * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like + * a normal array; it's serialized as an Object rather than an Array, so it lacks a "length" + * property and causes problems for State.store() and State.parse(). + */ + adw = new Array(this.size >> 2); + for (i = 0; i < adw.length; i++) { + adw[i] = this.dv.getInt32(i << 2, true); + } + } + else { + adw = this.adw; + } + return adw; + }, + /** + * restore(adw) + * + * This restores the contents of a MemoryPDP11 block from an array of 32-bit values; + * used by BusPDP11.restoreMemory(), which is called by CPUStatePDP11.restore(), after all other + * components have been restored and thus all MemoryPDP11 blocks have been allocated + * by their respective components. + * + * @this {MemoryPDP11} + * @param {Array|null} adw + * @return {boolean} true if successful, false if block size mismatch + */ + restore: function(adw) { + /* + * At this point, it's a consistency error for adw to be null; it's happened once already, + * when there was a restore bug in the Video component that added the frame buffer at the video + * card's "spec'ed" address instead of the programmed address, so there were no controller-owned + * memory blocks installed at the programmed address, and so we arrived here at a block with + * no controller AND no data. + */ + Component.assert(adw != null); + + if (adw && this.size == adw.length << 2) { + var i; + if (BYTEARRAYS) { + var off = 0; + for (i = 0; i < adw.length; i++) { + this.ab[off] = adw[i] & 0xff; + this.ab[off + 1] = (adw[i] >> 8) & 0xff; + this.ab[off + 2] = (adw[i] >> 16) & 0xff; + this.ab[off + 3] = (adw[i] >> 24) & 0xff; + off += 4; + } + } else if (TYPEDARRAYS) { + for (i = 0; i < adw.length; i++) { + this.dv.setInt32(i << 2, adw[i], true); + } + } else { + this.adw = adw; + } + this.fDirty = true; + return true; + } + return false; + }, + /** + * setAccess(afn, fDirect) + * + * If no function table is specified, a default is selected based on the MemoryPDP11 type. + * + * @this {MemoryPDP11} + * @param {Array.} [afn] function table + * @param {boolean} [fDirect] (true to update direct access functions as well; default is true) + */ + setAccess: function(afn, fDirect) { + if (!afn) { + Component.assert(this.type == MemoryPDP11.TYPE.NONE); + afn = MemoryPDP11.afnNone; + } + this.setReadAccess(afn, fDirect); + this.setWriteAccess(afn, fDirect); + }, + /** + * setReadAccess(afn, fDirect) + * + * @this {MemoryPDP11} + * @param {Array.} afn + * @param {boolean} [fDirect] + */ + setReadAccess: function(afn, fDirect) { + if (!fDirect || !this.cReadBreakpoints) { + this.readByte = afn[0] || this.readNone; + this.readShort = afn[1] || this.readShortDefault; + } + if (fDirect || fDirect === undefined) { + this.readByteDirect = afn[0] || this.readNone; + this.readShortDirect = afn[1] || this.readShortDefault; + } + }, + /** + * setWriteAccess(afn, fDirect) + * + * @this {MemoryPDP11} + * @param {Array.} afn + * @param {boolean} [fDirect] + */ + setWriteAccess: function(afn, fDirect) { + if (!fDirect || !this.cWriteBreakpoints) { + this.writeByte = !this.fReadOnly && afn[2] || this.writeNone; + this.writeShort = !this.fReadOnly && afn[3] || this.writeShortDefault; + } + if (fDirect || fDirect === undefined) { + this.writeByteDirect = afn[2] || this.writeNone; + this.writeShortDirect = afn[3] || this.writeShortDefault; + } + }, + /** + * resetReadAccess() + * + * @this {MemoryPDP11} + */ + resetReadAccess: function() { + this.readByte = this.readByteDirect; + this.readShort = this.readShortDirect; + }, + /** + * resetWriteAccess() + * + * @this {MemoryPDP11} + */ + resetWriteAccess: function() { + this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect; + this.writeShort = this.fReadOnly? this.writeShortDefault : this.writeShortDirect; + }, + /** + * printAddr(sMessage) + * + * @this {MemoryPDP11} + * @param {string} sMessage + */ + printAddr: function(sMessage) { + if (DEBUG && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEM)) { + this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('%' + str.toHex(this.addr)) : '#' + this.id), true); + } + }, + /** + * addBreakpoint(off, fWrite) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {boolean} fWrite + */ + addBreakpoint: function(off, fWrite) { + if (!fWrite) { + if (this.cReadBreakpoints++ === 0) { + this.setReadAccess(MemoryPDP11.afnChecked, false); + } + if (DEBUG) this.printAddr("read breakpoint added to memory block"); + } + else { + if (this.cWriteBreakpoints++ === 0) { + this.setWriteAccess(MemoryPDP11.afnChecked, false); + } + if (DEBUG) this.printAddr("write breakpoint added to memory block"); + } + }, + /** + * removeBreakpoint(off, fWrite) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {boolean} fWrite + */ + removeBreakpoint: function(off, fWrite) { + if (!fWrite) { + if (--this.cReadBreakpoints === 0) { + this.resetReadAccess(); + if (DEBUG) this.printAddr("all read breakpoints removed from memory block"); + } + Component.assert(this.cReadBreakpoints >= 0); + } + else { + if (--this.cWriteBreakpoints === 0) { + this.resetWriteAccess(); + if (DEBUG) this.printAddr("all write breakpoints removed from memory block"); + } + Component.assert(this.cWriteBreakpoints >= 0); + } + }, + /** + * copyBreakpoints(dbg, mem) + * + * @this {MemoryPDP11} + * @param {DebuggerPDP11} [dbg] + * @param {MemoryPDP11} [mem] (outgoing MemoryPDP11 block to copy breakpoints from, if any) + */ + copyBreakpoints: function(dbg, mem) { + this.dbg = dbg; + this.cReadBreakpoints = this.cWriteBreakpoints = 0; + if (mem) { + if ((this.cReadBreakpoints = mem.cReadBreakpoints)) { + this.setReadAccess(MemoryPDP11.afnChecked, false); + } + if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) { + this.setWriteAccess(MemoryPDP11.afnChecked, false); + } + } + }, + /** + * readNone(off) + * + * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS + * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and + * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later + * when it performs a more exhaustive memory test, generating unwanted error messages in the process. + * + * TODO: Determine if we should have separate readByteNone(), readShortNone() and readLongNone() functions + * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely + * that a system would require nonexistent memory locations to return ALL bits set. + * + * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above + * MemoryPDP11 interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively. + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readNone: function readNone(off, addr) { + if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.CPU | MessagesPDP11.MEM) /* && !off */) { + this.dbg.message("attempt to read invalid block %" + str.toHex(this.addr), true); + } + return 0xff; + }, + /** + * writeNone(off, v, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses) + * @param {number} addr + */ + writeNone: function writeNone(off, v, addr) { + if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.CPU | MessagesPDP11.MEM) /* && !off */) { + this.dbg.message("attempt to write " + str.toHexWord(v) + " to invalid block %" + str.toHex(this.addr), true); + } + }, + /** + * readShortDefault(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readShortDefault: function readShortDefault(off, addr) { + return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8); + }, + /** + * writeShortDefault(off, w, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} w + * @param {number} addr + */ + writeShortDefault: function writeShortDefault(off, w, addr) { + this.writeByte(off++, w & 0xff, addr++); + this.writeByte(off, w >> 8, addr); + }, + /** + * readByteMemory(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readByteMemory: function readByteMemory(off, addr) { + if (BYTEARRAYS) { + return this.ab[off]; + } + return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff); + }, + /** + * readShortMemory(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readShortMemory: function readShortMemory(off, addr) { + if (BYTEARRAYS) { + return this.ab[off] | (this.ab[off + 1] << 8); + } + var w; + var idw = off >> 2; + var nShift = (off & 0x3) << 3; + var dw = (this.adw[idw] >> nShift); + if (nShift < 24) { + w = dw & 0xffff; + } else { + w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8); + } + return w; + }, + /** + * writeByteMemory(off, b, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} b + * @param {number} addr + */ + writeByteMemory: function writeByteMemory(off, b, addr) { + if (BYTEARRAYS) { + this.ab[off] = b; + } else { + var idw = off >> 2; + var nShift = (off & 0x3) << 3; + this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift); + } + this.fDirty = true; + }, + /** + * writeShortMemory(off, w, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} w + * @param {number} addr + */ + writeShortMemory: function writeShortMemory(off, w, addr) { + if (BYTEARRAYS) { + this.ab[off] = (w & 0xff); + this.ab[off + 1] = (w >> 8); + } else { + var idw = off >> 2; + var nShift = (off & 0x3) << 3; + if (nShift < 24) { + this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift); + } else { + this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24); + idw++; + this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8); + } + } + this.fDirty = true; + }, + /** + * readByteChecked(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readByteChecked: function readByteChecked(off, addr) { + if (DEBUGGER && this.dbg && this.addr != null) { + this.dbg.checkMemoryRead(this.addr + off); + } + return this.readByteDirect(off, addr); + }, + /** + * readShortChecked(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readShortChecked: function readShortChecked(off, addr) { + if (DEBUGGER && this.dbg && this.addr != null) { + this.dbg.checkMemoryRead(this.addr + off, 2); + } + return this.readShortDirect(off, addr); + }, + /** + * writeByteChecked(off, b, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @param {number} b + */ + writeByteChecked: function writeByteChecked(off, b, addr) { + if (DEBUGGER && this.dbg && this.addr != null) { + this.dbg.checkMemoryWrite(this.addr + off); + } + if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr); + }, + /** + * writeShortChecked(off, w, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @param {number} w + */ + writeShortChecked: function writeShortChecked(off, w, addr) { + if (DEBUGGER && this.dbg && this.addr != null) { + this.dbg.checkMemoryWrite(this.addr + off, 2) + } + if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeShortDirect(off, w, addr); + }, + /** + * readByteBE(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readByteBE: function readByteBE(off, addr) { + return this.ab[off]; + }, + /** + * readByteLE(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readByteLE: function readByteLE(off, addr) { + return this.ab[off]; + }, + /** + * readShortBE(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readShortBE: function readShortBE(off, addr) { + return this.dv.getUint16(off, true); + }, + /** + * readShortLE(off, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @return {number} + */ + readShortLE: function readShortLE(off, addr) { + /* + * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read + * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts. + */ + return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1]; + }, + /** + * writeByteBE(off, b, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} b + * @param {number} addr + */ + writeByteBE: function writeByteBE(off, b, addr) { + this.ab[off] = b; + this.fDirty = true; + }, + /** + * writeByteLE(off, b, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @param {number} b + */ + writeByteLE: function writeByteLE(off, b, addr) { + this.ab[off] = b; + this.fDirty = true; + }, + /** + * writeShortBE(off, w, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @param {number} w + */ + writeShortBE: function writeShortBE(off, w, addr) { + this.dv.setUint16(off, w, true); + this.fDirty = true; + }, + /** + * writeShortLE(off, w, addr) + * + * @this {MemoryPDP11} + * @param {number} off + * @param {number} addr + * @param {number} w + */ + writeShortLE: function writeShortLE(off, w, addr) { + /* + * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write + * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts. + */ + if (off & 0x1) { + this.ab[off] = w; + this.ab[off+1] = w >> 8; + } else { + this.aw[off >> 1] = w; + } + this.fDirty = true; + } +}; + +/* + * This is the effective definition of afnNone, but we need not fully define it, because setAccess() + * uses these defaults when any of the 6 handlers (ie, 3 read handlers and 3 write handlers) are undefined. + * +MemoryPDP11.afnNone = [MemoryPDP11.prototype.readNone, MemoryPDP11.prototype.readShortDefault, MemoryPDP11.prototype.writeNone, MemoryPDP11.prototype.writeShortDefault]; + */ + +MemoryPDP11.afnNone = []; +MemoryPDP11.afnMemory = [MemoryPDP11.prototype.readByteMemory, MemoryPDP11.prototype.readShortMemory, MemoryPDP11.prototype.writeByteMemory, MemoryPDP11.prototype.writeShortMemory]; +MemoryPDP11.afnChecked = [MemoryPDP11.prototype.readByteChecked, MemoryPDP11.prototype.readShortChecked, MemoryPDP11.prototype.writeByteChecked, MemoryPDP11.prototype.writeShortChecked]; + +if (TYPEDARRAYS) { + MemoryPDP11.afnArrayBE = [MemoryPDP11.prototype.readByteBE, MemoryPDP11.prototype.readShortBE, MemoryPDP11.prototype.writeByteBE, MemoryPDP11.prototype.writeShortBE]; + MemoryPDP11.afnArrayLE = [MemoryPDP11.prototype.readByteLE, MemoryPDP11.prototype.readShortLE, MemoryPDP11.prototype.writeByteLE, MemoryPDP11.prototype.writeShortLE]; +} + +if (NODE) module.exports = MemoryPDP11; diff --git a/modules/pdp11/lib/messages.js b/modules/pdp11/lib/messages.js new file mode 100644 index 000000000..4b0ac3814 --- /dev/null +++ b/modules/pdp11/lib/messages.js @@ -0,0 +1,89 @@ +/** + * @fileoverview Defines PDP11 message categories. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +var MessagesPDP11 = { + CPU: 0x00000001, + BUS: 0x00000040, + MEM: 0x00000080, + KEYBOARD: 0x00010000, + KEYS: 0x00020000, + DISK: 0x00200000, + SERIAL: 0x00800000, + SPEAKER: 0x02000000, + COMPUTER: 0x04000000, + LOG: 0x10000000, + WARN: 0x20000000, + BUFFER: 0x40000000, + HALT: 0x80000000|0 +}; + +/* + * Message categories supported by the messageEnabled() function and other assorted message + * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as + * needed. The Debugger's message command ("m") is used to turn message categories on and off, + * like so: + * + * m port on + * m port off + * ... + * + * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be + * aware that changing the bit values could break saved Debugger states (not a huge concern, just + * something to be aware of). + */ +MessagesPDP11.CATEGORIES = { + "cpu": MessagesPDP11.CPU, + "bus": MessagesPDP11.BUS, + "mem": MessagesPDP11.MEM, + "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 + "disk": MessagesPDP11.DISK, + "serial": MessagesPDP11.SERIAL, + "speaker": MessagesPDP11.SPEAKER, + "computer": MessagesPDP11.COMPUTER, + "log": MessagesPDP11.LOG, + "warn": MessagesPDP11.WARN, + /* + * Now we turn to message actions rather than message types; for example, setting "halt" + * on or off doesn't enable "halt" messages, but rather halts the CPU on any message above. + * + * Similarly, "m buffer on" turns on message buffering, deferring the display of all messages + * until "m buffer off" is issued. + */ + "buffer": MessagesPDP11.BUFFER, + "halt": MessagesPDP11.HALT +}; + +if (NODE) module.exports = MessagesPDP11; diff --git a/modules/pdp11/lib/nodebugger.js b/modules/pdp11/lib/nodebugger.js new file mode 100644 index 000000000..4b4f7d92a --- /dev/null +++ b/modules/pdp11/lib/nodebugger.js @@ -0,0 +1,48 @@ +/** + * @fileoverview Compile-time definitions for Debugger-less configurations. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +/* + * 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 + * "type skeleton", which also solves some type-related warnings we would otherwise have if we tried to remove + * debugger.js from the compilation process altogether. + * + * However, when we're in "development mode" and running uncompiled code in debugger-less configurations, + * I would still like to skip loading debugger.js altogether. To do that, we must arrange for this additional file, + * nodebugger.js, to be loaded immediately after defines.js, *explicitly* overriding the previously defined value + * of DEBUGGER with *false*. + */ +DEBUGGER = false; diff --git a/modules/pdp11/lib/panel.js b/modules/pdp11/lib/panel.js new file mode 100644 index 000000000..e0421bca3 --- /dev/null +++ b/modules/pdp11/lib/panel.js @@ -0,0 +1,185 @@ +/** + * @fileoverview Implements the PDP11 Panel component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var usr = require("../../shared/lib/usrlib"); + var web = require("../../shared/lib/weblib"); + var Component = require("../../shared/lib/component"); + var PDP11 = require("./defines"); + var BusPDP11 = require("./bus"); + var CPUDefPDP11 = require("./cpudef"); + var MemoryPDP11 = require("./memory"); +} + +/** + * PanelPDP11(parmsPanel) + * + * The PanelPDP11 component has no required (parmsPanel) properties. + * + * @constructor + * @extends Component + * @param {Object} parmsPanel + */ +function PanelPDP11(parmsPanel) +{ + Component.call(this, "Panel", parmsPanel, PanelPDP11); +} + +Component.subclass(PanelPDP11); + +/** + * setBinding(sHTMLType, sBinding, control, sValue) + * + * Most panel layouts don't have bindings of their own, so we pass along all binding requests to the + * Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any component + * that doesn't recognize the specified binding should simply ignore it. + * + * @this {PanelPDP11} + * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") + * @param {Object} control is the HTML control DOM object (eg, HTMLButtonElement) + * @param {string} [sValue] optional data value + * @return {boolean} true if binding was successful, false if unrecognized binding request + */ +PanelPDP11.prototype.setBinding = function(sHTMLType, sBinding, control, sValue) +{ + if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true; + if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true; + if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true; + return this.parent.setBinding.call(this, sHTMLType, sBinding, control, sValue); +}; + +/** + * initBus(cmp, bus, cpu, dbg) + * + * @this {PanelPDP11} + * @param {ComputerPDP11} cmp + * @param {BusPDP11} bus + * @param {CPUStatePDP11} cpu + * @param {DebuggerPDP11} dbg + */ +PanelPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) +{ + this.cmp = cmp; + this.bus = bus; + this.cpu = cpu; + this.dbg = dbg; +}; + +/** + * powerUp(data, fRepower) + * + * @this {PanelPDP11} + * @param {Object|null} data + * @param {boolean} [fRepower] + * @return {boolean} true if successful, false if failure + */ +PanelPDP11.prototype.powerUp = function(data, fRepower) +{ + if (!fRepower) PanelPDP11.init(); + return true; +}; + +/** + * powerDown(fSave, fShutdown) + * + * @this {PanelPDP11} + * @param {boolean} [fSave] + * @param {boolean} [fShutdown] + * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure + */ +PanelPDP11.prototype.powerDown = function(fSave, fShutdown) +{ + return true; +}; + +/** + * updateStatus(fForce) + * + * Update function for Panels containing elements with high-frequency display requirements. + * + * For older (and slower) DOM-based display elements, those are sill being managed by the CPUState component, + * so it has its own updateStatus() handler. + * + * The Computer's updateStatus() handler is currently responsible for calling both our handler and the CPU's handler. + * + * @this {PanelPDP11} + * @param {boolean} [fForce] (true will display registers even if the CPU is running and "live" registers are not enabled) + */ +PanelPDP11.prototype.updateStatus = function(fForce) +{ +}; + +/** + * PanelPDP11.init() + * + * This function operates on every HTML element of class "panel", extracting the + * JSON-encoded parameters for the PanelPDP11 constructor from the element's "data-value" + * attribute, invoking the constructor to create a PanelPDP11 component, and then binding + * any associated HTML controls to the new component. + * + * NOTE: Unlike most other component init() functions, this one is designed to be + * called multiple times: once at load time, so that we can bind our print() + * function to the panel's output control ASAP, and again when the Computer component + * is verifying that all components are ready and invoking their powerUp() functions. + * + * Our powerUp() method gives us a second opportunity to notify any components that + * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they + * might want to use. + */ +PanelPDP11.init = function() +{ + var fReady = false; + var aePanels = Component.getElementsByClass(document, PDP11.APPCLASS, "panel"); + for (var iPanel=0; iPanel < aePanels.length; iPanel++) { + var ePanel = aePanels[iPanel]; + var parmsPanel = Component.getComponentParms(ePanel); + var panel = Component.getComponentByID(parmsPanel['id']); + if (!panel) { + fReady = true; + panel = new PanelPDP11(parmsPanel); + } + Component.bindComponentControls(panel, ePanel, PDP11.APPCLASS); + if (fReady) panel.setReady(); + } +}; + +/* + * Initialize every Panel module on the page. + */ +web.onInit(PanelPDP11.init); + +if (NODE) module.exports = PanelPDP11; diff --git a/modules/pdp11/lib/ram.js b/modules/pdp11/lib/ram.js new file mode 100644 index 000000000..528295035 --- /dev/null +++ b/modules/pdp11/lib/ram.js @@ -0,0 +1,199 @@ +/** + * @fileoverview Implements the PDP11 RAM component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"use strict"; + +if (NODE) { + var str = require("../../shared/lib/strlib"); + var web = require("../../shared/lib/weblib"); + var Component = require("../../shared/lib/component"); + var State = require("../../shared/lib/state"); + var PDP11 = require("./defines"); + var MemoryPDP11 = require("./memory"); + var ROMPDP11 = require("./rom"); +} + +/** + * RAMPDP11(parmsRAM) + * + * The RAMPDP11 component expects the following (parmsRAM) properties: + * + * addr: starting physical address of RAM (default is 0) + * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings) + * + * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the + * Computer component calls powerUp(). + * + * @constructor + * @extends Component + * @param {Object} parmsRAM + */ +function RAMPDP11(parmsRAM) +{ + Component.call(this, "RAM", parmsRAM, RAMPDP11); + + this.addrRAM = parmsRAM['addr']; + this.sizeRAM = parmsRAM['size']; + this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified + this.fAllocated = false; +} + +Component.subclass(RAMPDP11); + +/** + * initBus(cmp, bus, cpu, dbg) + * + * @this {RAMPDP11} + * @param {ComputerPDP11} cmp + * @param {BusPDP11} bus + * @param {CPUStatePDP11} cpu + * @param {DebuggerPDP11} dbg + */ +RAMPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) +{ + this.bus = bus; + this.cpu = cpu; + this.dbg = dbg; + this.setReady(); +}; + +/** + * powerUp(data, fRepower) + * + * @this {RAMPDP11} + * @param {Object|null} data + * @param {boolean} [fRepower] + * @return {boolean} true if successful, false if failure + */ +RAMPDP11.prototype.powerUp = function(data, fRepower) +{ + if (!fRepower) { + /* + * The Computer powers up the CPU last, at which point CPUState state is restored, + * which includes the Bus state, and since we use the Bus to allocate all our memory, + * memory contents are already restored for us, so we don't need the usual restore + * logic. We just need to call reset(), to allocate memory for the RAM. + */ + this.reset(); + } + return true; +}; + +/** + * powerDown(fSave, fShutdown) + * + * @this {RAMPDP11} + * @param {boolean} [fSave] + * @param {boolean} [fShutdown] + * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure + */ +RAMPDP11.prototype.powerDown = function(fSave, fShutdown) +{ + /* + * The Computer powers down the CPU first, at which point CPUState state is saved, + * which includes the Bus state, and since we use the Bus component to allocate all + * our memory, memory contents are already saved for us, so we don't need the usual + * save logic. + */ + return (fSave)? this.save() : true; +}; + +/** + * reset() + * + * @this {RAMPDP11} + */ +RAMPDP11.prototype.reset = function() +{ + if (!this.fAllocated && this.sizeRAM) { + if (this.bus.addMemory(this.addrRAM, this.sizeRAM, MemoryPDP11.TYPE.RAM)) { + this.fAllocated = true; + } + } + if (!this.fAllocated) { + Component.error("No RAM allocated"); + } +}; + +/** + * save() + * + * This implements save support for the RAMPDP11 component. + * + * @this {RAMPDP11} + * @return {Object} + */ +RAMPDP11.prototype.save = function() +{ + return null; +}; + +/** + * restore(data) + * + * This implements restore support for the RAMPDP11 component. + * + * @this {RAMPDP11} + * @param {Object} data + * @return {boolean} true if successful, false if failure + */ +RAMPDP11.prototype.restore = function(data) +{ + return true; +}; + +/** + * RAMPDP11.init() + * + * This function operates on every HTML element of class "ram", extracting the + * JSON-encoded parameters for the RAMPDP11 constructor from the element's "data-value" + * attribute, invoking the constructor to create a RAMPDP11 component, and then binding + * any associated HTML controls to the new component. + */ +RAMPDP11.init = function() +{ + var aeRAM = Component.getElementsByClass(document, PDP11.APPCLASS, "ram"); + for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) { + var eRAM = aeRAM[iRAM]; + var parmsRAM = Component.getComponentParms(eRAM); + var ram = new RAMPDP11(parmsRAM); + Component.bindComponentControls(ram, eRAM, PDP11.APPCLASS); + } +}; + +/* + * Initialize all the RAMPDP11 modules on the page. + */ +web.onInit(RAMPDP11.init); + +if (NODE) module.exports = RAMPDP11; diff --git a/modules/pdp11/lib/rom.js b/modules/pdp11/lib/rom.js new file mode 100644 index 000000000..5dfd40a2d --- /dev/null +++ b/modules/pdp11/lib/rom.js @@ -0,0 +1,391 @@ +/** + * @fileoverview Implements the PDP11 ROM component. + * @author Jeff Parsons + * @version 1.0 + * Created 2016-Sep-03 + * + * This file is part of PCjs, a computer emulation software project at . + * + * It has been adapted from the JavaScript PDP 11/70 Emulator v1.3 written by Paul Nankervis + * (paulnank@hotmail.com) as of August 2016 from http://skn.noip.me/pdp11/pdp11.html. This code + * may be used freely provided the original author name is acknowledged in any modified source code. + * + * PCjs is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCjs. If not, + * see . + * + * You are required to include the above copyright notice in every source code file of every + * copy or modified version of this work, and to display that copyright notice on every screen + * that loads or runs any version of this software (see COPYRIGHT in /modules/shared/lib/defines.js). + * + * Some PCjs files also attempt to load external resource files, such as character-image files, + * ROM files, and disk image files. Those external resource files are not considered part of PCjs + * for purposes of the GNU General Public License, and the author does not claim any copyright + * as to their contents. + */ + +"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 CPUDefPDP11 = require("./cpudef"); + var MemoryPDP11 = require("./memory"); +} + +/** + * ROMPDP11(parmsROM) + * + * The ROMPDP11 component expects the following (parmsROM) properties: + * + * addr: physical address of ROM + * size: amount of ROM, in bytes + * alias: physical alias address (null if none) + * file: name of ROM data file + * writable: true to make ROM writable (default is false) + * + * 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. + * + * Finally, while making ROM "writable" may seem a contradiction in terms, I want to be able to load selected + * CP/M binary files into memory purely for testing purposes, and the RAM component has no "file" option, so the + * simplest solution was to add the option to load binary files into memory as "writable" ROMs. + * + * Moreover, if a "writable" ROM is installed at addr 0x100, that triggers our "Fake CP/M" support, providing + * a quick-and-dirty means of loading simple CP/M test binaries. See addROM() for details. + * + * @constructor + * @extends Component + * @param {Object} parmsROM + */ +function ROMPDP11(parmsROM) +{ + Component.call(this, "ROM", parmsROM, ROMPDP11); + + this.abROM = null; + this.addrROM = parmsROM['addr']; + this.sizeROM = parmsROM['size']; + this.fWritable = parmsROM['writable']; + + /* + * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of + * physical addresses; eg: + * + * [0xf0000,0xffff0000,0xffff8000] + * + * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any + * aliased locations listed under a separate property. + * + * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null. + */ + this.addrAlias = parmsROM['alias']; + + this.sFilePath = parmsROM['file']; + this.sFileName = str.getBaseName(this.sFilePath); + + if (this.sFilePath) { + var sFileURL = this.sFilePath; + if (DEBUG) this.log('load("' + sFileURL + '")'); + /* + * If the selected ROM file has a ".json" extension, then we assume it's pre-converted + * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a ".hex" extension. + * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format. + */ + var sFileExt = str.getExtension(this.sFileName); + if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) { + sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true'; + } + var rom = this; + web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) { + rom.doneLoad(sURL, sResponse, nErrorCode); + }); + } +} + +Component.subclass(ROMPDP11); + +/* + * NOTE: There's currently no need for this component to have a reset() function, since + * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize. + * + * OK, well, I take that back, because the Debugger, if installed, has the ability to modify + * ROM contents, so in that case, having a reset() function that restores the original ROM data + * might be useful; then again, it might not, depending on what you're trying to debug. + * + * If we do add reset(), then we'll want to change copyROM() to hang onto the original + * ROM data; currently, we release it after copying it into the read-only memory allocated + * via bus.addMemory(). + */ + +/** + * initBus(cmp, bus, cpu, dbg) + * + * @this {ROMPDP11} + * @param {ComputerPDP11} cmp + * @param {BusPDP11} bus + * @param {CPUStatePDP11} cpu + * @param {DebuggerPDP11} dbg + */ +ROMPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) +{ + this.bus = bus; + this.cpu = cpu; + this.dbg = dbg; + this.copyROM(); +}; + +/** + * powerUp(data, fRepower) + * + * @this {ROMPDP11} + * @param {Object|null} data + * @param {boolean} [fRepower] + * @return {boolean} true if successful, false if failure + */ +ROMPDP11.prototype.powerUp = function(data, fRepower) +{ + if (this.aSymbols) { + if (this.dbg) { + this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols); + } + /* + * Our only role in the handling of symbols is to hand them off to the Debugger at our + * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast. + */ + delete this.aSymbols; + } + return true; +}; + +/** + * powerDown(fSave, fShutdown) + * + * Since we have nothing to do on powerDown(), and no state to return, we could simply omit + * this function. But it doesn't hurt anything, and maybe we'll use our state to save something + * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have + * created, above and beyond those symbols we automatically loaded, if any, along with the ROM). + * + * @this {ROMPDP11} + * @param {boolean} [fSave] + * @param {boolean} [fShutdown] + * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure + */ +ROMPDP11.prototype.powerDown = function(fSave, fShutdown) +{ + return true; +}; + +/** + * doneLoad(sURL, sROMData, nErrorCode) + * + * @this {ROMPDP11} + * @param {string} sURL + * @param {string} sROMData + * @param {number} nErrorCode (response from server if anything other than 200) + */ +ROMPDP11.prototype.doneLoad = function(sURL, sROMData, nErrorCode) +{ + if (nErrorCode) { + this.notice("Unable to load system ROM (error " + nErrorCode + ": " + sURL + ")"); + return; + } + + Component.addMachineResource(this.idMachine, sURL, sROMData); + + if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") { + try { + /* + * The most likely source of any exception will be here: parsing the JSON-encoded ROM data. + */ + var rom = eval("(" + sROMData + ")"); + var ab = rom['bytes']; + var adw = rom['data']; + + if (ab) { + this.abROM = ab; + } + else if (adw) { + /* + * Convert all the DWORDs into BYTEs, so that subsequent code only has to deal with abROM. + */ + this.abROM = new Array(adw.length * 4); + for (var idw = 0, ib = 0; idw < adw.length; idw++) { + this.abROM[ib++] = adw[idw] & 0xff; + this.abROM[ib++] = (adw[idw] >> 8) & 0xff; + this.abROM[ib++] = (adw[idw] >> 16) & 0xff; + this.abROM[ib++] = (adw[idw] >> 24) & 0xff; + } + } + else { + this.abROM = rom; + } + + this.aSymbols = rom['symbols']; + + if (!this.abROM.length) { + Component.error("Empty ROM: " + sURL); + return; + } + else if (this.abROM.length == 1) { + Component.error(this.abROM[0]); + return; + } + } catch (e) { + this.notice("ROM data error: " + e.message); + return; + } + } + else { + /* + * Parse the ROM data manually; we assume it's in "simplified" hex form (a series of hex byte-values + * separated by whitespace). + */ + var sHexData = sROMData.replace(/\n/gm, " ").replace(/ +$/, ""); + var asHexData = sHexData.split(" "); + this.abROM = new Array(asHexData.length); + for (var i = 0; i < asHexData.length; i++) { + this.abROM[i] = str.parseInt(asHexData[i], 16); + } + } + this.copyROM(); +}; + +/** + * copyROM() + * + * This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place + * until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both + * those criteria are satisfied, the component becomes "ready". + * + * @this {ROMPDP11} + */ +ROMPDP11.prototype.copyROM = function() +{ + if (!this.isReady()) { + if (!this.sFilePath) { + this.setReady(); + } + else if (this.abROM && this.bus) { + /* + * If no explicit size was specified, then use whatever the actual size is. + */ + if (!this.sizeROM) { + this.sizeROM = this.abROM.length; + } + if (this.abROM.length != this.sizeROM) { + /* + * Note that setError() sets the component's fError flag, which in turn prevents setReady() from + * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a + * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be + * times when we'd like to forge ahead anyway. + */ + this.setError("ROM size (" + str.toHexLong(this.abROM.length) + ") does not match specified size (" + str.toHexLong(this.sizeROM) + ")"); + } + else if (this.addROM(this.addrROM)) { + + var aliases = []; + if (typeof this.addrAlias == "number") { + aliases.push(this.addrAlias); + } else if (this.addrAlias != null && this.addrAlias.length) { + aliases = this.addrAlias; + } + for (var i = 0; i < aliases.length; i++) { + this.cloneROM(aliases[i]); + } + /* + * We used to hang onto the original ROM data so that we could restore any bytes the CPU overwrote, + * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's + * no longer necessary. + * + * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs. + * That may be useful for "resumable" machines that save/restore all dirty block of memory, regardless + * 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.abROM; + } + this.setReady(); + } + } +}; + +/** + * addROM(addr) + * + * @this {ROMPDP11} + * @param {number} addr + * @return {boolean} + */ +ROMPDP11.prototype.addROM = function(addr) +{ + if (this.bus.addMemory(addr, this.sizeROM, this.fWritable? MemoryPDP11.TYPE.RAM : MemoryPDP11.TYPE.ROM)) { + if (DEBUG) this.log("addROM(): copying ROM to " + str.toHexLong(addr) + " (" + str.toHexLong(this.abROM.length) + " bytes)"); + var i; + for (i = 0; i < this.abROM.length; i++) { + this.bus.setByteDirect(addr + i, this.abROM[i]); + } + return true; + } + /* + * We don't need to report an error here, because addMemory() already takes care of that. + */ + return false; +}; + +/** + * cloneROM(addr) + * + * For ROMs with one or more alias addresses, we used to call addROM() for each address. However, + * that obviously wasted memory, since each alias was an independent copy, and if you used the + * Debugger to edit the ROM in one location, the changes would not appear in the other location(s). + * + * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods + * to manually get and set the blocks of any memory range, it is now possible to create true aliases. + * + * @this {ROMPDP11} + * @param {number} addr + */ +ROMPDP11.prototype.cloneROM = function(addr) +{ + var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM); + this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks); +}; + +/** + * ROMPDP11.init() + * + * This function operates on every HTML element of class "rom", extracting the + * JSON-encoded parameters for the ROMPDP11 constructor from the element's "data-value" + * attribute, invoking the constructor to create a ROMPDP11 component, and then binding + * any associated HTML controls to the new component. + */ +ROMPDP11.init = function() +{ + var aeROM = Component.getElementsByClass(document, PDP11.APPCLASS, "rom"); + for (var iROM = 0; iROM < aeROM.length; iROM++) { + var eROM = aeROM[iROM]; + var parmsROM = Component.getComponentParms(eROM); + var rom = new ROMPDP11(parmsROM); + Component.bindComponentControls(rom, eROM, PDP11.APPCLASS); + } +}; + +/* + * Initialize all the ROMPDP11 modules on the page. + */ +web.onInit(ROMPDP11.init); + +if (NODE) module.exports = ROMPDP11; diff --git a/modules/shared/lib/embed.js b/modules/shared/lib/embed.js index 39de4ea9a..4737fa884 100644 --- a/modules/shared/lib/embed.js +++ b/modules/shared/lib/embed.js @@ -577,6 +577,21 @@ function embedPC8080(idMachine, sXMLFile, sXSLFile, sParms) return embedMachine("PC8080", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms); } +/** + * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms) + * + * @param {string} idMachine + * @param {string} sXMLFile + * @param {string} sXSLFile + * @param {string} [sParms] + * @return {boolean} true if successful, false if error + */ +function embedPDP11(idMachine, sXMLFile, sXSLFile, sParms) +{ + if (fAsync) web.enablePageEvents(false); + return embedMachine("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. @@ -591,6 +606,9 @@ if (APPNAME == "PCx86") { if (APPNAME == "PC8080") { window['embedPC8080'] = embedPC8080; } +if (APPNAME == "PDP11") { + window['embedPDP11'] = embedPDP11; +} window['enableEvents'] = web.enablePageEvents; window['sendEvent'] = web.sendPageEvent; diff --git a/package.json b/package.json index 4acf559b4..13601eb3c 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "./modules/shared/lib/embed.js", "./modules/shared/lib/save.js" ], - "pc8080Files": [ + "pc8080Files": [ "./modules/shared/lib/defines.js", "./modules/shared/lib/dumpapi.js", "./modules/shared/lib/reportapi.js", @@ -159,5 +159,31 @@ "./modules/pc8080/lib/computer.js", "./modules/shared/lib/state.js", "./modules/shared/lib/embed.js" + ], + "pdp11Files": [ + "./modules/shared/lib/defines.js", + "./modules/shared/lib/dumpapi.js", + "./modules/shared/lib/reportapi.js", + "./modules/shared/lib/userapi.js", + "./modules/shared/lib/strlib.js", + "./modules/shared/lib/usrlib.js", + "./modules/shared/lib/weblib.js", + "./modules/shared/lib/component.js", + "./modules/pdp11/lib/defines.js", + "./modules/pdp11/lib/cpudef.js", + "./modules/pdp11/lib/messages.js", + "./modules/pdp11/lib/panel.js", + "./modules/pdp11/lib/bus.js", + "./modules/pdp11/lib/memory.js", + "./modules/pdp11/lib/cpu.js", + "./modules/pdp11/lib/cpustate.js", + "./modules/pdp11/lib/cpuops.js", + "./modules/pdp11/lib/rom.js", + "./modules/pdp11/lib/ram.js", + "./modules/pdp11/lib/keyboard.js", + "./modules/pdp11/lib/debugger.js", + "./modules/pdp11/lib/computer.js", + "./modules/shared/lib/state.js", + "./modules/shared/lib/embed.js" ] } diff --git a/versions/c1pjs/1.24.2/c1p-dbg.js b/versions/c1pjs/1.24.2/c1p-dbg.js new file mode 100644 index 000000000..79867f56c --- /dev/null +++ b/versions/c1pjs/1.24.2/c1p-dbg.js @@ -0,0 +1,166 @@ +(function(){var f;function p(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function q(a){return"0x"+p(a,2)}function r(a){return"0x"+p(a,4)}function aa(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("&");0":">",'"':""","'":"'"};function da(a){return a.replace(/[&<>"']/g,function(a){return ca[a]})}var ea=Date.now||function(){return+new Date}; +function t(a,b){var c=0,d=null;if("object"==typeof resources&&(d=resources[a]))b&&b(a,d,c);else if("function"==typeof resources)resources(a,function(c,d){b&&b(a,c,d)});else{var e=window.XMLHttpRequest?new window.XMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");e.onreadystatechange=function(){4===e.readyState&&(d=e.responseText,200==e.status||!e.status&&d.length&&"file:"==(window?window.location.protocol:"file:")||(c=e.status||-1),b&&b(a,d,c))};e.open("GET",a,!0);e.send()}} +function u(a){window&&window.alert(a)}function v(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}function fa(a,b,c){function d(){--a;0<=a&&(b()||(a=0));0b?this.eb=this.id:(this.rb=this.id.substr(0,b),this.eb=this.id.substr(b+1));this[a]=c;this.C={Za:!1,Ba:!1,kb:!1,M:!1,Ca:!1};this.cb=null;this.C.Ca=!1;this.H={};this.u=null;this.la=d||0;B.push(this)}var na=void 0,oa={}; +if(window){na||(na=window.location.search.substr(1));for(var pa,qa=/\+/g,ra=/([^&=]+)=?([^&]*)/g;pa=ra.exec(na);)oa[decodeURIComponent(pa[1].replace(qa," "))]=decodeURIComponent(pa[2].replace(qa," "))}function sa(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b} +function C(a){var b;b||(b=A);a.prototype=sa(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var D=window.PCjs.Machines||(window.PCjs.Machines={}),B=window.PCjs.Components||(window.PCjs.Components=[])}else D={},B=[];function ta(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;cBa(a.P,b,c,d,e)&&(a.oa>b&&(a.oa=b),a.pa=a.P[d][0]&&b<=a.P[d][1]&&a.P[d][3].call(a.P[d][2],b,c)}function N(a,b,c,d,e){0>Ba(a.K,b,c,d,e)&&(a.da>b&&(a.da=b),a.ea=a.K[d][0]&&b<=a.K[d][1]&&a.K[d][3].call(a.K[d][2],b,c)}function Ba(a,b,c,d,e){for(var g=0;ga.Ra&&a.ta&&(d=a.ta);d>a.Ma&&2>a.speed&&(d=a.Ma);a.lb=Math.round(1E3/30);a.ja=Math.floor(1E6/c*d);a.ra=Math.floor(1E6/30*d);a.Xa=Math.floor(1E6/a.Ja*d);a.Wa=Math.floor(1E6/a.Ia*d);b||(a.R=a.ra,a.Z=a.Xa,a.V=a.Wa);a.Aa=0} +function Ha(a){var b=ea(),c=a.lb;a.$&&(c=Math.round(c*a.$/a.ra));c=c-(b-a.mb);if(b=b-a.Oa)a.ta=Math.round(a.U/(100*b))/10,864E5<=b&&M(a);0>c?c=0:1==a.speed?a.ta<=a.Ma&&(c=0):2==a.speed&&(c=0);a.Aa+=a.$;return c} +f.va=function(){if(I(this,!0)){this.C.ma||(M(this),this.J&&this.J.start(),this.C.ma=!0,this.H.run&&(this.H.run.innerHTML="Halt"),this.ca());1E6<=this.Aa&&Ea(this,!0);this.$=0;this.mb=ea();try{do{this.step(this.ja);var a=this.L-this.D;this.U+=a;this.$+=a;this.L=this.D=0;this.Z-=this.ja;0>=this.Z&&(this.Z+=this.Xa,this.ib());this.V-=this.ja;0>=this.V&&(this.V+=this.Wa,Fa(this));this.R-=this.ja;if(0>=this.R){this.R+=this.ra;break}}while(this.C.ma)}catch(b){this.aa();this.update();I(this,!1);ua(this, +b.stack||b.message);return}setTimeout(function(a){return function(){a.va()}}(this),Ha(this))}else this.update(),this.J&&this.J.stop(this.Oa,this.U)}; +f.step=function(a){var b=!0;this.b=this.g=-1;var c;if(c=a&&this.u)c=this.u,c=0=d.xa.length&&(d.La=0));d=!!g}if(d){b=void 0;this.aa();break}this.f++;this.o[a].call(this);if(0<=this.b){this.b>=this.oa&&this.b<=this.pa&&Ca(this,this.b,this.f);if(d=c)d=this.u,e=!1,Ia(d,this.b,d.wa,"read")&&(e=!0),d=!!e;if(d){b=!1;this.aa(); +break}this.b=-1}else if(0<=this.g){this.g>=this.da&&this.g<=this.ea&&Da(this,this.g,this.f);if(d=c){d=this.u;var e=this.g,g=this.a[this.g],h=!1;(g&255)!=g&&(d.l("invalid value at "+r(e)+": "+g),h=!0);Ia(d,e,d.ya,"write")&&(h=!0);d=!!h}if(d){b=!1;this.aa();break}this.g=-1}this.D-=this.gb[a]}while(0>1)&128?64:0),b=b|(a.i&128?128:0);return a.B&60|b} +function La(a){a.B|=8;a.o[97]=a.Yb;a.o[101]=a.$b;a.o[105]=a.Xb;a.o[109]=a.Ub;a.o[113]=a.Zb;a.o[117]=a.ac;a.o[121]=a.Wb;a.o[125]=a.Vb;a.o[225]=a.ne;a.o[229]=a.pe;a.o[233]=a.me;a.o[237]=a.je;a.o[241]=a.oe;a.o[245]=a.qe;a.o[249]=a.le;a.o[253]=a.ke}function Ma(a){a.B&=-9;a.o[97]=a.xb;a.o[101]=a.zb;a.o[105]=a.wb;a.o[109]=a.tb;a.o[113]=a.yb;a.o[117]=a.Ab;a.o[121]=a.vb;a.o[125]=a.ub;a.o[225]=a.Fb;a.o[229]=a.Hb;a.o[233]=a.Eb;a.o[237]=a.Bb;a.o[241]=a.Gb;a.o[245]=a.Ib;a.o[249]=a.Db;a.o[253]=a.Cb} +function P(a,b,c){var d=a.c&256?1:0,e=(b&15)+(c&15)+d;10<=e&&(e=e+6&15|16);e+=(b&240)+(c&240);a.A=b^c;a.v=e;a.i=e&255;160<=e&&(e+=96);512<=e&&(e-=256);a.c=e;a.j=b+c+d&255;a.D--;return e&255}function Q(a,b,c){var d=a.c&256?0:1,e=(b&15)-(c&15)-d;0>e&&(e=(e-6&15)-16);e+=(b&240)-(c&240);0>e&&(e-=96);a.i=a.j=(a.c=b-c-d)&255;a.A=b^c;a.v=a.c;a.c^=256;a.D--;return e&255}function ya(a){a.h=0;a.w=0;a.F=0;a.G=256;a.B=0;a.i=0;a.j=0;a.A=0;a.v=0;a.c=0;a.f=0;a.b=-1;a.g=-1;a.ta=0;a.U=a.L=a.D=0} +f.wc=function(){this.f++;this.a[this.G--]=this.f>>8;this.G|=256;this.a[this.G--]=this.f&255;this.G|=256;this.B|=16;this.B=Ga(this);this.a[this.G--]=this.B;this.G|=256;this.B&=239;this.b=65534;this.f=this.a[this.b]|this.a[this.b+1]<<8};f.Qd=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.i=this.j=this.h|=this.a[this.b]};f.Sd=function(){this.b=this.a[this.f++];this.i=this.j=this.h|=this.a[this.b]}; +f.mc=function(){this.g=this.a[this.f++];this.c=this.a[this.g]<<1;this.i=this.j=this.a[this.g]=this.c&255};f.Vd=function(){this.B=Ga(this);this.a[this.G--]=this.B;this.G|=256};f.Pd=function(){this.b=this.f++;this.i=this.j=this.h|=this.a[this.b]};f.lc=function(){this.c=this.h<<1;this.i=this.j=this.h=this.c&255};f.Md=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.h|=this.a[this.b]}; +f.jc=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.c=this.a[this.g]<<1;this.i=this.j=this.a[this.g]=this.c&255};f.vc=function(){this.f+=(this.i&128?0:(this.D--,this.a[this.f]<<24>>24))+1};f.Rd=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.i=this.j=this.h|=this.a[this.b]};f.Td=function(){this.b=this.a[this.f++]+this.w&255;this.i=this.j=this.h|=this.a[this.b]}; +f.nc=function(){this.g=this.a[this.f++]+this.w&255;this.c=this.a[this.g]<<1;this.i=this.j=this.a[this.g]=this.c&255};f.zc=function(){this.c=0};f.Od=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.i=this.j=this.h|=this.a[this.b]};f.Nd=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.h|=this.a[this.b]};f.kc=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.c=this.a[this.g]<<1;this.i=this.j=this.a[this.g]=this.c&255}; +f.nd=function(){this.b=this.f++;this.a[this.G--]=this.f>>8;this.G|=256;this.a[this.G--]=this.f&255;this.G|=256;this.f=this.a[this.b]|this.a[this.b+1]<<8};f.fc=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.i=this.j=this.h&=this.a[this.b]};f.sc=function(){this.b=this.a[this.f++];this.j=this.h&this.a[this.b];this.i=this.i&127|this.a[this.b]&128;this.v=0;this.A=this.a[this.b]&64?128:0};f.hc=function(){this.b=this.a[this.f++];this.i=this.j=this.h&=this.a[this.b]}; +f.ae=function(){this.g=this.a[this.f++];this.c=this.c&65280|this.a[this.g];this.c<<=1;this.c=this.c&65534|(this.c&512?1:0);this.i=this.j=this.a[this.g]=this.c&255};f.Xd=function(){this.G=this.G+1&255|256;this.B=this.a[this.G];this.c=this.B&1?256:0;this.j=this.B&2?0:1;this.i=this.B&128;this.v=0;this.A=this.B&64?128:0};f.ec=function(){this.b=this.f++;this.i=this.j=this.h&=this.a[this.b]}; +f.$d=function(){this.c=this.c&65280|this.h;this.c<<=1;this.c=this.c&65534|(this.c&512?1:0);this.i=this.j=this.h=this.c&255};f.rc=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.j=this.h&this.a[this.b];this.i=this.i&127|this.a[this.b]&128;this.v=0;this.A=this.a[this.b]&64?128:0};f.bc=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.h&=this.a[this.b]}; +f.Yd=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.c=this.c&65280|this.a[this.g];this.c<<=1;this.c=this.c&65534|(this.c&512?1:0);this.i=this.j=this.a[this.g]=this.c&255};f.tc=function(){this.f+=(this.i&128?(this.D--,this.a[this.f]<<24>>24):0)+1};f.gc=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.i=this.j=this.h&=this.a[this.b]};f.ic=function(){this.b=this.a[this.f++]+this.w&255;this.i=this.j=this.h&=this.a[this.b]}; +f.be=function(){this.g=this.a[this.f++]+this.w&255;this.c=this.c&65280|this.a[this.g];this.c<<=1;this.c=this.c&65534|(this.c&512?1:0);this.i=this.j=this.a[this.g]=this.c&255};f.re=function(){this.c=256};f.dc=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.i=this.j=this.h&=this.a[this.b]};f.cc=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.h&=this.a[this.b]}; +f.Zd=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.c=this.c&65280|this.a[this.g];this.c<<=1;this.c=this.c&65534|(this.c&512?1:0);this.i=this.j=this.a[this.g]=this.c&255};f.he=function(){this.G=this.G+1&255|256;this.B=this.a[this.G];this.c=this.B&1?256:0;this.j=this.B&2?0:1;this.i=this.B&128;this.v=0;this.A=this.B&64?128:0;this.G=this.G+2&255|256;this.f=this.a[this.G-1|256]|this.a[this.G]<<8}; +f.ad=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.i=this.j=this.h^=this.a[this.b]};f.cd=function(){this.b=this.a[this.f++];this.i=this.j=this.h^=this.a[this.b]};f.Jd=function(){this.g=this.a[this.f++];this.c=this.c&65279|(this.a[this.g]&1?256:0);this.a[this.g]=(this.c=this.c&65280|this.a[this.g]>>1)&255;this.i=this.j=this.c&255};f.Ud=function(){this.a[this.G--]=this.h;this.G|=256};f.$c=function(){this.b=this.f++;this.i=this.j=this.h^=this.a[this.b]}; +f.Id=function(){this.c=this.c&65279|(this.h&1?256:0);this.h=(this.c=this.c&65280|this.h>>1)&255;this.i=this.j=this.c&255};f.md=function(){this.b=this.f;this.f=this.a[this.b]|this.a[this.b+1]<<8};f.Xc=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.h^=this.a[this.b]};f.Gd=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.c=this.c&65279|(this.a[this.g]&1?256:0);this.a[this.g]=(this.c=this.c&65280|this.a[this.g]>>1)&255;this.i=this.j=this.c&255}; +f.xc=function(){this.f+=((this.v&255^this.A^this.v>>1)&128?0:(this.D--,this.a[this.f]<<24>>24))+1};f.bd=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.i=this.j=this.h^=this.a[this.b]};f.dd=function(){this.b=this.a[this.f++]+this.w&255;this.i=this.j=this.h^=this.a[this.b]};f.Kd=function(){this.g=this.a[this.f++]+this.w&255;this.c=this.c&65279|(this.a[this.g]&1?256:0);this.a[this.g]=(this.c=this.c&65280|this.a[this.g]>>1)&255;this.i=this.j=this.c&255}; +f.Bc=function(){this.B&=251};f.Zc=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.i=this.j=this.h^=this.a[this.b]};f.Yc=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.h^=this.a[this.b]};f.Hd=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.c=this.c&65279|(this.a[this.g]&1?256:0);this.a[this.g]=(this.c=this.c&65280|this.a[this.g]>>1)&255;this.i=this.j=this.c&255}; +f.ie=function(){this.G=this.G+2&255|256;this.f=(this.a[this.G-1|256]|this.a[this.G]<<8)+1};f.xb=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.Yb=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=P(this,this.h,this.a[this.b])}; +f.zb=function(){this.b=this.a[this.f++];this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.$b=function(){this.b=this.a[this.f++];this.h=P(this,this.h,this.a[this.b])};f.fe=function(){this.g=this.a[this.f++];this.c=this.c&65280|this.a[this.g];this.c=this.c&65023|(this.c&1?512:0);this.c>>=1;this.i=this.j=this.a[this.g]=this.c&255};f.Wd=function(){this.G=this.G+1&255|256;this.i=this.j=this.h=this.a[this.G]}; +f.wb=function(){this.b=this.f++;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.Xb=function(){this.b=this.f++;this.h=P(this,this.h,this.a[this.b])};f.ee=function(){this.c=this.c&65280|this.h;this.c=this.c&65023|(this.c&1?512:0);this.c>>=1;this.i=this.j=this.h=this.c&255};f.ld=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.f=this.a[this.b]|this.a[this.b+1]<<8}; +f.tb=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.Ub=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.h=P(this,this.h,this.a[this.b])};f.ce=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.c=this.c&65280|this.a[this.g];this.c=this.c&65023|(this.c&1?512:0);this.c>>=1;this.i=this.j=this.a[this.g]=this.c&255}; +f.yc=function(){this.f+=((this.v&255^this.A^this.v>>1)&128?(this.D--,this.a[this.f]<<24>>24):0)+1};f.yb=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.Zb=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.h=P(this,this.h,this.a[this.b])}; +f.Ab=function(){this.b=this.a[this.f++]+this.w&255;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.ac=function(){this.b=this.a[this.f++]+this.w&255;this.h=P(this,this.h,this.a[this.b])};f.ge=function(){this.g=this.a[this.f++]+this.w&255;this.c=this.c&65280|this.a[this.g];this.c=this.c&65023|(this.c&1?512:0);this.c>>=1;this.i=this.j=this.a[this.g]=this.c&255};f.te=function(){this.B|=4}; +f.vb=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255};f.Wb=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.h=P(this,this.h,this.a[this.b])};f.ub=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.c=this.h+this.a[this.b]+(this.c&256?1:0);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255}; +f.Vb=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.h=P(this,this.h,this.a[this.b])};f.de=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.c=this.c&65280|this.a[this.g];this.c=this.c&65023|(this.c&1?512:0);this.c>>=1;this.i=this.j=this.a[this.g]=this.c&255};f.xe=function(){this.g=this.a[this.f++]+this.w&255;this.g=this.a[this.g]|this.a[this.g+1]<<8;this.a[this.g]=this.h};f.Fe=function(){this.g=this.a[this.f++];this.a[this.g]=this.F}; +f.ze=function(){this.g=this.a[this.f++];this.a[this.g]=this.h};f.Ce=function(){this.g=this.a[this.f++];this.a[this.g]=this.w};f.Wc=function(){this.i=this.j=this.F=this.F-1&255};f.Le=function(){this.i=this.j=this.h=this.w};f.Ee=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.a[this.g]=this.F};f.ue=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.a[this.g]=this.h};f.Be=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.a[this.g]=this.w}; +f.oc=function(){this.f+=(this.c&256?0:(this.D--,this.a[this.f]<<24>>24))+1};f.ye=function(){this.g=this.a[this.f++];this.g=(this.a[this.g]|this.a[this.g+1]<<8)+this.F;this.a[this.g]=this.h};f.Ge=function(){this.g=this.a[this.f++]+this.w&255;this.a[this.g]=this.F};f.Ae=function(){this.g=this.a[this.f++]+this.w&255;this.a[this.g]=this.h};f.De=function(){this.g=this.a[this.f++]+this.F&255;this.a[this.g]=this.w};f.Ne=function(){this.i=this.j=this.h=this.F}; +f.we=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.a[this.g]=this.h};f.Me=function(){this.G=this.w|256};f.ve=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.a[this.g]=this.h};f.Dd=function(){this.b=this.f++;this.i=this.j=this.F=this.a[this.b]};f.sd=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.i=this.j=this.h=this.a[this.b]};f.yd=function(){this.b=this.f++;this.i=this.j=this.w=this.a[this.b]}; +f.Ed=function(){this.b=this.a[this.f++];this.i=this.j=this.F=this.a[this.b]};f.ud=function(){this.b=this.a[this.f++];this.i=this.j=this.h=this.a[this.b]};f.zd=function(){this.b=this.a[this.f++];this.i=this.j=this.w=this.a[this.b]};f.Je=function(){this.i=this.j=this.F=this.h};f.rd=function(){this.b=this.f++;this.i=this.j=this.h=this.a[this.b]};f.Ie=function(){this.i=this.j=this.w=this.h};f.Bd=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.F=this.a[this.b]}; +f.od=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.h=this.a[this.b]};f.wd=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.w=this.a[this.b]};f.pc=function(){this.f+=(this.c&256?(this.D--,this.a[this.f]<<24>>24):0)+1};f.td=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.i=this.j=this.h=this.a[this.b]};f.Fd=function(){this.b=this.a[this.f++]+this.w&255;this.i=this.j=this.F=this.a[this.b]}; +f.vd=function(){this.b=this.a[this.f++]+this.w&255;this.i=this.j=this.h=this.a[this.b]};f.Ad=function(){this.b=this.a[this.f++]+this.F&255;this.i=this.j=this.w=this.a[this.b]};f.Cc=function(){this.A=this.v=0};f.qd=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.i=this.j=this.h=this.a[this.b]};f.Ke=function(){this.i=this.j=this.w=this.G&255};f.Cd=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.F=this.a[this.b]}; +f.pd=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.h=this.a[this.b]};f.xd=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.i=this.j=this.w=this.a[this.b]};f.Pc=function(){this.b=this.f++;this.i=this.j=this.c=this.F-this.a[this.b];this.c^=256};f.Hc=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256}; +f.Qc=function(){this.b=this.a[this.f++];this.i=this.j=this.c=this.F-this.a[this.b];this.c^=256};f.Jc=function(){this.b=this.a[this.f++];this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Tc=function(){this.g=this.a[this.f++];this.i=this.j=this.a[this.g]=this.a[this.g]-1&255};f.kd=function(){this.i=this.j=this.F=this.F+1&255};f.Gc=function(){this.b=this.f++;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Vc=function(){this.i=this.j=this.w=this.w-1&255}; +f.Oc=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.c=this.F-this.a[this.b];this.c^=256};f.Dc=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Rc=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.a[this.g]=this.a[this.g]-1&255};f.uc=function(){this.f+=(this.j&255?(this.D--,this.a[this.f]<<24>>24):0)+1}; +f.Ic=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Kc=function(){this.b=this.a[this.f++]+this.w&255;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Uc=function(){this.g=this.a[this.f++]+this.w&255;this.i=this.j=this.a[this.g]=this.a[this.g]-1&255};f.Ac=function(){Ma(this)}; +f.Fc=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Ec=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.c=this.h-this.a[this.b];this.c^=256};f.Sc=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.a[this.g]=this.a[this.g]-1&255};f.Mc=function(){this.b=this.f++;this.i=this.j=this.c=this.w-this.a[this.b];this.c^=256}; +f.Fb=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.ne=function(){this.b=this.a[this.f++]+this.w&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=Q(this,this.h,this.a[this.b])};f.Nc=function(){this.b=this.a[this.f++];this.i=this.j=this.c=this.w-this.a[this.b];this.c^=256}; +f.Hb=function(){this.b=this.a[this.f++];this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.pe=function(){this.b=this.a[this.f++];this.h=Q(this,this.h,this.a[this.b])};f.gd=function(){this.g=this.a[this.f++];this.i=this.j=this.a[this.g]=this.a[this.g]+1&255};f.jd=function(){this.i=this.j=this.w=this.w+1&255}; +f.Eb=function(){this.b=this.f++;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.me=function(){this.b=this.f++;this.h=Q(this,this.h,this.a[this.b])};f.Ld=function(){};f.Lc=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.c=this.w-this.a[this.b];this.c^=256}; +f.Bb=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.je=function(){this.b=this.a[this.f++]|this.a[this.f++]<<8;this.h=Q(this,this.h,this.a[this.b])};f.ed=function(){this.g=this.a[this.f++]|this.a[this.f++]<<8;this.i=this.j=this.a[this.g]=this.a[this.g]+1&255};f.qc=function(){this.f+=(this.j&255?0:(this.D--,this.a[this.f]<<24>>24))+1}; +f.Gb=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.oe=function(){this.b=this.a[this.f++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.F;this.h=Q(this,this.h,this.a[this.b])}; +f.Ib=function(){this.b=this.a[this.f++]+this.w&255;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.qe=function(){this.b=this.a[this.f++]+this.w&255;this.h=Q(this,this.h,this.a[this.b])};f.hd=function(){this.g=this.a[this.f++]+this.w&255;this.i=this.j=this.a[this.g]=this.a[this.g]+1&255};f.se=function(){La(this)}; +f.Db=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.le=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.F;this.h=Q(this,this.h,this.a[this.b])}; +f.Cb=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.c=this.h-this.a[this.b]-(this.c&256?0:1);this.A=this.h^this.a[this.b];this.v=this.c;this.i=this.j=this.h=this.c&255;this.c^=256};f.ke=function(){this.b=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.h=Q(this,this.h,this.a[this.b])};f.fd=function(){this.g=(this.a[this.f++]|this.a[this.f++]<<8)+this.w;this.i=this.j=this.a[this.g]=this.a[this.g]+1&255}; +f.He=function(){var a;a=this.a[this.f++];switch(a){case 0:this.l("HALT");this.aa();break;case 1:a=this.f;for(var b="";a=c&&(c+=32);a.B=a.B.substr(1);Sa(a,c)}0=b&&(b+=32),Ua(a,b),T(a,b,!0,0)&&(a.s.speed==a.s.fb?T(a,b,!1,1):(c=!1,a.v[b]&&(clearTimeout(a.v[b]),c=!0),c=Ta(a,c),a.v[a.A=b]=setTimeout(function(a){return function(){T(a,b,!1,3)}}(a),c),a.u&&H(a.u,a.u.za)&&a.u.message("keyPressSimulate("+q(b)+"): setTimeout()")),c=!0));a.u&&H(a.u,a.u.za)&&a.u.message("keyPressSimulate("+q(b)+"): "+(c?"true":"false"));return c} +function T(a,b,c,d){var e=!1;c||(a.v[b]=null,a.A==b&&(a.A=0));var g=0,h=a.b[b];void 0===h&&(1<=b&&26>=b&&(b+=64,g=a.L),h=a.b[b]);void 0!==h&&(b=h>>12,e=h>>8&15,g||(g=h&255),c?(a.o[b]|=1<b||8192<=b));b&&(b=a.P.shift(),void 0!==b&&(a.ja=b),a.V=0,a.qa=d);for(b=d=0;8>b;b++)a.oa&1<d[g][0]&&(h=d[g][0]),k=a.Z&&(d-=a.Z,dMissing <canvas> support. Please try a newer web browser.";break}e.setAttribute("class","c1pjs-canvas");e.setAttribute("width",d.screenWidth);e.setAttribute("height",d.screenHeight);e.setAttribute("contenteditable","true");e.setAttribute("autocapitalize","off");e.setAttribute("autocorrect","off");e.style.backgroundColor=d.screenColor; +e.style.height="auto";0<=(window?window.navigator.userAgent:"").indexOf("MSIE")&&(e.style.height=(c.clientWidth*d.screenHeight/d.screenWidth|0)+"px",c.onresize=function(a,b,c,d){return function(){b.style.height=(a.clientWidth*d/c|0)+"px"}}(c,e,d.screenWidth,d.screenHeight));c.appendChild(e);var g=new Image,h=e.getContext("2d"),e=new Xa(d,e,h,g);g.onload=function(a){return function(){a.X()}}(e,d.charSet);g.src=d.charSet;F(e,c)}}); +function $a(a){A.call(this,"C1PSerialPort",a);this.C.M=!1;this.D=a.demo;this.reset(!0)}C($a);f=$a.prototype;f.reset=function(a){if(a||2!=this.o){this.v=-1;this.A=0;this.g="";if(this.D){a=1;if(this.rb){var b=this.rb.match(/\d+/);null!==b&&(a=parseInt(b[0],10))}this.g='10 PRINT "HELLO OSI #'+a+'"\n'}this.B=!0;this.o=0}};f.start=function(){this.b&&this.D&&(U(this.b," C\n\n",3E3),setTimeout(function(a){return function(){a.o=1;U(a.b,"LOAD\n")}}(this),12E3));this.D=!1}; +f.T=function(a,b,c){var d=this;switch(b){case "listSerial":return this.H[b]=c,!0;case "loadSerial":return this.H[b]=c,c.onclick=function(){d.H.listSerial&&t(d.H.listSerial.value,function(a,b,c){ab(d,a,b,c)})},!0;case "mountSerial":return!v("Mobi")&&window&&"FileReader"in window?(this.H[b]=c,c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length}),c.onsubmit=function(a){var b=a.currentTarget[1].files[0],c=new FileReader;c.onload=function(){ab(d, +b.name,c.result.toString(),0)};c.readAsText(b);return!1}):c.parentNode.removeChild(c),!0}return!1};f.ba=function(a,b,c,d){this.a=a;this.N=b;this.L=c-b+1;this.K=this.N+this.L;if(this.s=d)Aa(d,b,c,this,this.S),N(d,b,c,this,this.W);this.X()};f.ia=function(a,b){a&&!this.C.M&&(this.C.M=!0,this.J=b,this.b=L(b,"keyboard"),this.u=L(b,"debugger"))}; +function ab(a,b,c,d){if(c){a.A=0;a.g=c;a.B=!0;a.o=0;if(-1!==b.indexOf(".json",b.length-5))try{d="";var e=eval("("+c+")").bytes;for(c=0;c=--d.Fa&&(0=d.sb&&(d.na=d.sb),0>d.na&&(d.na=0),d.Fa=20, +a.o.update(a.o.I|128),fb(a))}this.I=c;a.D.I&4&&V(a,2,this)}}(a)};a.D={I:0,read:function(){},update:function(a){return function(c){void 0!==c&&(this.I=c&-193);V(a,3,this);a.A.update();a.L.update()}}(a)};a.P={I:0,read:function(){},update:function(a){return function(c){void 0!==c&&(3==(c&3)&&(a.v.I=14),this.I=c);a.v.update()}}(a)};a.v={I:14,read:function(){},update:function(a){return function(c){void 0===c&&(c=a.v.I);c&=-2;0<=a.b&&0<=a.g[a.b].Ea&&(c|=1);this.I=c;V(a,16,this)}}(a)};a.N={I:0,read:function(a){return function(){gb(a)}}(a), +update:function(a){return function(c){void 0!==c&&(this.I=c);V(a,17,this)}}(a)};a.R={I:0,read:function(){},update:function(){return function(){}}(a)}}f.T=function(a,b,c){switch(b){case "listDisk":return this.H[b]=c,!0;case "loadDisk":return this.H[b]=c,c.onclick=function(a){return function(){if(a.H.listDisk){var b=a.H.listDisk.value,c=b;".json"!=b.substr(b.length-5)&&(c="http://"+window.location.host+"/api/v1/dump?disk="+b);a.l("loading "+aa(b)+"...");t(c,function(b,c,e){hb(a,b,c,e)})}}}(this),!0}return!1}; +f.ba=function(a,b,c,d){this.a=a;this.J=b;if(this.s=d)Aa(d,b,c,this,this.S),N(d,b,c,this,this.W);this.X()};f.ia=function(a,b){a&&!this.C.M&&(this.C.M=!0,this.u=L(b,"debugger"))}; +function hb(a,b,c,d){if(d)a.l("disk load error ("+d+")");else{d=[];a.l("mounting "+b+"...");try{if(d=eval("("+c+")"),d.length)if(d[0].length){var e=d[0];if(void 0===e[0].trackNum)a.l("data error: "+e[0]);else if(a.g[0]){for(c=0;c>8&255);a.push(b&255)}function ib(a,b,c){b=b[c];if(void 0===b)throw Error("missing signature: "+c);for(c=0;cb?b&=3:32>b&&(b&=17);switch(b){case 0:a=a.B.I&4?a.o:a.K;break;case 1:a=a.B;break;case 2:a=a.D.I&4?a.A:a.L;break;case 3:a=a.D;break;case 16:a=c?a.P:a.v;break;case 17:a=a.N;break;default:a=a.R}return a}f.S=function(a,b){if(void 0!==b){var c=kb(this,a-this.J,!1);this.u&&S(this.u,this,a,b,this.u.Ha,!1,c.Jb);c.read()}}; +f.W=function(a,b){if(void 0!==b){var c=this.s.S(a),d=kb(this,a-this.J,!0);if(this.u&&H(this.u,this.u.Ha|this.u.qb)&&(S(this.u,this,a,b,this.u.Ha,!0,d.Jb),d.Ob))for(var e=128,g=d.I^c;g&&e;)g&e&&this.u.message(" changed "+d.Jb+"."+d.Ob[e]+" to "+(c&e?"1":"0")),e>>=1;d.update(c)}};function eb(a,b,c){var d=-1;void 0!==b&&void 0!==c&&(d=0,c&32||(d|=2),a.o.I&64||(d|=1));a.b!=d&&(a.b=d,a.v.update())}function fb(a){0<=a.b&&(a.g[a.b].Ea=-1,a.N.update(255),a.v.update())} +function gb(a){var b=null;if(0<=a.b){var b=a.g[a.b],c=b.Va[b.na];void 0!==c&&(0<=b.Ea&&b.Ea>24)} +f.S=function(a){var b;a>=this.N&&a=this.Ga?this.l("invalid address: "+r(a)):(this.a[this.N+a]=b&255,Da(this.s,a),this.s.update())};function tb(a,b){X(a.sa,b,void 0)||a.sa.push(b);return!0}function X(a,b,c){for(var d=!1,e=0;eh&&(m+=" ;'"+String.fromCharCode(h)+"'")}if(e==a.s.bb&& +(hl?m+=String.fromCharCode(h):16==l&&(m+="\u2026"),l++;m+='"'}m&&(d+=" "+m);c&&(d=(d+" ").substr(0,30),d+=";"+c.toString());a.$=b;return d} +function Y(a,b){var c=a.ua;if(void 0!==b){var d=16;"$"==b.charAt(0)?b=b.substr(1):"0x"==b.substr(0,2)?b=b.substr(2):"."==b.charAt(b.length-1)&&(d=10,b=b.substr(0,b.length-1));c=parseInt(b,d);isNaN(c)&&(a.l("invalid base-"+d+" address: "+b),c=void 0)}void 0!==c&&(c=a.Ga)&&(a.l("address out of range: "+p(c)),c=void 0);return c} +function wb(a,b){if("?"==b)a.l("\nfrequency commands:"),a.l("clear\tclear all frequency counts");else{var c=0,d;if(a.B)if("clear"==b){for(d=0;da.Pb.indexOf(k)&&(e=a.O);e==a.pb&&27!=k&&(e=a.O)}else a.l("unknown operand: "+l),k=-1;if(0<=k){m=-1;for(h=0;hm)m=h;else{a.l("too many instruction matches (both "+q(m)+" and "+q(h)+")");m=-2;break}if(0<=m){if(d.push(m),void 0!==e)if(g=a.ga[m][1],l=l.match(/[0-9A-F]+/),null!==l)for(l=parseInt(l[0],16),1==g&&e==a.fa&&(l-=c+2,-128>l||127>>=8;else g&&a.l("instruction missing "+g+" bytes")}else a.l("unknown instruction: "+g+" "+l+"")}}e=d;if(e.length){for(c=0;ck&&em?String.fromCharCode(m):".",e++;a.l(p(h,4)+" "+g+l)}a.ua=e}break;case "e":e=c[1];if(void 0===e)a.l("missing address");else if(e=Y(a,e),void 0!==e)for(d=2;dd.length&&(a.l("note: only "+ +d.length+" available"),g=d.length);void 0!==l&&(a.nb=0,a.l(g+" instructions earlier:"));l=a.nb?a.nb:1;c-=g;for(0>c&&(c=d.length-1);e&&c!=a.La;){h=d[c];if(0>h)break;a.l(vb(a,h,l++));++c==d.length&&(c=0);e--;g--}a.Tb=g;a.nb=l}10==e&&a.l("no history available");break;case "r":qb(a,c);break;case "s":a.S(a.s.f)==a.s.Qa?(ub(a,a.s.f+3),a.Da=!0,a.va()||a.s.ca()):xb(a);break;case "t":xb(a,c[1]);break;case "u":pb(a,c[1],c[2],8);break;case "?":case "help":a.l("\ncommands:\n?\thelp\na [#]\tassemble\nb [#]\tbreakpoint\nd [#]\tdump memory\ne [#]\tedit memory\nf\tdump frequencies\ng [#]\trun to [#]\nh\thalt\no\toptions\np [#]\tdump history\nr\tdump/edit registers\ns\tstep over instruction\nt [#]\tstep instruction(s)\nu [#]\tunassemble"); +a.l("note: frequency and history commands operate only when breakpoints are set");break;default:a.l("unknown command: "+b)}}}x(function(){for(var a=G(document,"c1pjs","debugger"),b=0;b");b&&b.ia(!0,a)} +x(function(){for(var a=G(document,"c1pjs","computer"),b=0;b');return}}if(void 0===h){u(' definition must appear first in the specification'); +break}if(e=ta("debugger",d.id))g["debugger"]=[e],e.ba&&e.ba(h,k,l,g.cpu[0]);k=new Z(d,g);if(l=ta("panel",d.id))if(g.panel=[l],l.hb){e=d.id;d=void 0;g=[];e&&(e=0<(d=e.indexOf("."))?e.substr(0,d+1):"");for(d=0;dk.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(k=window.location.pathname+k);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(k?' url="'+k+'"':""))}e||(a=a.replace(/().*?(<\/xsl:variable>)/, +"$1c1pjs$2"));k=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(k=new window.ActiveXObject("Microsoft.XMLDOM"),k.async=!1,k.loadXML(a)):k=(new window.DOMParser).parseFromString(a,"text/xml")}catch(y){k=null,a=y.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");t(e,function(g,h,k){if(k||!h)c(a,"unable to resolve XML reference: "+d[0]+" ("+k+")");else{if(g=d[3])if(k=h.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var l=k[0],m,n=/( [a-z]+=)(['"])(.*?)\2/g;m=n.exec(g);)l=0>l.indexOf(m[1])?l.replace(">",m[0]+">"):l.replace(new RegExp(m[1]+"(['\"])(.*?)\\1"),m[0]);k[0]!=l&&(h=h.replace(k[0],l))}else{c(a,"missing <"+d[1]+"> in "+e);return}h=h.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],h);Db(a,b,c)}})}else c(a,null)} +function Eb(a,b,c){function d(a){if(void 0===h){var b=g&&G(g,"machine-warning");h=b&&b[0]||g}h&&(h.innerHTML=da(a))}function e(a){d("Error: "+a);k&&(--zb||z(!0));k=!1}var g,h,k=!0;zb++;D[a]={};try{if(g=document.getElementById(a)){var l;if("object"==typeof resources&&(l=resources.css)){var m=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css";n.styleSheet?n.styleSheet.cssText=l:n.appendChild(document.createTextNode(l));m.appendChild(n)}c||(c= +"/versions/c1pjs/1.24.2/components.xsl");l=function(h,k){k?Ab(c,null,null,!1,d,function(h,l){if(l)if(D[a]&&c&&(D[a][c]=h),d("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var m=k.transformNode(l);m?(g.outerHTML=m,--zb||z(!0)):e("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(m=new XSLTProcessor,m.importStylesheet(l),(m=m.transformToFragment(k,document))?g.parentNode?(g.parentNode.replaceChild(m,g),--zb||z(!0)):e("invalid machine element: "+ +a):e("transformToFragment failed")):e("unable to transform XML: unsupported browser");else e(h)}):e(h)};"<"!=b.charAt(0)?Ab(b,a,void 0,!0,d,l):Cb(b,null,a,void 0,!1,d,l)}else e("missing machine element: "+a)}catch(y){e(y.message)}return k}window.embedC1P=function(a,b,c){z(!1);return Eb(a,b,c)};window.enableEvents=z;window.sendEvent=ma;})(); diff --git a/versions/c1pjs/1.24.2/c1p.js b/versions/c1pjs/1.24.2/c1p.js new file mode 100644 index 000000000..a767eb5ae --- /dev/null +++ b/versions/c1pjs/1.24.2/c1p.js @@ -0,0 +1,127 @@ +(function(){var e;function p(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function aa(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("&");0":">",'"':""","'":"'"}; +function da(a){return a.replace(/[&<>"']/g,function(a){return ca[a]})}var q=Date.now||function(){return+new Date}; +function r(a,b){var c=0,d=null;if("object"==typeof resources&&(d=resources[a]))b&&b(a,d,c);else if("function"==typeof resources)resources(a,function(c,d){b&&b(a,c,d)});else{var f=window.XMLHttpRequest?new window.XMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");f.onreadystatechange=function(){4===f.readyState&&(d=f.responseText,200==f.status||!f.status&&d.length&&"file:"==(window?window.location.protocol:"file:")||(c=f.status||-1),b&&b(a,d,c))};f.open("GET",a,!0);f.send()}} +function t(a){window&&window.alert(a)}function v(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}var w={init:[],show:[],exit:[]},ea=!1,fa=!1,x=!0;function ga(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function y(a){w.init.push(a)} +function z(a){if(x)try{for(var b=0;bb?this.ya=this.id:(this.Da=this.id.substr(0,b),this.ya=this.id.substr(b+1));this[a]=c;this.u={va:!1,pa:!1,Ba:!1,H:!1,qa:!1};this.xa=null;this.u.qa=!1;this.A={};C.push(this)}var ia=void 0,ja={};if(window){ia||(ia=window.location.search.substr(1));for(var ka,la=/\+/g,ma=/([^&=]+)=?([^&]*)/g;ka=ma.exec(ia);)ja[decodeURIComponent(ka[1].replace(la," "))]=decodeURIComponent(ka[2].replace(la," "))} +function na(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b}function D(a){var b;b||(b=B);a.prototype=na(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var E=window.PCjs.Machines||(window.PCjs.Machines={}),C=window.PCjs.Components||(window.PCjs.Components=[])}else E={},C=[]; +function F(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;cwa(a.O,b,c,d,f)&&(a.ja>b&&(a.ja=b),a.kawa(a.K,b,c,d,f)&&(a.Y>b&&(a.Y=b),a.caa.ia&&a.ba&&(d=a.ba);d>a.ea&&2>a.speed&&(d=a.ea);a.eb=Math.round(1E3/30);a.fa=Math.floor(1E6/c*d);a.la=Math.floor(1E6/30*d);a.Ga=Math.floor(1E6/a.oa*d);a.Fa=Math.floor(1E6/a.na*d);b||(a.P=a.la,a.U=a.Ga,a.T=a.Fa);a.ma=0}function Aa(a){1E6<=a.ma&&xa(a,!0);a.V=0;a.fb=q()} +function Ba(a){var b=q(),c=a.eb;a.V&&(c=Math.round(c*a.V/a.la));c=c-(b-a.fb);if(b=b-a.Ea)a.ba=Math.round(a.S/(100*b))/10,864E5<=b&&ta(a);0>c?c=0:1==a.speed?a.ba<=a.ea&&(c=0):2==a.speed&&(c=0);a.ma+=a.V;return c} +function N(a){if(oa(a,!0)){a.u.Z||(ta(a),a.I&&a.I.start(),a.u.Z=!0,a.A.run&&(a.A.run.innerHTML="Halt"),a.da());Aa(a);try{do{a.step(a.fa);var b=a.L-a.G;a.S+=b;a.V+=b;a.L=a.G=0;a.U-=a.fa;0>=a.U&&(a.U+=a.Ga,a.Aa());a.T-=a.fa;0>=a.T&&(a.T+=a.Fa,ya(a));a.P-=a.fa;if(0>=a.P){a.P+=a.la;break}}while(a.u.Z)}catch(c){M(a);a.update();oa(a,!1);pa(a,c.stack||c.message);return}setTimeout(function(a){return function(){N(a)}}(a),Ba(a))}else a.update(),a.I&&a.I.stop(a.Ea,a.S)} +e.step=function(a){this.b=this.j=-1;this.L=this.G=a;do{a=this.a[this.c];this.c++;this.v[a].call(this);if(0<=this.b){if(this.b>=this.ja&&this.b<=this.ka)for(var b=this.b,c=this.c,d=0;d=this.O[d][0]&&b<=this.O[d][1]&&this.O[d][3].call(this.O[d][2],b,c);this.b=-1}else if(0<=this.j){if(this.j>=this.Y&&this.j<=this.ca)for(b=this.j,c=this.c,d=0;d=this.K[d][0]&&b<=this.K[d][1]&&this.K[d][3].call(this.K[d][2],b,c);this.j=-1}this.G-=this.bb[a]}while(0>1)&128?64:0),b=b|(a.h&128?128:0);return a.B&60|b} +function Q(a,b,c){var d=a.f&256?1:0,f=(b&15)+(c&15)+d;10<=f&&(f=f+6&15|16);f+=(b&240)+(c&240);a.C=b^c;a.w=f;a.h=f&255;160<=f&&(f+=96);512<=f&&(f-=256);a.f=f;a.i=b+c+d&255;a.G--;return f&255}function R(a,b,c){var d=a.f&256?0:1,f=(b&15)-(c&15)-d;0>f&&(f=(f-6&15)-16);f+=(b&240)-(c&240);0>f&&(f-=96);a.h=a.i=(a.f=b-c-d)&255;a.C=b^c;a.w=a.f;a.f^=256;a.G--;return f&255}function sa(a){a.g=0;a.m=0;a.o=0;a.s=256;a.B=0;a.h=0;a.i=0;a.C=0;a.w=0;a.f=0;a.c=0;a.b=-1;a.j=-1;a.ba=0;a.S=a.L=a.G=0} +e.Jb=function(){this.c++;this.a[this.s--]=this.c>>8;this.s|=256;this.a[this.s--]=this.c&255;this.s|=256;this.B|=16;this.B=za(this);this.a[this.s--]=this.B;this.s|=256;this.B&=239;this.b=65534;this.c=this.a[this.b]|this.a[this.b+1]<<8};e.bd=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=this.i=this.g|=this.a[this.b]};e.dd=function(){this.b=this.a[this.c++];this.h=this.i=this.g|=this.a[this.b]}; +e.zb=function(){this.j=this.a[this.c++];this.f=this.a[this.j]<<1;this.h=this.i=this.a[this.j]=this.f&255};e.gd=function(){this.B=za(this);this.a[this.s--]=this.B;this.s|=256};e.ad=function(){this.b=this.c++;this.h=this.i=this.g|=this.a[this.b]};e.yb=function(){this.f=this.g<<1;this.h=this.i=this.g=this.f&255};e.Yc=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.g|=this.a[this.b]}; +e.wb=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.f=this.a[this.j]<<1;this.h=this.i=this.a[this.j]=this.f&255};e.Ib=function(){this.c+=(this.h&128?0:(this.G--,this.a[this.c]<<24>>24))+1};e.cd=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.h=this.i=this.g|=this.a[this.b]};e.ed=function(){this.b=this.a[this.c++]+this.m&255;this.h=this.i=this.g|=this.a[this.b]}; +e.Ab=function(){this.j=this.a[this.c++]+this.m&255;this.f=this.a[this.j]<<1;this.h=this.i=this.a[this.j]=this.f&255};e.Mb=function(){this.f=0};e.$c=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.h=this.i=this.g|=this.a[this.b]};e.Zc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.g|=this.a[this.b]};e.xb=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.f=this.a[this.j]<<1;this.h=this.i=this.a[this.j]=this.f&255}; +e.zc=function(){this.b=this.c++;this.a[this.s--]=this.c>>8;this.s|=256;this.a[this.s--]=this.c&255;this.s|=256;this.c=this.a[this.b]|this.a[this.b+1]<<8};e.sb=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=this.i=this.g&=this.a[this.b]};e.Fb=function(){this.b=this.a[this.c++];this.i=this.g&this.a[this.b];this.h=this.h&127|this.a[this.b]&128;this.w=0;this.C=this.a[this.b]&64?128:0};e.ub=function(){this.b=this.a[this.c++];this.h=this.i=this.g&=this.a[this.b]}; +e.nd=function(){this.j=this.a[this.c++];this.f=this.f&65280|this.a[this.j];this.f<<=1;this.f=this.f&65534|(this.f&512?1:0);this.h=this.i=this.a[this.j]=this.f&255};e.jd=function(){this.s=this.s+1&255|256;this.B=this.a[this.s];this.f=this.B&1?256:0;this.i=this.B&2?0:1;this.h=this.B&128;this.w=0;this.C=this.B&64?128:0};e.rb=function(){this.b=this.c++;this.h=this.i=this.g&=this.a[this.b]}; +e.md=function(){this.f=this.f&65280|this.g;this.f<<=1;this.f=this.f&65534|(this.f&512?1:0);this.h=this.i=this.g=this.f&255};e.Eb=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.i=this.g&this.a[this.b];this.h=this.h&127|this.a[this.b]&128;this.w=0;this.C=this.a[this.b]&64?128:0};e.ob=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.g&=this.a[this.b]}; +e.kd=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.f=this.f&65280|this.a[this.j];this.f<<=1;this.f=this.f&65534|(this.f&512?1:0);this.h=this.i=this.a[this.j]=this.f&255};e.Gb=function(){this.c+=(this.h&128?(this.G--,this.a[this.c]<<24>>24):0)+1};e.tb=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.h=this.i=this.g&=this.a[this.b]};e.vb=function(){this.b=this.a[this.c++]+this.m&255;this.h=this.i=this.g&=this.a[this.b]}; +e.od=function(){this.j=this.a[this.c++]+this.m&255;this.f=this.f&65280|this.a[this.j];this.f<<=1;this.f=this.f&65534|(this.f&512?1:0);this.h=this.i=this.a[this.j]=this.f&255};e.Ed=function(){this.f=256};e.qb=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.h=this.i=this.g&=this.a[this.b]};e.pb=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.g&=this.a[this.b]}; +e.ld=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.f=this.f&65280|this.a[this.j];this.f<<=1;this.f=this.f&65534|(this.f&512?1:0);this.h=this.i=this.a[this.j]=this.f&255};e.ud=function(){this.s=this.s+1&255|256;this.B=this.a[this.s];this.f=this.B&1?256:0;this.i=this.B&2?0:1;this.h=this.B&128;this.w=0;this.C=this.B&64?128:0;this.s=this.s+2&255|256;this.c=this.a[this.s-1|256]|this.a[this.s]<<8}; +e.nc=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=this.i=this.g^=this.a[this.b]};e.pc=function(){this.b=this.a[this.c++];this.h=this.i=this.g^=this.a[this.b]};e.Vc=function(){this.j=this.a[this.c++];this.f=this.f&65279|(this.a[this.j]&1?256:0);this.a[this.j]=(this.f=this.f&65280|this.a[this.j]>>1)&255;this.h=this.i=this.f&255};e.fd=function(){this.a[this.s--]=this.g;this.s|=256};e.mc=function(){this.b=this.c++;this.h=this.i=this.g^=this.a[this.b]}; +e.Uc=function(){this.f=this.f&65279|(this.g&1?256:0);this.g=(this.f=this.f&65280|this.g>>1)&255;this.h=this.i=this.f&255};e.yc=function(){this.b=this.c;this.c=this.a[this.b]|this.a[this.b+1]<<8};e.jc=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.g^=this.a[this.b]};e.Sc=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.f=this.f&65279|(this.a[this.j]&1?256:0);this.a[this.j]=(this.f=this.f&65280|this.a[this.j]>>1)&255;this.h=this.i=this.f&255}; +e.Kb=function(){this.c+=((this.w&255^this.C^this.w>>1)&128?0:(this.G--,this.a[this.c]<<24>>24))+1};e.oc=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.h=this.i=this.g^=this.a[this.b]};e.qc=function(){this.b=this.a[this.c++]+this.m&255;this.h=this.i=this.g^=this.a[this.b]};e.Wc=function(){this.j=this.a[this.c++]+this.m&255;this.f=this.f&65279|(this.a[this.j]&1?256:0);this.a[this.j]=(this.f=this.f&65280|this.a[this.j]>>1)&255;this.h=this.i=this.f&255}; +e.Ob=function(){this.B&=251};e.lc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.h=this.i=this.g^=this.a[this.b]};e.kc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.g^=this.a[this.b]};e.Tc=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.f=this.f&65279|(this.a[this.j]&1?256:0);this.a[this.j]=(this.f=this.f&65280|this.a[this.j]>>1)&255;this.h=this.i=this.f&255}; +e.vd=function(){this.s=this.s+2&255|256;this.c=(this.a[this.s-1|256]|this.a[this.s]<<8)+1};e.Na=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.kb=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.g=Q(this,this.g,this.a[this.b])}; +e.Pa=function(){this.b=this.a[this.c++];this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.mb=function(){this.b=this.a[this.c++];this.g=Q(this,this.g,this.a[this.b])};e.sd=function(){this.j=this.a[this.c++];this.f=this.f&65280|this.a[this.j];this.f=this.f&65023|(this.f&1?512:0);this.f>>=1;this.h=this.i=this.a[this.j]=this.f&255};e.hd=function(){this.s=this.s+1&255|256;this.h=this.i=this.g=this.a[this.s]}; +e.Ma=function(){this.b=this.c++;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.jb=function(){this.b=this.c++;this.g=Q(this,this.g,this.a[this.b])};e.rd=function(){this.f=this.f&65280|this.g;this.f=this.f&65023|(this.f&1?512:0);this.f>>=1;this.h=this.i=this.g=this.f&255};e.xc=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.c=this.a[this.b]|this.a[this.b+1]<<8}; +e.Ja=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.gb=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.g=Q(this,this.g,this.a[this.b])};e.pd=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.f=this.f&65280|this.a[this.j];this.f=this.f&65023|(this.f&1?512:0);this.f>>=1;this.h=this.i=this.a[this.j]=this.f&255}; +e.Lb=function(){this.c+=((this.w&255^this.C^this.w>>1)&128?(this.G--,this.a[this.c]<<24>>24):0)+1};e.Oa=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.lb=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.g=Q(this,this.g,this.a[this.b])}; +e.Qa=function(){this.b=this.a[this.c++]+this.m&255;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.nb=function(){this.b=this.a[this.c++]+this.m&255;this.g=Q(this,this.g,this.a[this.b])};e.td=function(){this.j=this.a[this.c++]+this.m&255;this.f=this.f&65280|this.a[this.j];this.f=this.f&65023|(this.f&1?512:0);this.f>>=1;this.h=this.i=this.a[this.j]=this.f&255};e.Gd=function(){this.B|=4}; +e.La=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255};e.ib=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.g=Q(this,this.g,this.a[this.b])};e.Ka=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.f=this.g+this.a[this.b]+(this.f&256?1:0);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255}; +e.hb=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.g=Q(this,this.g,this.a[this.b])};e.qd=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.f=this.f&65280|this.a[this.j];this.f=this.f&65023|(this.f&1?512:0);this.f>>=1;this.h=this.i=this.a[this.j]=this.f&255};e.Kd=function(){this.j=this.a[this.c++]+this.m&255;this.j=this.a[this.j]|this.a[this.j+1]<<8;this.a[this.j]=this.g};e.Sd=function(){this.j=this.a[this.c++];this.a[this.j]=this.o}; +e.Md=function(){this.j=this.a[this.c++];this.a[this.j]=this.g};e.Pd=function(){this.j=this.a[this.c++];this.a[this.j]=this.m};e.ic=function(){this.h=this.i=this.o=this.o-1&255};e.Yd=function(){this.h=this.i=this.g=this.m};e.Rd=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.a[this.j]=this.o};e.Hd=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.a[this.j]=this.g};e.Od=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.a[this.j]=this.m}; +e.Bb=function(){this.c+=(this.f&256?0:(this.G--,this.a[this.c]<<24>>24))+1};e.Ld=function(){this.j=this.a[this.c++];this.j=(this.a[this.j]|this.a[this.j+1]<<8)+this.o;this.a[this.j]=this.g};e.Td=function(){this.j=this.a[this.c++]+this.m&255;this.a[this.j]=this.o};e.Nd=function(){this.j=this.a[this.c++]+this.m&255;this.a[this.j]=this.g};e.Qd=function(){this.j=this.a[this.c++]+this.o&255;this.a[this.j]=this.m};e.$d=function(){this.h=this.i=this.g=this.o}; +e.Jd=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.a[this.j]=this.g};e.Zd=function(){this.s=this.m|256};e.Id=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.a[this.j]=this.g};e.Pc=function(){this.b=this.c++;this.h=this.i=this.o=this.a[this.b]};e.Ec=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=this.i=this.g=this.a[this.b]};e.Kc=function(){this.b=this.c++;this.h=this.i=this.m=this.a[this.b]}; +e.Qc=function(){this.b=this.a[this.c++];this.h=this.i=this.o=this.a[this.b]};e.Gc=function(){this.b=this.a[this.c++];this.h=this.i=this.g=this.a[this.b]};e.Lc=function(){this.b=this.a[this.c++];this.h=this.i=this.m=this.a[this.b]};e.Wd=function(){this.h=this.i=this.o=this.g};e.Dc=function(){this.b=this.c++;this.h=this.i=this.g=this.a[this.b]};e.Vd=function(){this.h=this.i=this.m=this.g};e.Nc=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.o=this.a[this.b]}; +e.Ac=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.g=this.a[this.b]};e.Ic=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.m=this.a[this.b]};e.Cb=function(){this.c+=(this.f&256?(this.G--,this.a[this.c]<<24>>24):0)+1};e.Fc=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.h=this.i=this.g=this.a[this.b]};e.Rc=function(){this.b=this.a[this.c++]+this.m&255;this.h=this.i=this.o=this.a[this.b]}; +e.Hc=function(){this.b=this.a[this.c++]+this.m&255;this.h=this.i=this.g=this.a[this.b]};e.Mc=function(){this.b=this.a[this.c++]+this.o&255;this.h=this.i=this.m=this.a[this.b]};e.Pb=function(){this.C=this.w=0};e.Cc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.h=this.i=this.g=this.a[this.b]};e.Xd=function(){this.h=this.i=this.m=this.s&255};e.Oc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.o=this.a[this.b]}; +e.Bc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.g=this.a[this.b]};e.Jc=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.h=this.i=this.m=this.a[this.b]};e.bc=function(){this.b=this.c++;this.h=this.i=this.f=this.o-this.a[this.b];this.f^=256};e.Ub=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256}; +e.cc=function(){this.b=this.a[this.c++];this.h=this.i=this.f=this.o-this.a[this.b];this.f^=256};e.Wb=function(){this.b=this.a[this.c++];this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256};e.fc=function(){this.j=this.a[this.c++];this.h=this.i=this.a[this.j]=this.a[this.j]-1&255};e.wc=function(){this.h=this.i=this.o=this.o+1&255};e.Tb=function(){this.b=this.c++;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256};e.hc=function(){this.h=this.i=this.m=this.m-1&255}; +e.ac=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.f=this.o-this.a[this.b];this.f^=256};e.Qb=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256};e.dc=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.a[this.j]=this.a[this.j]-1&255};e.Hb=function(){this.c+=(this.i&255?(this.G--,this.a[this.c]<<24>>24):0)+1}; +e.Vb=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256};e.Xb=function(){this.b=this.a[this.c++]+this.m&255;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256};e.gc=function(){this.j=this.a[this.c++]+this.m&255;this.h=this.i=this.a[this.j]=this.a[this.j]-1&255}; +e.Nb=function(){this.B&=-9;this.v[97]=this.Na;this.v[101]=this.Pa;this.v[105]=this.Ma;this.v[109]=this.Ja;this.v[113]=this.Oa;this.v[117]=this.Qa;this.v[121]=this.La;this.v[125]=this.Ka;this.v[225]=this.Va;this.v[229]=this.Xa;this.v[233]=this.Ua;this.v[237]=this.Ra;this.v[241]=this.Wa;this.v[245]=this.Ya;this.v[249]=this.Ta;this.v[253]=this.Sa};e.Sb=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256}; +e.Rb=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.f=this.g-this.a[this.b];this.f^=256};e.ec=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.a[this.j]=this.a[this.j]-1&255};e.Zb=function(){this.b=this.c++;this.h=this.i=this.f=this.m-this.a[this.b];this.f^=256}; +e.Va=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.Ad=function(){this.b=this.a[this.c++]+this.m&255;this.b=this.a[this.b]|this.a[this.b+1]<<8;this.g=R(this,this.g,this.a[this.b])};e.$b=function(){this.b=this.a[this.c++];this.h=this.i=this.f=this.m-this.a[this.b];this.f^=256}; +e.Xa=function(){this.b=this.a[this.c++];this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.Cd=function(){this.b=this.a[this.c++];this.g=R(this,this.g,this.a[this.b])};e.tc=function(){this.j=this.a[this.c++];this.h=this.i=this.a[this.j]=this.a[this.j]+1&255};e.vc=function(){this.h=this.i=this.m=this.m+1&255}; +e.Ua=function(){this.b=this.c++;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.zd=function(){this.b=this.c++;this.g=R(this,this.g,this.a[this.b])};e.Xc=function(){};e.Yb=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.f=this.m-this.a[this.b];this.f^=256}; +e.Ra=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.wd=function(){this.b=this.a[this.c++]|this.a[this.c++]<<8;this.g=R(this,this.g,this.a[this.b])};e.rc=function(){this.j=this.a[this.c++]|this.a[this.c++]<<8;this.h=this.i=this.a[this.j]=this.a[this.j]+1&255};e.Db=function(){this.c+=(this.i&255?0:(this.G--,this.a[this.c]<<24>>24))+1}; +e.Wa=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.Bd=function(){this.b=this.a[this.c++];this.b=(this.a[this.b]|this.a[this.b+1]<<8)+this.o;this.g=R(this,this.g,this.a[this.b])}; +e.Ya=function(){this.b=this.a[this.c++]+this.m&255;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.Dd=function(){this.b=this.a[this.c++]+this.m&255;this.g=R(this,this.g,this.a[this.b])};e.uc=function(){this.j=this.a[this.c++]+this.m&255;this.h=this.i=this.a[this.j]=this.a[this.j]+1&255}; +e.Fd=function(){this.B|=8;this.v[97]=this.kb;this.v[101]=this.mb;this.v[105]=this.jb;this.v[109]=this.gb;this.v[113]=this.lb;this.v[117]=this.nb;this.v[121]=this.ib;this.v[125]=this.hb;this.v[225]=this.Ad;this.v[229]=this.Cd;this.v[233]=this.zd;this.v[237]=this.wd;this.v[241]=this.Bd;this.v[245]=this.Dd;this.v[249]=this.yd;this.v[253]=this.xd}; +e.Ta=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.yd=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.o;this.g=R(this,this.g,this.a[this.b])}; +e.Sa=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.f=this.g-this.a[this.b]-(this.f&256?0:1);this.C=this.g^this.a[this.b];this.w=this.f;this.h=this.i=this.g=this.f&255;this.f^=256};e.xd=function(){this.b=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.g=R(this,this.g,this.a[this.b])};e.sc=function(){this.j=(this.a[this.c++]|this.a[this.c++]<<8)+this.m;this.h=this.i=this.a[this.j]=this.a[this.j]+1&255}; +e.Ud=function(){var a;a=this.a[this.c++];switch(a){case 0:this.F("HALT");M(this);break;case 1:a=this.c;for(var b="";a=c&&(c+=32);a.j=a.j.substr(1);T(a,c)}0=b&&(b+=32),Ja(a,b),U(a,b,!0,0)&&(a.f.speed==a.f.Ca?U(a,b,!1,1):(c=!1,a.h[b]&&(clearTimeout(a.h[b]),c=!0),c=Ia(a,c),a.h[a.i=b]=setTimeout(function(a){return function(){U(a,b,!1,3)}}(a),c)),c=!0));return c} +function U(a,b,c,d){var f=!1;c||(a.h[b]=null,a.i==b&&(a.i=0));var g=0,k=a.b[b];void 0===k&&(1<=b&&26>=b&&(b+=64,g=a.v),k=a.b[b]);void 0!==k&&(b=k>>12,f=k>>8&15,g||(g=k&255),c?(a.g[b]|=1<b||8192<=b));b&&(b=a.w.shift(),void 0!==b&&(a.P=b),a.C=0,a.V=d);for(b=d=0;8>b;b++)a.S&1<d[g][0]&&(k=d[g][0]),h=a.K&&(d-=a.K,dMissing <canvas> support. Please try a newer web browser.";break}f.setAttribute("class","c1pjs-canvas");f.setAttribute("width",d.screenWidth);f.setAttribute("height",d.screenHeight);f.setAttribute("contenteditable","true");f.setAttribute("autocapitalize","off");f.setAttribute("autocorrect","off");f.style.backgroundColor=d.screenColor; +f.style.height="auto";0<=(window?window.navigator.userAgent:"").indexOf("MSIE")&&(f.style.height=(c.clientWidth*d.screenHeight/d.screenWidth|0)+"px",c.onresize=function(a,b,c,d){return function(){b.style.height=(a.clientWidth*d/c|0)+"px"}}(c,f,d.screenWidth,d.screenHeight));c.appendChild(f);var g=new Image,k=f.getContext("2d"),f=new Ma(d,f,k,g);g.onload=function(a){return function(){a.N()}}(f,d.charSet);g.src=d.charSet;H(f,c)}}); +function Pa(a){B.call(this,"C1PSerialPort",a);this.u.H=!1;this.m=a.demo;this.reset(!0)}D(Pa);e=Pa.prototype;e.reset=function(a){if(a||2!=this.g){this.h=-1;this.i=0;this.c="";if(this.m){a=1;if(this.Da){var b=this.Da.match(/\d+/);null!==b&&(a=parseInt(b[0],10))}this.c='10 PRINT "HELLO OSI #'+a+'"\n'}this.j=!0;this.g=0}};e.start=function(){this.b&&this.m&&(V(this.b," C\n\n",3E3),setTimeout(function(a){return function(){a.g=1;V(a.b,"LOAD\n")}}(this),12E3));this.m=!1}; +e.J=function(a,b,c){var d=this;switch(b){case "listSerial":return this.A[b]=c,!0;case "loadSerial":return this.A[b]=c,c.onclick=function(){d.A.listSerial&&r(d.A.listSerial.value,function(a,b,c){Qa(d,a,b,c)})},!0;case "mountSerial":return!v("Mobi")&&window&&"FileReader"in window?(this.A[b]=c,c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length}),c.onsubmit=function(a){var b=a.currentTarget[1].files[0],c=new FileReader;c.onload=function(){Qa(d, +b.name,c.result.toString(),0)};c.readAsText(b);return!1}):c.parentNode.removeChild(c),!0}return!1};e.X=function(a,b,c,d){this.a=a;this.o=b;this.v=c-b+1;this.s=this.o+this.v;if(this.f=d)va(d,b,c,this,this.W),O(d,b,c,this,this.R);this.N()};e.$=function(a,b){a&&!this.u.H&&(this.u.H=!0,this.I=b,this.b=L(b,"keyboard"))}; +function Qa(a,b,c,d){if(c){a.i=0;a.c=c;a.j=!0;a.g=0;if(-1!==b.indexOf(".json",b.length-5))try{d="";var f=eval("("+c+")").bytes;for(c=0;c=--d.ha&&(0=d.Ia&&(d.aa=d.Ia),0>d.aa&&(d.aa=0),d.ha=20,a.g.update(a.g.D|128),Va(a))}this.D=c;a.m.D&4&&W(a,2,this)}}(a)};a.m={D:0,read:function(){}, +update:function(a){return function(c){void 0!==c&&(this.D=c&-193);W(a,3,this);a.i.update();a.w.update()}}(a)};a.B={D:0,read:function(){},update:function(a){return function(c){void 0!==c&&(3==(c&3)&&(a.h.D=14),this.D=c);a.h.update()}}(a)};a.h={D:14,read:function(){},update:function(a){return function(c){void 0===c&&(c=a.h.D);c&=-2;0<=a.b&&0<=a.c[a.b].ga&&(c|=1);this.D=c;W(a,16,this)}}(a)};a.s={D:0,read:function(a){return function(){Wa(a)}}(a),update:function(a){return function(c){void 0!==c&&(this.D= +c);W(a,17,this)}}(a)};a.C={D:0,read:function(){},update:function(){return function(){}}(a)}}e.J=function(a,b,c){switch(b){case "listDisk":return this.A[b]=c,!0;case "loadDisk":return this.A[b]=c,c.onclick=function(a){return function(){if(a.A.listDisk){var b=a.A.listDisk.value,c=b;".json"!=b.substr(b.length-5)&&(c="http://"+window.location.host+"/api/v1/dump?disk="+b);a.F("loading "+aa(b)+"...");r(c,function(b,c,f){Xa(a,b,c,f)})}}}(this),!0}return!1}; +e.X=function(a,b,c,d){this.a=a;this.o=b;if(this.f=d)va(d,b,c,this,this.W),O(d,b,c,this,this.R);this.N()};e.$=function(a){a&&!this.u.H&&(this.u.H=!0)}; +function Xa(a,b,c,d){if(d)a.F("disk load error ("+d+")");else{d=[];a.F("mounting "+b+"...");try{if(d=eval("("+c+")"),d.length)if(d[0].length){var f=d[0];if(void 0===f[0].trackNum)a.F("data error: "+f[0]);else if(a.c[0]){for(c=0;c>8&255);a.push(b&255)}function Ya(a,b,c){b=b[c];if(void 0===b)throw Error("missing signature: "+c);for(c=0;cb?b&=3:32>b&&(b&=17);switch(b){case 0:a=a.j.D&4?a.g:a.v;break;case 1:a=a.j;break;case 2:a=a.m.D&4?a.i:a.w;break;case 3:a=a.m;break;case 16:a=c?a.B:a.h;break;case 17:a=a.s;break;default:a=a.C}return a}e.W=function(a,b){void 0!==b&&$a(this,a-this.o,!1).read()};e.R=function(a,b){if(void 0!==b){var c=this.f.W(a);$a(this,a-this.o,!0).update(c)}};function Ua(a,b,c){var d=-1;void 0!==b&&void 0!==c&&(d=0,c&32||(d|=2),a.g.D&64||(d|=1));a.b!=d&&(a.b=d,a.h.update())} +function Va(a){0<=a.b&&(a.c[a.b].ga=-1,a.s.update(255),a.h.update())}function Wa(a){var b=null;if(0<=a.b){var b=a.c[a.b],c=b.ta[b.aa];void 0!==c&&(0<=b.ga&&b.ga");b&&b.$(!0,a)} +y(function(){for(var a=I(document,"c1pjs","computer"),b=0;b');return}}if(void 0===k){t(' definition must appear first in the specification'); +break}if(f=F("debugger",d.id))g["debugger"]=[f],f.X&&f.X(k,h,l,g.cpu[0]);h=new Y(d,g);if(l=F("panel",d.id))if(g.panel=[l],l.za){f=d.id;d=void 0;g=[];f&&(f=0<(d=f.indexOf("."))?f.substr(0,d+1):"");for(d=0;dh.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(h=window.location.pathname+h);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(h?' url="'+h+'"':""))}f||(a=a.replace(/().*?(<\/xsl:variable>)/, +"$1c1pjs$2"));h=null;if("<"==a.charAt(0))try{f||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(h=new window.ActiveXObject("Microsoft.XMLDOM"),h.async=!1,h.loadXML(a)):h=(new window.DOMParser).parseFromString(a,"text/xml")}catch(u){h=null,a=u.message}else a="unrecognized XML: "+(255/g.exec(a)){var f=d[2];b("Loading "+f+"...");r(f,function(g,k,h){if(h||!k)c(a,"unable to resolve XML reference: "+d[0]+" ("+h+")");else{if(g=d[3])if(h=k.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var l=h[0],m,n=/( [a-z]+=)(['"])(.*?)\2/g;m=n.exec(g);)l=0>l.indexOf(m[1])?l.replace(">",m[0]+">"):l.replace(new RegExp(m[1]+"(['\"])(.*?)\\1"),m[0]);h[0]!=l&&(k=k.replace(h[0],l))}else{c(a,"missing <"+d[1]+"> in "+f);return}k=k.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],k);db(a,b,c)}})}else c(a,null)} +function fb(a,b,c){function d(a){if(void 0===k){var b=g&&I(g,"machine-warning");k=b&&b[0]||g}k&&(k.innerHTML=da(a))}function f(a){d("Error: "+a);h&&(--Z||A(!0));h=!1}var g,k,h=!0;Z++;E[a]={};try{if(g=document.getElementById(a)){var l;if("object"==typeof resources&&(l=resources.css)){var m=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css";n.styleSheet?n.styleSheet.cssText=l:n.appendChild(document.createTextNode(l));m.appendChild(n)}c||(c="/versions/c1pjs/1.24.2/components.xsl"); +l=function(h,k){k?bb(c,null,null,!1,d,function(h,l){if(l)if(E[a]&&c&&(E[a][c]=h),d("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var m=k.transformNode(l);m?(g.outerHTML=m,--Z||A(!0)):f("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(m=new XSLTProcessor,m.importStylesheet(l),(m=m.transformToFragment(k,document))?g.parentNode?(g.parentNode.replaceChild(m,g),--Z||A(!0)):f("invalid machine element: "+a):f("transformToFragment failed")): +f("unable to transform XML: unsupported browser");else f(h)}):f(h)};"<"!=b.charAt(0)?bb(b,a,void 0,!0,d,l):cb(b,null,a,void 0,!1,d,l)}else f("missing machine element: "+a)}catch(u){f(u.message)}return h}window.embedC1P=function(a,b,c){A(!1);return fb(a,b,c)};window.enableEvents=A;window.sendEvent=ha;})(); diff --git a/versions/c1pjs/1.24.2/common.css b/versions/c1pjs/1.24.2/common.css new file mode 100644 index 000000000..6b1c0f887 --- /dev/null +++ b/versions/c1pjs/1.24.2/common.css @@ -0,0 +1,265 @@ +@CHARSET "UTF-8"; +/** + @author Jeff Parsons (@jeffpar) + @website http://www.pcjs.org/ + @created 2013-05-05 + @modified 2014-02-23 + @license http://www.gnu.org/licenses/gpl.html + */ +body { + margin: 0; + background: #202020; +} +h1, h2 { + margin-top: 0; + color: #cccccc; +} +h1, h2, h3, h4 { + word-wrap: break-word; +} + +h4 a { + color: #cccccc !important; +} +p { + line-height: 1.5em; +} +img { + max-width: 100%; +} +a img { + vertical-align: bottom; +} +pre, code { + color: #000000; + background-color: #cccccc; + font-family: Monaco, Consolas, "Lucida Console", monospace; + font-size: 12px; +} +pre { + margin: 1em 2em; + padding: 1em; + border-radius: 5px; + overflow: auto; +} +code { + padding: 1px; +} +pre a, code a { + color: #006400 !important; +} +.common { + width: 100%; + margin: 0 auto; + color: #cccccc; +} +.common a { + + color: #7fc07f; + text-decoration: none; +} +.common hr { + border-color: #808080; +} +.common a:hover { + text-decoration: underline; +} +.common, .machine { + font-family: "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif; + font-size: 15px; +} +.machine { + margin: 15px; + overflow: hidden; +} +.c1pjs { + overflow: visible; +} +.machine-placeholder { + text-align: center; + font-weight: bold; +} +.common-top { + background: #202020; + font-size: small; +} +.common-top-left { + float: left; + width: 60%; +} +.common-top-left ul { + line-height: 1.5em; + list-style-type: none; + margin: 0; + padding: 1em 1em 1em 9px; + overflow: hidden; +} +.common-top-left ul li { + display: block; + float: left; +} +.common-top-left ul li a { + border-right: 1px solid #6f6f6f; + padding: 2px 6px 2px 6px; +} +.common-top-left ul li:last-child a { + border-right: none; +} +.common-top-right { + float: right; + width: 40%; +} +.common-top-right p { + float: right; + margin: 0; + padding: 1em; +} +.common-middle { + clear: both; + padding: 1px 1em 1px 1em; + background: #404040; +} +.common-sidebar { + float: left; + font-size: small; + width: 140px; + padding-bottom: 20px; + overflow: hidden; + white-space: nowrap; + word-wrap: break-word; +} +.common-list { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} +.common-list li { + + padding-bottom: 7px; +} +.common-list-data { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} +.common-list-data li { + line-height: 1.5em; +} +.common-list-data-items, .common-list-data-subitems { + font-size: x-small; + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 2em; +} +.common-list-data-items li, .common-list-data-subitems li { + padding-bottom: 0; +} +.common-main { + margin-left: 150px; + +} +.common-main blockquote { + text-align: justify; +} +.common-image-gallery { + margin: 0 auto; + text-align: center; +} +.common-image-gallery:after { + content: ''; + display: block; +} +.common-image-frame { + display: inline-block; + margin: 8px; + text-align: center; +} +.common-image-link { + padding: 5px; + border: 1px solid black; + border-radius: 5px; + background-color: #FAEBD7; +} +.common-image-label { + font-size: x-small; +} +.common-bottom { + clear: both; + padding-top: 1em; +} +.common-bottom:after { + content: ''; + display: block; + clear: both; +} +.common-reference { + float: left; + font-size: x-small; +} +.common-reference a { + text-decoration: none; +} +.common-copyright { + float: right; + font-size: x-small; +} +.common-copyright a { + text-decoration: none; +} +.md-list { +} +.md-list li { + line-height: 1.5em; + margin-bottom: 1em; +} +.md-list li p { + padding-left: 2em; +} +.md-list-compact { +} +.md-list-compact li { + margin-bottom: 0; +} +.md-list-none { + list-style-type: none; + padding-left: 2em; +} +.md-list-none li { + margin-bottom: 0; +} +@media screen and (max-width: 900px) { + + .common-sidebar { + width: 100%; + white-space: normal; + } + .common-list { + padding-left: 0; + } + .common-list-data { + padding-left: 0; + } + .common-sidebar h4, .common-list li, .common-list-data li, .common-list-data-items li { + width: 130px; + float: left; + overflow: hidden; + vertical-align: top; + padding-right: 1em; + margin-top: 0; + } + .common-list-data-subitems { + display: none; + } + .common-main { + clear: both; + margin-left: 0; + padding-left: 0; + padding-right: 0; + } + .md-list-none { + padding-left: 1em; + } +} diff --git a/versions/c1pjs/1.24.2/common.xsl b/versions/c1pjs/1.24.2/common.xsl new file mode 100644 index 000000000..444139dd8 --- /dev/null +++ b/versions/c1pjs/1.24.2/common.xsl @@ -0,0 +1,58 @@ + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+

Powered by JavaScript and GitHub

+
+
+
+ + +
+

+ +
+
+ +
diff --git a/versions/c1pjs/1.24.2/components.css b/versions/c1pjs/1.24.2/components.css new file mode 100644 index 000000000..604435675 --- /dev/null +++ b/versions/c1pjs/1.24.2/components.css @@ -0,0 +1,108 @@ +@CHARSET "UTF-8"; + + +*:not(input,textarea) { + -webkit-user-select: none; +} +.c1pjs-embed { +} +.c1pjs-embed:after { + clear:both; +} +.c1pjs-machine { +} +.c1pjs-name { + clear: both; + font-weight: bold; + padding-bottom: 4px; +} +.c1pjs-canvas { + width: 100%; + height: auto; +} +.c1pjs-container { + color: #000000; + position: relative; +} +.c1pjs-label { + font-size: small; + line-height: 19px; + vertical-align: middle; + float: left; + font-family: "Lucida Console", monospace; +} +.c1pjs-control textarea { + font-family: Monaco, monospace; + font-size: x-small; +} +.c1pjs-fieldset { + border: none; + margin: 0; + padding: 0; +} +.c1pjs-flag { + font-family: "Lucida Console", monospace; + font-size: small; + text-align: center; + line-height: 19px; + vertical-align: middle; +} +.c1pjs-register { + font-family: "Lucida Console", monospace; + font-size: small; + text-align: center; + line-height: 19px; + vertical-align: middle; + border: 1px solid black; +} +.c1pjs-switches { + float: left; +} +.c1pjs-bitBucket { + float: left; + width: 19px; + height: 38px; +} +.c1pjs-bitCell { + float: left; + width: 19px; + height: 19px; + margin-right: -1px; + margin-bottom: -1px; + border: 1px solid black; + text-align: center; + line-height: 19px; +} +.c1pjs-bitCellLeft { + border-left: 1px solid black; +} +.c1pjs-bitLabel { + font-size: xx-small; + text-align: center; +} +.c1pjs-description, .c1pjs-status { + font-size: small; + line-height: 2em; +} +.c1pjs-key { + border: 1px solid black; + font-size: x-small; + text-align: center; + position: absolute; + height: 34px; + line-height: 34px; +} +.c1pjs-reference { + float: left; + font-size: x-small; +} +.c1pjs-reference a { + text-decoration: none; +} +.c1pjs-copyright { + float: right; + font-size: x-small; +} +.c1pjs-copyright a { + text-decoration: none; +} diff --git a/versions/c1pjs/1.24.2/components.xsl b/versions/c1pjs/1.24.2/components.xsl new file mode 100644 index 000000000..34711400c --- /dev/null +++ b/versions/c1pjs/1.24.2/components.xsl @@ -0,0 +1,588 @@ + + + + + + + + + + + c1p + c1pjs + 1.24.2 + www.pcjs.org + + + + + + + + + + + + + + + + + + + + + + +
+ + + + js + , + + +
+
+ + + + + + + + + + + + + , + + + + + + + + + + + + .machine + . + + + + + + + + + + + + + + border:1px solid black;border-radius:10px; + border:; + + + + + + left:; + + + + + + top:; + + + + + + + + width:; + width:auto;max-width:; + + + + + + + + height:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto; + position:; + position:absolute; + + + + + overflow:auto;width:100%; + background-color:; + + + + - -component + +
+ + + + + + +
+ +
+
+ +
+ +
+
+ +
+ + +
[XML]
+ +
+ +
+
+
+
+ + + + + text-align:center; + + + +

+
+ + +
+
+ + + + type:'' + + + binding:'' + + + + border:1px solid black; + border:; + + + + + + width:; + + + + + + height:; + + + + + + left:; + + + + + + top:; + + + + + + position:absolute; + float:left; + float:right; + margin:0 auto; + ; + float:left; + + + + + + + + +
+ + + font-size:; + + + + + -label + + + width:; + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+
+
+ +
+
+ +

+
+ +
+
+
+ + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + null + + + + + + ,autoStart: + + + + + + + + + + + + + + + 600 + + + + + keyboard + ,model: + + + + + + + + + + + + + + + false + + + + + serial + ,demo: + + + + + + + + + + + + + + disk + + + + + + + + + + + + + + + 0 + + + + + + + + + + + rom + ,size:,image:'' + + + + + + + + + + + + + + + 0 + + + + + ram + ,size: + + + + + + + + + + + + + + + 600 + + + + + + + 256 + + + + + + + 224 + + + + + + + black + + + + + + 32 + + + + + + 32 + + + + + + + 0 + + + + + + + 0 + + + + + + + + + + + + + + null + + + + + video + ,model:,screenWidth:,screenHeight:,charCols:,charRows:,charWidth:,charHeight:,charSet:'',screenColor:'',smoothing: + + + + + + + + + + + + + + debugger + + + + + + + + + + + + + + panel + + + + + + + + + + + + + [ + {} + , + ] + + + + computer + ,modules: + + + + + type:'',refID:'',start:,end: + + +
diff --git a/versions/c1pjs/1.24.2/document.css b/versions/c1pjs/1.24.2/document.css new file mode 100644 index 000000000..7072b406e --- /dev/null +++ b/versions/c1pjs/1.24.2/document.css @@ -0,0 +1,162 @@ +@CHARSET "UTF-8"; + +.page { + margin: 2% 2%; + padding: 2% 2%; + min-width: 30em; + overflow: auto; + font-size: large; + font-family: Helvetica, Arial, sans-serif; + background: #303030; + color: #ccc; + +} +.page-header { +} +.page-header-title { + text-align: center; + +} +.page a { + color: #7fc07f; + text-decoration: none; +} +a.footlink, a.paralink { + text-decoration: none; +} +a.footlink:link, a.paralink:link { + color: blue; +} +a.footlink:visited, a.paralink:visited { + color: blue; +} +.galleryitem { + float: left; + width: 200px; +} +.item { + float: left; + width: 2em; + text-indent: 1em; +} +.list { + margin-left: 3em; + text-indent: 0; + text-align: justify; +} +ul { + list-style: none; +} +div.pnumber { + float: left; + width: 2em; + text-indent: 1em; +} +div.pitem { + margin-left: 10em; +} +p.indent, .justified p { + text-indent: 2em; + text-align: justify; + line-height: 1.5em; +} +p.noindent { + text-indent: 0; + text-align: justify; +} +p.center, .center { + text-align: center; +} +li.para { + margin-top: 1em; + margin-bottom: 1em; +} +.left { + text-align: left; +} +.right { + text-align: right; +} +blockquote.tag { + font-size: small; + font-family: Monaco, Fixed, monospace; + margin-top: 0; + margin-bottom: 0; +} +.blockquote { + padding-left: 1em; + text-indent: 0; + text-align: justify; +} +.italics { + font-style: italic; +} +.medium { + font-size: medium; +} +.small { + font-size: x-small; +} +.smallcaps { + font-variant: small-caps; +} +.strike { + text-decoration: line-through; +} +.summation, .bracelist { + display: inline-block; + position: relative; + vertical-align: middle; + text-align: center; + margin-bottom: 0.5ex; + text-indent: 0; +} +.bracelist-symbol { + font-size: 3em; + vertical-align: -40%; +} +.summation .summation-lower, .summation .summation-upper, .bracelist-item { + display: block; + font-size: 75%; + text-align: center; +} +.summation .summation-upper { + margin-bottom: 0; + margin-left: 0.8ex; + font-style: italic; +} +.summation .summation-lower{ + margin-bottom: -0.6ex; + font-style: italic; +} +.summation .summation-symbol { + font-size: 2em; +} +p sup { + vertical-align: baseline; + position: relative; + bottom: .5em; + font-size: small; +} +p sub { + vertical-align: baseline; + position: relative; + bottom: -.5em; + font-size: small; +} +.footnote { + font-size: medium; + text-indent: 1em; + text-align: justify; + margin-top: .5em; +} +.image-right { + float: right; + margin-left: 1em; + margin-top: 1em; + margin-bottom: 1em; +} +.image-caption { + font-size: small; + text-align: center; +} \ No newline at end of file diff --git a/versions/c1pjs/1.24.2/document.xsl b/versions/c1pjs/1.24.2/document.xsl new file mode 100644 index 000000000..38d3d64f6 --- /dev/null +++ b/versions/c1pjs/1.24.2/document.xsl @@ -0,0 +1,452 @@ + + + + + +]> + + + + + + + + + +

+
+ + + + + + + +

+
+ +

+
+
+
+ + + + + + +
+
+ + +
+ +   + + +
+
+ +
+
+ + + + + + + + + + + + + + + + +

+
+ + +

+
+ + +

+
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + +
+
+ + +
+
+ + +
  • +
    + + +
    image
    +
    + + +
    +
    + + + + +
    {.}
    +
    + +
    {.}
    +
    +
    +
    + + + + + + + + + + < + > + + + + × + + ÷ + σ + + + + + + + + + + + + { + + + + + + + + + + [] + + + + +
    + +
    +
    + + + , and + + + + + MDY + + + + + + + + + + + + + + + + + + + + January + February + March + April + May + June + July + August + September + October + November + December + + + , + + + + + +

    + +
    +
    + + +
    + {.}
    +
    +
    +
    + + + +

    Timeline

    +
    + +

    +
    +
    + +
    +
    + + + + + + + + + +

    +
    + +
    +
    +
    + + + +

    People

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + +

    +
      + +
    +
    + + + + + + + + + + +
  • + +
  • +
    + + + +

    +
    +

    + +

    +
    +
    + + + + false + + + + + + [Original] + + + + + + + + + + [] + + +
    by
    + + +
    + [Source: + + + + + + + ] +
    +
    +
    + + + +

    Resources

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + + +

    +
    +
      + +
    +
    + + +
  • +
    + + + +

    +
    +
    + +
    +
    + + + +

    +
    + +
    + + + +

    +
    +
      + +
    +
    + + + + + +
      + +
    +
    + + + + +
  • +
    + +
  • +
    + +
  • +
    +
    +
    + + +
  • +
    + + + + + + + + + + +
    + < ="" + + ></> + ></> + /> + +
    +
    + +
    diff --git a/versions/c1pjs/1.24.2/machine.xsl b/versions/c1pjs/1.24.2/machine.xsl new file mode 100644 index 000000000..90e651791 --- /dev/null +++ b/versions/c1pjs/1.24.2/machine.xsl @@ -0,0 +1,49 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    +
    + + + + js + , + +
    +
    + +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/c1pjs/1.24.2/manifest.xsl b/versions/c1pjs/1.24.2/manifest.xsl new file mode 100644 index 000000000..2812e6ff2 --- /dev/null +++ b/versions/c1pjs/1.24.2/manifest.xsl @@ -0,0 +1,247 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Document Manifest

    +
    +
      + + + + None + + + + + + + + + + + + + + + + +
    +
    +
    +

    + +
    +
    +
    + + +
    + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Software Manifest

    +
    +
      + + + + None + + + + + Unknown + + + + + None + + + + + None + + + + + + + + + + + + + UpdatedReleased + + Unknown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +

    No default machine specified for '' in manifest.xml

    +
    + +
    +
    +
    + + + + -dbg + + + + + + +
    + + + + + Unknown + +
  • +
      + + + + + + + + +
    • + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
      • + + + + + + +
      • +
        +
      +
      +
    • +
      + + + + + + + + +
    +
  • +
    +
    + +
    diff --git a/versions/c1pjs/1.24.2/outline.xsl b/versions/c1pjs/1.24.2/outline.xsl new file mode 100644 index 000000000..e2cc08c7c --- /dev/null +++ b/versions/c1pjs/1.24.2/outline.xsl @@ -0,0 +1,47 @@ + + + + +]> + + + + + + + + + + + + + + + + + + <xsl:value-of select="title"/><xsl:text> | </xsl:text><xsl:value-of select="$SITEHOST"/> + + + + + +
    +
    + +
    +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pc8080/1.24.2/common.css b/versions/pc8080/1.24.2/common.css new file mode 100644 index 000000000..6b1c0f887 --- /dev/null +++ b/versions/pc8080/1.24.2/common.css @@ -0,0 +1,265 @@ +@CHARSET "UTF-8"; +/** + @author Jeff Parsons (@jeffpar) + @website http://www.pcjs.org/ + @created 2013-05-05 + @modified 2014-02-23 + @license http://www.gnu.org/licenses/gpl.html + */ +body { + margin: 0; + background: #202020; +} +h1, h2 { + margin-top: 0; + color: #cccccc; +} +h1, h2, h3, h4 { + word-wrap: break-word; +} + +h4 a { + color: #cccccc !important; +} +p { + line-height: 1.5em; +} +img { + max-width: 100%; +} +a img { + vertical-align: bottom; +} +pre, code { + color: #000000; + background-color: #cccccc; + font-family: Monaco, Consolas, "Lucida Console", monospace; + font-size: 12px; +} +pre { + margin: 1em 2em; + padding: 1em; + border-radius: 5px; + overflow: auto; +} +code { + padding: 1px; +} +pre a, code a { + color: #006400 !important; +} +.common { + width: 100%; + margin: 0 auto; + color: #cccccc; +} +.common a { + + color: #7fc07f; + text-decoration: none; +} +.common hr { + border-color: #808080; +} +.common a:hover { + text-decoration: underline; +} +.common, .machine { + font-family: "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif; + font-size: 15px; +} +.machine { + margin: 15px; + overflow: hidden; +} +.c1pjs { + overflow: visible; +} +.machine-placeholder { + text-align: center; + font-weight: bold; +} +.common-top { + background: #202020; + font-size: small; +} +.common-top-left { + float: left; + width: 60%; +} +.common-top-left ul { + line-height: 1.5em; + list-style-type: none; + margin: 0; + padding: 1em 1em 1em 9px; + overflow: hidden; +} +.common-top-left ul li { + display: block; + float: left; +} +.common-top-left ul li a { + border-right: 1px solid #6f6f6f; + padding: 2px 6px 2px 6px; +} +.common-top-left ul li:last-child a { + border-right: none; +} +.common-top-right { + float: right; + width: 40%; +} +.common-top-right p { + float: right; + margin: 0; + padding: 1em; +} +.common-middle { + clear: both; + padding: 1px 1em 1px 1em; + background: #404040; +} +.common-sidebar { + float: left; + font-size: small; + width: 140px; + padding-bottom: 20px; + overflow: hidden; + white-space: nowrap; + word-wrap: break-word; +} +.common-list { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} +.common-list li { + + padding-bottom: 7px; +} +.common-list-data { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} +.common-list-data li { + line-height: 1.5em; +} +.common-list-data-items, .common-list-data-subitems { + font-size: x-small; + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 2em; +} +.common-list-data-items li, .common-list-data-subitems li { + padding-bottom: 0; +} +.common-main { + margin-left: 150px; + +} +.common-main blockquote { + text-align: justify; +} +.common-image-gallery { + margin: 0 auto; + text-align: center; +} +.common-image-gallery:after { + content: ''; + display: block; +} +.common-image-frame { + display: inline-block; + margin: 8px; + text-align: center; +} +.common-image-link { + padding: 5px; + border: 1px solid black; + border-radius: 5px; + background-color: #FAEBD7; +} +.common-image-label { + font-size: x-small; +} +.common-bottom { + clear: both; + padding-top: 1em; +} +.common-bottom:after { + content: ''; + display: block; + clear: both; +} +.common-reference { + float: left; + font-size: x-small; +} +.common-reference a { + text-decoration: none; +} +.common-copyright { + float: right; + font-size: x-small; +} +.common-copyright a { + text-decoration: none; +} +.md-list { +} +.md-list li { + line-height: 1.5em; + margin-bottom: 1em; +} +.md-list li p { + padding-left: 2em; +} +.md-list-compact { +} +.md-list-compact li { + margin-bottom: 0; +} +.md-list-none { + list-style-type: none; + padding-left: 2em; +} +.md-list-none li { + margin-bottom: 0; +} +@media screen and (max-width: 900px) { + + .common-sidebar { + width: 100%; + white-space: normal; + } + .common-list { + padding-left: 0; + } + .common-list-data { + padding-left: 0; + } + .common-sidebar h4, .common-list li, .common-list-data li, .common-list-data-items li { + width: 130px; + float: left; + overflow: hidden; + vertical-align: top; + padding-right: 1em; + margin-top: 0; + } + .common-list-data-subitems { + display: none; + } + .common-main { + clear: both; + margin-left: 0; + padding-left: 0; + padding-right: 0; + } + .md-list-none { + padding-left: 1em; + } +} diff --git a/versions/pc8080/1.24.2/common.xsl b/versions/pc8080/1.24.2/common.xsl new file mode 100644 index 000000000..92e18d9a8 --- /dev/null +++ b/versions/pc8080/1.24.2/common.xsl @@ -0,0 +1,58 @@ + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +

    Powered by JavaScript and GitHub

    +
    +
    +
    + + +
    +

    + +
    +
    + +
    diff --git a/versions/pc8080/1.24.2/components.css b/versions/pc8080/1.24.2/components.css new file mode 100644 index 000000000..0e0842602 --- /dev/null +++ b/versions/pc8080/1.24.2/components.css @@ -0,0 +1,159 @@ +@CHARSET "UTF-8"; + + +*:not(input,textarea) { + -webkit-user-select: none; +} +.pcjs-embed { +} +.pcjs-embed:after { + clear:both; +} +.pcjs-machine { +} +.pcjs-name, .pcjs-menu { + clear: both; + font-weight: bold; + padding-bottom: 4px; +} +.pcjs-menu { + float: left; +} +.pcjs-canvas { + width: 100%; + height: auto; +} +.pcjs-container { + color: #000000; + position: relative; +} +.pcjs-label { + font-size: small; + line-height: 19px; + vertical-align: middle; + float: left; + font-family: "Lucida Console", monospace; +} +.pcjs-controls textarea { + font-family: Monaco, monospace; + font-size: x-small; +} +.pcjs-fieldset { + border: none; + margin: 0; + padding: 0; +} +.pcjs-flag { + font-family: "Lucida Console", monospace; + font-size: small; + text-align: center; + line-height: 19px; + vertical-align: middle; +} +.pcjs-register { + font-family: "Lucida Console", monospace; + font-size: small; + text-align: center; + line-height: 19px; + vertical-align: middle; + border: 1px solid black; +} +.pcjs-switches { + float: left; +} +.pcjs-bitBucket { + float: left; + width: 19px; + height: 38px; +} +.pcjs-bitCell { + float: left; + width: 19px; + height: 19px; + margin-right: -1px; + margin-bottom: -1px; + border: 1px solid black; + text-align: center; + line-height: 19px; +} +.pcjs-bitCellLeft { + border-left: 1px solid black; +} +.pcjs-bitLabel { + font-size: xx-small; + text-align: center; +} +.pcjs-description, .pcjs-status { + font-size: x-small; + line-height: 2em; +} +.pcjs-key { + border: 1px solid black; + font-size: x-small; + text-align: center; + position: absolute; + height: 34px; + line-height: 34px; + background-color: #ffffff; +} +.pcjs-led { + float: left; + width: 8px; + height: 8px; + margin: 4px; + border: 1px solid black; + text-align: center; + line-height: 19px; + background-color: #000000; +} +.pcjs-rled { + float: left; + width: 8px; + height: 8px; + margin: 4px; + border: 1px solid black; + border-radius: 50%; + text-align: center; + line-height: 19px; + background-color: #000000; +} +.pcjs-screen { + clear: both; + height: auto; + position: relative; + line-height: 0; +} +.pcjs-screen textarea { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + opacity: 0; + border: 0; + padding: 0; + line-height: 0; +} +.pcjs-reference { + float: left; + font-size: x-small; +} +.pcjs-reference a { + text-decoration: none; +} +.pcjs-copyright { + float: right; + font-size: x-small; +} +.pcjs-copyright a { + text-decoration: none; +} + +@media screen and (max-width: 900px) { + .pcjs-textarea { + width: 100% !important; + } + .pcjs-registers { + width: 100% !important; + } +} diff --git a/versions/pc8080/1.24.2/components.xsl b/versions/pc8080/1.24.2/components.xsl new file mode 100644 index 000000000..1fe5b3c8a --- /dev/null +++ b/versions/pc8080/1.24.2/components.xsl @@ -0,0 +1,1242 @@ + + + + + + + + + + + pc + pcjs + pc8080 + PC8080 + 1.24.2 + www.pcjs.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + float: + + + + js + + + +
    + + + + + + + + + + js + + + "" + + + + + +
    +
    + + + + + + + + + + + + + + + , + + + + + + + + + + + + + .machine + . + . + + + + + + + + + + + + + + + + + + + + ,comment:'' + + + + + + border:1px solid black;border-radius:15px; + border:; + + + + + + left:; + + + + + + top:; + + + + + + + + width:; + width:;max-width:; + width:auto;max-width:; + + + + + + + + height:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto;clear:both; + position:; + position:relative; + + + + + overflow:auto;width:100%; + background-color:; + + + + - -component + +
    + + + + + + +
    + + + + + + + + --object -screen + + +
    +
    + +
    + +
    +
    + + + + +
    + + +
    [XML]
    + +
    + + +
    +
    +
    +
    + + + + + text-align:center; + + + +

    +
    + + +
    +
    + + + + + + +
    +
    + + + + type:'' + + + binding:'' + + + value:'' + + + + border:1px solid black; + border:; + + + + + + width:; + + + + + + height:; + + + + + + left:; + + + + + + top:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto; + position:; + position:relative; + float:left; + + + + + + + + + + + + + + + + + + +
    + + + font-size:; + + + + + -label + + + + width:; + width:; + + + + + + + + text-align:right; + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    + + + + +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + ; + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8088 + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + 1 + + + + + + + null + + + + + + + -1 + + + + + + + -1 + + + + + + + -1 + + + + + + ,model:'',stepping:'',fpu:,cycles:,multiplier:,autoStart:,csStart:,csInterval:,csStop: + + + + + + + + + + + + + + + 8087 + + + + + + + + + + + + ,model:'',stepping:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + true + + + + + + false + + + + + + {} + + + + + + + + + + + + + + + + + chipset + ,model:'',scaleTimers:,sw1:'',sw2:'',sound:,floppies:,monitor:'',rtcDate:'' + + + + + + + + + + + + + + + + + + + + keyboard + ,model:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + parallel + ,adapter:,binding:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 0 + + + + + + + 0 + + + + + serial + ,adapter:,binding:'',tabSize:,charBOL: + + + + + + + + + + + + + + + + + + + + mouse + ,serial:'' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fdc + ,autoMount:'',sortBy:'' + + + + + + + + + + + + + + + + + + + + + xt + + + + + hdc + ,drives:'',type:'' + + + + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + null + + + + + + + + + + + + + + + + + + false + + + + + rom + ,addr:,size:,alias:,file:'',notify:'',writable: + + + + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + true + + + + + ram + ,addr:,size:,test: + + + + + + + + + + + + + + + + + + + + + null + + + + + + + 256 + + + + + + + 224 + + + + + + + black + + + + + + 0 + + + + + + 0 + + + + + + false + + + + + + 1bpp + + + + + + 0 + + + + + + 0 + + + + + + 1 + + + + + + 0 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + false + + + + + + 1 + + + + + + 1 + + + + + + + 80 + + + + + + + 25 + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + 0 + + + + + + null + + + + + + 0 + + + + + + 60 + + + + + video + ,model:'',mode:,screenWidth:,screenHeight:,screenColor:'',screenRotate:,bufferAddr:,bufferRAM:,bufferFormat:'',bufferCols:,bufferRows:,bufferBits:,bufferLeft:,bufferRotate:,memory:,switches:'',scale:,cellWidth:,cellHeight:,charCols:,charRows:,fontROM:'',fontColor:'',touchScreen:'',autoLock:,aspectRatio:,smoothing:,interruptRate:,refreshRate: + + + + + + + + + + + + + + + + + + + + + + + + + + debugger + ,commands:'',messages:'' + + + + + + + + + + + + + + panel + + + + + + + + + + + + + + + + + + + + + true + + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + computer + ,autoPower:,busWidth:,resume:,state:'' + + + + + + + +
    diff --git a/versions/pc8080/1.24.2/document.css b/versions/pc8080/1.24.2/document.css new file mode 100644 index 000000000..7072b406e --- /dev/null +++ b/versions/pc8080/1.24.2/document.css @@ -0,0 +1,162 @@ +@CHARSET "UTF-8"; + +.page { + margin: 2% 2%; + padding: 2% 2%; + min-width: 30em; + overflow: auto; + font-size: large; + font-family: Helvetica, Arial, sans-serif; + background: #303030; + color: #ccc; + +} +.page-header { +} +.page-header-title { + text-align: center; + +} +.page a { + color: #7fc07f; + text-decoration: none; +} +a.footlink, a.paralink { + text-decoration: none; +} +a.footlink:link, a.paralink:link { + color: blue; +} +a.footlink:visited, a.paralink:visited { + color: blue; +} +.galleryitem { + float: left; + width: 200px; +} +.item { + float: left; + width: 2em; + text-indent: 1em; +} +.list { + margin-left: 3em; + text-indent: 0; + text-align: justify; +} +ul { + list-style: none; +} +div.pnumber { + float: left; + width: 2em; + text-indent: 1em; +} +div.pitem { + margin-left: 10em; +} +p.indent, .justified p { + text-indent: 2em; + text-align: justify; + line-height: 1.5em; +} +p.noindent { + text-indent: 0; + text-align: justify; +} +p.center, .center { + text-align: center; +} +li.para { + margin-top: 1em; + margin-bottom: 1em; +} +.left { + text-align: left; +} +.right { + text-align: right; +} +blockquote.tag { + font-size: small; + font-family: Monaco, Fixed, monospace; + margin-top: 0; + margin-bottom: 0; +} +.blockquote { + padding-left: 1em; + text-indent: 0; + text-align: justify; +} +.italics { + font-style: italic; +} +.medium { + font-size: medium; +} +.small { + font-size: x-small; +} +.smallcaps { + font-variant: small-caps; +} +.strike { + text-decoration: line-through; +} +.summation, .bracelist { + display: inline-block; + position: relative; + vertical-align: middle; + text-align: center; + margin-bottom: 0.5ex; + text-indent: 0; +} +.bracelist-symbol { + font-size: 3em; + vertical-align: -40%; +} +.summation .summation-lower, .summation .summation-upper, .bracelist-item { + display: block; + font-size: 75%; + text-align: center; +} +.summation .summation-upper { + margin-bottom: 0; + margin-left: 0.8ex; + font-style: italic; +} +.summation .summation-lower{ + margin-bottom: -0.6ex; + font-style: italic; +} +.summation .summation-symbol { + font-size: 2em; +} +p sup { + vertical-align: baseline; + position: relative; + bottom: .5em; + font-size: small; +} +p sub { + vertical-align: baseline; + position: relative; + bottom: -.5em; + font-size: small; +} +.footnote { + font-size: medium; + text-indent: 1em; + text-align: justify; + margin-top: .5em; +} +.image-right { + float: right; + margin-left: 1em; + margin-top: 1em; + margin-bottom: 1em; +} +.image-caption { + font-size: small; + text-align: center; +} \ No newline at end of file diff --git a/versions/pc8080/1.24.2/document.xsl b/versions/pc8080/1.24.2/document.xsl new file mode 100644 index 000000000..15ca6874c --- /dev/null +++ b/versions/pc8080/1.24.2/document.xsl @@ -0,0 +1,452 @@ + + + + + +]> + + + + + + + + + +

    +
    + + + + + + + +

    +
    + +

    +
    +
    +
    + + + + + + +
    +
    + + +
    + +   + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + +

    +
    + + +

    +
    + + +

    +
    + + +
    +
    + + +
    +
    + + + + + + + + + + + + + + +
    +
    + + +
    +
    + + +
  • +
    + + +
    image
    +
    + + +
    +
    + + + + +
    {.}
    +
    + +
    {.}
    +
    +
    +
    + + + + + + + + + + < + > + + + + × + + ÷ + σ + + + + + + + + + + + + { + + + + + + + + + + [] + + + + +
    + +
    +
    + + + , and + + + + + MDY + + + + + + + + + + + + + + + + + + + + January + February + March + April + May + June + July + August + September + October + November + December + + + , + + + + + +

    + +
    +
    + + +
    + {.}
    +
    +
    +
    + + + +

    Timeline

    +
    + +

    +
    +
    + +
    +
    + + + + + + + + + +

    +
    + +
    +
    +
    + + + +

    People

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + +

    +
      + +
    +
    + + + + + + + + + + +
  • + +
  • +
    + + + +

    +
    +

    + +

    +
    +
    + + + + false + + + + + + [Original] + + + + + + + + + + [] + + +
    by
    + + +
    + [Source: + + + + + + + ] +
    +
    +
    + + + +

    Resources

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + + +

    +
    +
      + +
    +
    + + +
  • +
    + + + +

    +
    +
    + +
    +
    + + + +

    +
    + +
    + + + +

    +
    +
      + +
    +
    + + + + + +
      + +
    +
    + + + + +
  • +
    + +
  • +
    + +
  • +
    +
    +
    + + +
  • +
    + + + + + + + + + + +
    + < ="" + + ></> + ></> + /> + +
    +
    + +
    diff --git a/versions/pc8080/1.24.2/machine.xsl b/versions/pc8080/1.24.2/machine.xsl new file mode 100644 index 000000000..89de96410 --- /dev/null +++ b/versions/pc8080/1.24.2/machine.xsl @@ -0,0 +1,49 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    +
    + + + + js + , + +
    +
    + +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pc8080/1.24.2/manifest.xsl b/versions/pc8080/1.24.2/manifest.xsl new file mode 100644 index 000000000..59e12f4cf --- /dev/null +++ b/versions/pc8080/1.24.2/manifest.xsl @@ -0,0 +1,247 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Document Manifest

    +
    +
      + + + + None + + + + + + + + + + + + + + + + +
    +
    +
    +

    + +
    +
    +
    + + +
    + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Software Manifest

    +
    +
      + + + + None + + + + + Unknown + + + + + None + + + + + None + + + + + + + + + + + + + UpdatedReleased + + Unknown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +

    No default machine specified for '' in manifest.xml

    +
    + +
    +
    +
    + + + + -dbg + + + + + + +
    + + + + + Unknown + +
  • +
      + + + + + + + + +
    • + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
      • + + + + + + +
      • +
        +
      +
      +
    • +
      + + + + + + + + +
    +
  • +
    +
    + +
    diff --git a/versions/pc8080/1.24.2/outline.xsl b/versions/pc8080/1.24.2/outline.xsl new file mode 100644 index 000000000..b4f866b6d --- /dev/null +++ b/versions/pc8080/1.24.2/outline.xsl @@ -0,0 +1,47 @@ + + + + +]> + + + + + + + + + + + + + + + + + + <xsl:value-of select="title"/><xsl:text> | </xsl:text><xsl:value-of select="$SITEHOST"/> + + + + + +
    +
    + +
    +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pc8080/1.24.2/pc8080-dbg.js b/versions/pc8080/1.24.2/pc8080-dbg.js new file mode 100644 index 000000000..d4461e94b --- /dev/null +++ b/versions/pc8080/1.24.2/pc8080-dbg.js @@ -0,0 +1,245 @@ +(function(){var m;function ca(a,b){var c;if(a){b||(b=16);if("$"==a.charAt(0))b=16,a=a.substr(1);else if("0x"==a.substr(0,2))b=16,a=a.substr(2);else{var d=a.charAt(a.length-1).toLowerCase();"h"==d?(b=16,d=null):"."==d&&(b=10,d=null);null==d&&(a=a.substr(0,a.length-1))}var e,d=a,f=b;(f&&10!=f?16==f?null!==d.match(/^[0-9a-f]+$/i):2==f&&null!==d.match(/^[01]+$/i):null!==d.match(/^[0-9]+$/))&&!isNaN(e=parseInt(a,b))&&(c=e|0)}return c} +function n(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function da(a){return"0x"+n(a,2)}function t(a){return"0x"+n(a,4)}function ea(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("&");0":">",'"':""","'":"'"};function ka(a){return a.replace(/[&<>"']/g,function(a){return ja[a]})}function la(a,b){return(a+" ").slice(0,b)}function ma(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")} +var na={0:"NUL",1:"SOH",2:"STX",3:"ETX",4:"EOT",5:"ENQ",6:"ACK",7:"BEL",8:"BS",9:"TAB",11:"VT",12:"FF",13:"CR",14:"SO",15:"SI",16:"DLE",17:"XON",18:"DC2",19:"XOFF",20:"DC4",21:"NAK",22:"SYN",23:"ETB",24:"CAN",25:"EM",26:"SUB",27:"ESC",28:"FS",29:"GS",30:"RS",31:"US"};function oa(a,b,c){var d=0,e=a.length,f=0;for(void 0===c&&(c=function(a,b){return a>b?1:a>1,g;g=c(b,a[h]);0a?"0":"")+a}var b=new Date;return b.getFullYear()+"-"+a(b.getMonth()+1)+"-"+a(b.getDate())+" "+a(b.getHours())+":"+a(b.getMinutes())+":"+a(b.getSeconds())}function ra(a,b){var c;if(Array.prototype.indexOf)return a.indexOf(b,c);c=c||0;0>c&&(c+=a.length);0>c&&(c=0);for(var d=a.length;cb?this.Ya=this.id:(this.Cb=this.id.substr(0,b),this.Ya=this.id.substr(b+1));this[a]=c;this.C={Ma:!1,gb:!1,Kb:!1,wa:!1,ib:!1};this.Fb=null;this.C.ib=!1;this.N={};this.H=null;this.sa=d||0;Ta.push(this)}var Ua=void 0,Va={}; +if(window){Ua||(Ua=window.location.search.substr(1));for(var Wa,Za=/\+/g,$a=/([^&=]+)=?([^&]*)/g;Wa=$a.exec(Ua);)Va[decodeURIComponent(Wa[1].replace(Za," "))]=decodeURIComponent(Wa[2].replace(Za," "))}function ab(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b} +function bb(a,b){b||(b=w);a.prototype=ab(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var cb=window.PCjs.Machines||(window.PCjs.Machines={}),Ta=window.PCjs.Components||(window.PCjs.Components=[])}else cb={},Ta=[];function db(a,b,c){cb[a]&&b&&(cb[a][b]=c)}function Oa(a,b,c){b||v((c?c+": ":"")+a)} +function eb(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b=this.G?10:20>=this.G?12:24>=this.G?14:15;this.Ga=1<>2;this.u=this.Ga-1;this.J=this.L/this.Ga|0;this.K=this.J-1;this.B=[];this.j=[];this.D=this.I=!1;this.O=[];this.P=[];a=new F;yb(a,this.H);this.X=Array(this.J);for(b=0;b>>a.qa;0f&&(l=f);if(g&&g.size){if(g.type==d){if(e+f<=g.F)return g.yb+=g.F-e,g.F=e,!0;if(e>=g.F+g.yb){l=g.size-(e-k);l>f&&(l=f);g.yb=e-g.F+l;e=k+a.Ga;f-=l;h++;continue}}return Ab(1,e,f)}e=new F(e,l,a.Ga,d);yb(e,a.H,g);a.X[h++]=e;e=k+a.Ga;f-=l}return 0>=f?(a.status(Math.floor(c/1024)+"Kb "+Bb[d]+" at "+t(b)),!0):Ab(2,b,c)}m.$=function(a){return this.X[(a&this.w)>>>this.qa].lb(a&this.u,a)}; +function Cb(a,b){return a.X[(b&a.w)>>>a.qa].wb(b&a.u,b)}m.Sa=function(a){var b=a&this.u,c=(a&this.w)>>>this.qa;return b!=this.u?this.X[c].tc(b,a):this.X[c++].lb(b,a)|this.X[c&this.K].lb(0,a+1)<<8};function Db(a,b){var c=b&a.u,d=(b&a.w)>>>a.qa;return c!=a.u?a.X[d].Ob(c,b):a.X[d++].wb(c,b)|a.X[d&a.K].wb(0,b+1)<<8}m.ua=function(a,b){this.X[(a&this.w)>>>this.qa].nb(a&this.u,b&255,a)};function Fb(a,b,c){a.X[(b&a.w)>>>a.qa].zb(b&a.u,c&255,b)} +m.Ib=function(a,b){var c=a&this.u,d=(a&this.w)>>>this.qa;c!=this.u?this.X[d].yc(c,b&65535,a):(this.X[d++].nb(c,b&255,a),this.X[d&this.K].nb(0,b>>8&255,a+1))};function Gb(a,b){if(void 0===b)return a.D=!a.D,a.D;void 0===a.B[b]&&(a.B[b]=[null,!1]);a.B[b][1]=!a.B[b][1];return a.B[b][1]}function Hb(a,b,c,d){void 0===d&&(d=0);if(c)for(var e in c){var f=a,h=+e+d,g=c[e].bind(b);if(void 0!==g)for(var k=+e+d;k<=h;k++)void 0!==f.B[k]?v("Input port "+t(k)+" already registered"):f.B[k]=[g,!1]}} +function Ib(a,b,c){for(var d=1,e=0,f=0;0>>=f)&k;if(void 0!==h){if(h[0])h[0](b,k,d);a.H&&a.I!=h[1]&&Vb(a.H,b,k)}else a.H&&(ib(a.H,a,b,k,d),a.I&&Vb(a.H,b,k));f+=g<<3;b+=g;e-=g}} +function Ab(a,b,c){v("Memory block error ("+a+": "+n(b)+","+n(c)+")");return!1}var Wb;if(rb){var Xb=new ArrayBuffer(2);(new DataView(Xb)).setUint16(0,256,!0);Wb=256===(new Uint16Array(Xb))[0]}else Wb=!1;var Yb=Wb; +function F(a,b,c,d){this.id=Zb+=2;this.b=null;this.F=a;this.yb=b;this.size=c||0;this.type=d||$b;this.N=d==ac;yb(this);this.Na=this.ec=!1;if(c)if(rb)this.D=new ArrayBuffer(c),this.I=new DataView(this.D,0,c),this.u=new Uint8Array(this.D,0,c),this.K=new Uint16Array(this.D,0,c>>1),this.b=new Int32Array(this.D,0,c>>2),bc(this,Yb?cc:dc);else{this.b=Array(c>>2);for(a=0;a>2),b=0;b>8,c)},Z:function(a){return this.b[a>>2]>>>((a&3)<<3)&255},ea:function(a){var b=a>>2;a=(a&3)<<3;var c=this.b[b]>>a;return 24>a?c&65535:c&255|(this.b[b+1]&255)<<8},ia:function(a,b){var c=a>>2,d=(a&3)<<3;this.b[c]=this.b[c]&~(255<>2,d=(a&3)<<3;24>d?this.b[c]=this.b[c]&~(65535<>8);this.Na=!0},O:function(a,b){if(this.H&&null!=this.F){var c=this.H;ic(c,this.F+a,1,c.O)&&c.oa(!0)}return this.wb(a,b)},ba:function(a,b){if(this.H&&null!=this.F){var c=this.H;ic(c,this.F+a,2,c.O)&&c.oa(!0)}return this.Ob(a,b)},ha:function(a,b,c){if(this.H&&null!=this.F){var d=this.H;ic(d,this.F+a,1,d.I)&&d.oa(!0)}this.N?this.w(a,b,c):this.zb(a,b,c)},ra:function(a, +b,c){if(this.H&&null!=this.F){var d=this.H;ic(d,this.F+a,2,d.I)&&d.oa(!0)}this.N?this.w(a,b,c):this.Rb(a,b,c)},M:function(a){return this.u[a]},P:function(a){return this.u[a]},aa:function(a){return this.I.getUint16(a,!0)},da:function(a){return a&1?this.u[a]|this.u[a+1]<<8:this.K[a>>1]},ga:function(a,b){this.u[a]=b;this.Na=!0},Ya:function(a,b){this.u[a]=b;this.Na=!0},ka:function(a,b){this.I.setUint16(a,b,!0);this.Na=!0},va:function(a,b){a&1?(this.u[a]=b,this.u[a+1]=b>>8):this.K[a>>1]=b;this.Na=!0}}; +function yb(a,b,c){a.H=b;a.B=a.j=0;c&&((a.B=c.B)&&hc(a,gc,!1),(a.j=c.j)&&fc(a,gc,!1))}function jc(a,b){b?0===--a.j&&(a.nb=a.N?a.w:a.zb,a.yc=a.N?a.G:a.Rb):0===--a.B&&(a.lb=a.wb,a.tc=a.Ob)}function fc(a,b,c){c&&a.j||(a.nb=!a.N&&b[2]||a.w,a.yc=!a.N&&b[3]||a.G);if(c||void 0===c)a.zb=b[2]||a.w,a.Rb=b[3]||a.G}function hc(a,b,c){c&&a.B||(a.lb=b[0]||a.J,a.tc=b[1]||a.L);if(c||void 0===c)a.wb=b[0]||a.J,a.Ob=b[1]||a.L}function bc(a,b){b||(b=kc);hc(a,b,void 0);fc(a,b,void 0)} +var kc=[],ec=[F.prototype.Z,F.prototype.ea,F.prototype.ia,F.prototype.ya],gc=[F.prototype.O,F.prototype.ba,F.prototype.ha,F.prototype.ra];if(rb)var dc=[F.prototype.M,F.prototype.aa,F.prototype.ga,F.prototype.ka],cc=[F.prototype.P,F.prototype.da,F.prototype.Ya,F.prototype.va]; +function lc(a,b){w.call(this,"CPU",a,lc,1);var c=a.multiplier||1;this.Z=a.cycles||b;this.Ra=c;this.ga=Math.round(this.Z/1E4)/100;this.bb=this.ga*this.Ra;this.C.za=!1;this.C.Lb=!1;this.C.dc=a.autoStart;this.C.fc=!1;this.C.hb=!1;this.tb=this.O=0;this.ub=a.csStart;this.jb=a.csInterval;this.kb=a.csStop;this.D=[];this.Ea=this.cb.bind(this);E(this)}bb(lc);var mc=["power","reset"];m=lc.prototype; +m.Pa=function(a,b,c,d){this.B=a;this.u=b;this.H=d;for(b=0;b=a.O&&(a.O+=a.jb,c=!0);0<=a.kb&&a.kb<=Gc(a)&&(a.jb=a.kb=-1,Bc(a),a.oa(),c=!0);c&&a.g(Gc(a)+" cycles: checksum="+n(a.tb))}} +m.na=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.N[b]=c;a=!0;break;case "run":this.N[b]=c;c.onclick=function(){var a;if(a=d.B)if(a=d.B,a.C.wa)a=!0;else{var b=null,c,g=eb(a.id);for(c=0;ca.J/a.bb?b=1:d=!0;a.Ra=b;b=a.ga*a.Ra;if(a.bb!=b){a.bb=b;b=a.bb.toFixed(2)+"Mhz";var e=a.N.setSpeed;e&&(e.textContent=b);a.g("target speed: "+b)}c&&a.B&&a.B.xb()}Ic(a,a.K);a.K=0;a.G=pa();a.L=0;Jc(a);return d}function Kc(a,b){var c=a.D.length;a.D.push([-1,b]);return c}function Lc(a,b,c){var d=-1;0<=b&&b=this.Z&&Jc(this,!0);this.aa=0;this.da=pa();this.L&&(a=this.da-this.L,a>this.va&&(this.G+=a,this.G>this.da&&(this.G=this.da)));try{do{for(var c=this.C.hb?1:this.ea,d=this.D.length-1;0<=d;d--){var e=this.D[d];0>e[0]||c>e[0]&&(c=e[0])}this.mb(c);var f=this.j-this.b;a= +f;for(var h=this.D.length-1;0<=h;h--){var g=this.D[h];0>g[0]||(g[0]-=a,0>=g[0]&&(g[0]=-1,g[1]()))}this.aa+=f;this.K+=f;Ic(this,0,!0);Fc(this,f);this.P-=f;if(0>=this.P){this.P+=this.ea;15<=++this.ya&&(this.B&&this.B.Ia(),this.ya=0);break}}while(this.C.za)}catch(k){this.oa();Dc(this);this.B&&this.B.stop(pa(),Gc(this));lb(this,!1);qb(this,k.stack||k.message);return}c=setTimeout;d=this.Ea;this.L=pa();e=this.va;this.aa&&(e=Math.round(e*this.aa/this.ea));e=e-(this.L-this.da);if(f=this.L-this.G)this.J=Math.round(this.K/ +(10*f))/100,864E5<=f&&(this.M=0,Hc(this));if(0>e||this.Je&&(this.G-=e),e=0;this.ha+=this.aa;this.L+=e;c(d,e)}else Dc(this),this.B&&this.B.stop(pa(),Gc(this))};m.mb=function(){return 0};m.oa=function(a){mb(this,!0);this.j-=this.b;this.b=0;Ic(this,this.K);this.K=0;if(this.C.za){this.C.za=!1;this.I&&this.I.stop();var b=this.N.run;b&&(b.textContent="Run")}this.C.Eb=a};function Dc(a,b){if(a.B){for(var c=a.B,d=0;d>8&255;a.T=b&255}function Wc(a){return a.U<<8|a.V}function Xc(a,b){a.U=b>>8&255;a.V=b&255}function J(a){return a.W<<8|a.Y} +function Yc(a,b){a.W=b>>8&255;a.Y=b&255}function G(a,b){a.R=b&65535}function Zc(a){return a.ca&256?1:0}function $c(a,b){a.ca=a.ca&255|b}function ad(a){return sb[a.fa&255]?4:0}function bd(a){return(a.fa^a.xa)&16?16:0}function cd(a){return a.ca&255?0:64}function dd(a){return a.fa&128?128:0}function Tc(a){return a.ta&-214|dd(a)|cd(a)|bd(a)|ad(a)|Zc(a)}function Rc(a,b){a.ca=a.fa=a.xa=0;b&1&&(a.ca|=256);b&4||(a.fa|=1);b&16&&(a.xa|=16);b&64||(a.ca|=255);b&128&&(a.fa^=192);a.ta=a.ta&-726|b&512|2} +function ed(a,b){a.xa=a.i^b;return a.fa=(a.ca=a.i+b)&255}function fd(a,b){a.xa=a.i^b;return a.fa=(a.ca=a.i+b+(a.ca&256?1:0))&255}function gd(a,b){a.ca=a.fa=a.xa=a.i&b;(a.i|b)&8&&(a.xa^=16);return a.ca}function hd(a,b){a.xa=b^255;b=a.fa=b+255&255;a.ca=a.ca&-256|b;return b}function id(a,b){a.xa=b;b=a.fa=b+1&255;a.ca=a.ca&-256|b;return b}function jd(a,b){return a.fa=a.ca=a.xa=a.i|b}function K(a,b){b^=255;a.xa=a.i^b;return a.fa=(a.ca=a.i+b+1^256)&255} +function Dd(a,b){b^=255;a.xa=a.i^b;return a.fa=(a.ca=a.i+b+(a.ca&256?0:1)^256)&255}function Ed(a,b){return a.fa=a.ca=a.xa=a.i^b}m.$=function(a){return this.u.$(a)};m.ua=function(a,b){this.u.ua(a,b)};function L(a){var b=a.$(a.R);G(a,a.R+1);return b}function M(a){var b=a.u.Sa(a.R);G(a,a.R+2);return b}function O(a){var b=a.u.Sa(a.ma);a.ma=a.ma+2&65535;return b}function P(a,b){a.ma=a.ma-2&65535;a.u.Ib(a.ma,b)} +function Fd(a){if(a.b&&a.w&255&&a.ta&512){for(var b=0;8>b&&!(a.w&1<b?255:1<>8;$c(this,a&256);this.b-=4},Jd,function(){var a;Yc(this,a=J(this)+Uc(this));$c(this,a>>8&256);this.b-=10},function(){this.i=this.$(Uc(this));this.b-=7},function(){Vc(this,Uc(this)-1);this.b-= +5},function(){this.T=id(this,this.T);this.b-=5},function(){this.T=hd(this,this.T);this.b-=5},function(){this.T=L(this);this.b-=7},function(){var a=this.i<<8&256;this.i=(a|this.i)>>1;$c(this,a);this.b-=4},Jd,function(){Xc(this,M(this));this.b-=10},function(){this.ua(Wc(this),this.i);this.b-=7},function(){Xc(this,Wc(this)+1);this.b-=5},function(){this.U=id(this,this.U);this.b-=5},function(){this.U=hd(this,this.U);this.b-=5},function(){this.U=L(this);this.b-=7},function(){var a=this.i<<1;this.i=a&255| +Zc(this);$c(this,a&256);this.b-=4},Jd,function(){var a;Yc(this,a=J(this)+Wc(this));$c(this,a>>8&256);this.b-=10},function(){this.i=this.$(Wc(this));this.b-=7},function(){Xc(this,Wc(this)-1);this.b-=5},function(){this.V=id(this,this.V);this.b-=5},function(){this.V=hd(this,this.V);this.b-=5},function(){this.V=L(this);this.b-=7},function(){var a=this.i<<8;this.i=(Zc(this)<<8|this.i)>>1;$c(this,a&256);this.b-=4},Jd,function(){Yc(this,M(this));this.b-=10},function(){var a=M(this);this.u.Ib(a,J(this)); +this.b-=16},function(){Yc(this,J(this)+1);this.b-=5},function(){this.W=id(this,this.W);this.b-=5},function(){this.W=hd(this,this.W);this.b-=5},function(){this.W=L(this);this.b-=7},function(){var a=0,b=Zc(this);if(bd(this)||9<(this.i&15))a|=6;if(b||154<=this.i)a|=96,b=1;this.i=ed(this,a);$c(this,b?256:0);this.b-=4},Jd,function(){var a;Yc(this,a=J(this)+J(this));$c(this,a>>8&256);this.b-=10},function(){var a;a=M(this);a=this.u.Sa(a);Yc(this,a);this.b-=16},function(){Yc(this,J(this)-1);this.b-=5},function(){this.Y= +id(this,this.Y);this.b-=5},function(){this.Y=hd(this,this.Y);this.b-=5},function(){this.Y=L(this);this.b-=7},function(){this.i=~this.i&255;this.b-=4},Jd,function(){this.ma=M(this)&65535;this.b-=10},function(){this.ua(M(this),this.i);this.b-=13},function(){this.ma=this.ma+1&65535;this.b-=5},function(){var a=J(this);this.ua(a,id(this,this.$(a)));this.b-=10},function(){var a=J(this);this.ua(a,hd(this,this.$(a)));this.b-=10},function(){this.ua(J(this),L(this));this.b-=10},function(){this.ca|=256;this.b-= +4},Jd,function(){var a;Yc(this,a=J(this)+this.ma);$c(this,a>>8&256);this.b-=10},function(){this.i=this.$(M(this));this.b-=13},function(){this.ma=this.ma-1&65535;this.b-=5},function(){this.i=id(this,this.i);this.b-=5},function(){this.i=hd(this,this.i);this.b-=5},function(){this.i=L(this);this.b-=7},function(){$c(this,Zc(this)?0:256);this.b-=4},function(){this.b-=5},function(){this.S=this.T;this.b-=5},function(){this.S=this.U;this.b-=5},function(){this.S=this.V;this.b-=5},function(){this.S=this.W;this.b-= +5},function(){this.S=this.Y;this.b-=5},function(){this.S=this.$(J(this));this.b-=7},function(){this.S=this.i;this.b-=5},function(){this.T=this.S;this.b-=5},function(){this.b-=5},function(){this.T=this.U;this.b-=5},function(){this.T=this.V;this.b-=5},function(){this.T=this.W;this.b-=5},function(){this.T=this.Y;this.b-=5},function(){this.T=this.$(J(this));this.b-=7},function(){this.T=this.i;this.b-=5},function(){this.U=this.S;this.b-=5},function(){this.U=this.T;this.b-=5},function(){this.b-=5},function(){this.U= +this.V;this.b-=5},function(){this.U=this.W;this.b-=5},function(){this.U=this.Y;this.b-=5},function(){this.U=this.$(J(this));this.b-=7},function(){this.U=this.i;this.b-=5},function(){this.V=this.S;this.b-=5},function(){this.V=this.T;this.b-=5},function(){this.V=this.U;this.b-=5},function(){this.b-=5},function(){this.V=this.W;this.b-=5},function(){this.V=this.Y;this.b-=5},function(){this.V=this.$(J(this));this.b-=7},function(){this.V=this.i;this.b-=5},function(){this.W=this.S;this.b-=5},function(){this.W= +this.T;this.b-=5},function(){this.W=this.U;this.b-=5},function(){this.W=this.V;this.b-=5},function(){this.b-=5},function(){this.W=this.Y;this.b-=5},function(){this.W=this.$(J(this));this.b-=7},function(){this.W=this.i;this.b-=5},function(){this.Y=this.S;this.b-=5},function(){this.Y=this.T;this.b-=5},function(){this.Y=this.U;this.b-=5},function(){this.Y=this.V;this.b-=5},function(){this.Y=this.W;this.b-=5},function(){this.b-=5},function(){this.Y=this.$(J(this));this.b-=7},function(){this.Y=this.i; +this.b-=5},function(){this.ua(J(this),this.S);this.b-=7},function(){this.ua(J(this),this.T);this.b-=7},function(){this.ua(J(this),this.U);this.b-=7},function(){this.ua(J(this),this.V);this.b-=7},function(){this.ua(J(this),this.W);this.b-=7},function(){this.ua(J(this),this.Y);this.b-=7},function(){var a=this.R-1;if(this.ba.length)for(var b=0;b>8;this.b-=10},function(){var a=M(this);dd(this)||G(this,a);this.b-=10},function(){this.ta&=-513;this.b-=4},function(){var a=M(this);dd(this)||(P(this,this.R),G(this,a),this.b-=6);this.b-=11},function(){P(this,Tc(this)&255|this.i<<8);this.b-=11},function(){this.i=jd(this,L(this));this.b-=7},function(){P(this,this.R);G(this,48);this.b-=11},function(){dd(this)&&(G(this, +O(this)),this.b-=6);this.b-=5},function(){this.ma=J(this)&65535;this.b-=5},function(){var a=M(this);dd(this)&&G(this,a);this.b-=10},function(){this.ta|=512;this.b-=4;Fd(this)},function(){var a=M(this);dd(this)&&(P(this,this.R),G(this,a),this.b-=6);this.b-=11},Md,function(){K(this,L(this));this.b-=7},function(){P(this,this.R);G(this,56);this.b-=11}]; +function S(a){w.call(this,"ChipSet",a,S,32768);var b=a.model;b&&!Nd[b]&&Oa("Unrecognized ChipSet model: "+b);this.w=Nd[b]||{};a.sound&&(this.ea=null,window&&(this.ea=window.AudioContext||window.webkitAudioContext),this.ea&&new this.ea);E(this)}bb(S); +var T={Aa:1978.1,cd:{Ba:0,Od:1,Sd:16,Zd:32,he:64,ge:128,ob:14},Xa:{Ba:1,Ec:1,Xc:2,Tc:4,Uc:16,Vc:32,Wc:64,ob:8},dd:{Ba:2,Nd:3,pe:4,Pd:8,ce:16,de:32,ee:64,Qd:128,ob:0},le:{Ba:3},je:{Ba:2,$d:7},ne:{Ba:3,qe:1,me:2,fe:4,Xd:8,Rd:16,Kd:32},ke:{Ba:4},oe:{Ba:5,Td:1,Ud:2,Vd:4,Wd:8,re:16}},U={Aa:100,Ja:{Ba:66,ac:1,Xb:2,Sc:4,be:8,ae:16,Zb:32,Yb:64,Ub:128},Dc:{Ba:66,INIT:0},Va:{Ba:194,Md:0,Tb:16,Yc:32,$b:48,Ic:0,Jc:32},Ab:{Ba:162,ie:0,Lc:0,Hc:0,Kc:0,Gc:0},Ka:{Yd:{Ba:98},Ua:{Ac:0,zc:1,$c:2,ed:4,Fc:5,Zc:6,ad:7}, +Bb:16383}},Nd={SI1978:T,VT100:U};S.prototype.na=function(){return!1};S.prototype.Pa=function(a,b,c,d){this.u=b;this.b=c;this.H=d;this.B=a;this.K=vb(a,"Keyboard");this.Ea=vb(a,"SerialPort");this.video=vb(a,"Video");Hb(b,this,this.w.Gb);Tb(b,this,this.w.Hb);if(d){var e=this;Od(d,16384,function(){for(var a="",b=0;b>8-this.da&255;D(this,a,null,b,"SHIFT.RESULT",c,!0);return c};m.vd=function(a,b,c){D(this,a,b,c,"SHIFT.COUNT",null,!0);this.da=b};m.xd=function(a,b,c){D(this,a,b,c,"SOUND1",null,!0);this.ka=b};m.wd=function(a,b,c){D(this,a,b,c,"SHIFT.DATA",null,!0);this.Z=b<<8|this.Z>>8}; +m.yd=function(a,b,c){D(this,a,b,c,"SOUND2",null,!0);this.ra=b};m.zd=function(a,b,c){D(this,a,b,c,"WATCHDOG",null,!0)};function Pd(a){var b=0,c=0,d=~a.P;for(a=0;10>a;a++)d&1&&(b=9-a),d>>=1;for(a=0;10>a;a++)d&1&&(c=9-a),d>>=1;return 10*b+c} +m.pd=function(a,b){var c=this.J,c=c&~U.Ja.Yb;if((Gc(this.b)&64)<<1&&(c|=U.Ja.Yb,c!=this.J)){var d,e;d=this.O&1;e=this.O>>1&7;switch(e){case U.Ka.Ua.ad:break;case U.Ka.Ua.zc:this.P=this.P<<1|d;break;case U.Ka.Ua.Fc:d=Pd(this);this.D[d]=U.Ka.Bb;jb(this,"doNVRCommand(): erase data at addr "+t(d));break;case U.Ka.Ua.Ac:this.j=this.j<<1|d;break;case U.Ka.Ua.ed:d=Pd(this);e=this.j&U.Ka.Bb;this.D[d]=e;jb(this,"doNVRCommand(): write data "+t(e)+" to addr "+t(d));break;case U.Ka.Ua.Zc:d=Pd(this);e=this.D[d]; +null==e&&(e=U.Ka.Bb);this.j=e;jb(this,"doNVRCommand(): read data "+t(e)+" from addr "+t(d));break;case U.Ka.Ua.$c:this.j<<=1;this.ba=this.j&U.Ka.Bb+1;break;default:jb(this,"doNVRCommand(): unrecognized command "+da(e))}}c&=~U.Ja.Zb;this.ba&&(c|=U.Ja.Zb);c&=~U.Ja.Ub;if(d=this.K){d=this.K;if(e=d.D)e=d.b,e=Gc(d.b)>=d.J+e.Z*e.Ra/1E3*1.2731488;e&&(d.D=!1);d=!d.D}d&&(c|=U.Ja.Ub);c&=~U.Ja.ac;this.Ea&&this.Ea.Ca&1&&(c|=U.Ja.ac);this.J=c;D(this,a,null,b,"FLAGS",c);return c}; +m.Ad=function(a,b,c){D(this,a,b,c,"BRIGHTNESS");this.ga=b};m.Dd=function(a,b,c){D(this,a,b,c,"NVR.LATCH");this.O=b};m.Cd=function(a,b,c){D(this,a,b,c,"DC012");a=b&3;switch(b>>2&3){case 0:this.I=this.I&-4|a;break;case 1:this.I=this.I&-13|a<<2;this.video&&(b=this.video,a=this.I,jb(b,"updateScrollOffset("+a+")"),b.eb!==a&&((b.eb=a)?Mc(b,!0):b.rb=!0));break;case 2:switch(a){case 0:this.aa=~this.aa;break;case 2:case 3:this.ia=3-a}break;case 3:this.ha=a}}; +m.Bd=function(a,b,c){D(this,a,b,c,"DC011");b&U.Va.Yc?(b&=U.Va.$b,this.M!=b&&(this.M=b,this.video&&(a=this.video,b=this.M==U.Va.$b?50:60,jb(a,"updateRate("+b+")"),a.vc=b))):(b&=U.Va.Tb,this.L!=b&&(this.L=b,this.video&&(a=this.L==U.Va.Tb?132:80,b=this.video,jb(b,"updateDimensions("+a+","+(80>>0,h],q=oa(p,k,a.Ta);0>q&&p.splice(-(q+1),0,k)}l&&(g.a=l.replace(/''/g,'"'))}a.G.push({se:b,F:c,rd:d,Qa:e,bc:f})}delete this.Qa}return!0};Sd.prototype.Ha=function(){return!0}; +function Td(a,b,c,d){if(d)a.ja("Unable to load system ROM (error "+d+": "+b+")");else{db(a.Cb,b,c);if("["==c.charAt(0)||"{"==c.charAt(0))try{var e=eval("("+c+")"),f=e.bytes,h=e.data;if(f)a.B=f;else if(h)for(a.B=Array(4*h.length),d=c=0;c>8&255,a.B[d++]=h[c]>>16&255,a.B[d++]=h[c]>>24&255;else a.B=e;a.Qa=e.symbols;if(!a.B.length){v("Empty ROM: "+b);return}if(1==a.B.length){v(a.B[0]);return}}catch(g){a.ja("ROM data error: "+g.message);return}else for(b=c.replace(/\n/gm, +" ").replace(/ +$/,"").split(" "),a.B=Array(b.length),e=0;e>>f.qa;0>>=f.qa;0d?a.j.push({Qb:b,Nb:Date.now(),Db:!1}):(a.j[d].Nb=Date.now(),a.j[d].Db=!1);else if(0<=d){if(!a.j[d].Db){var e=a.j[d].Nb;if(e&&100>Date.now()-e)return a.j[d].Db=!0,ee(a),!0}a.j.splice(d,1)}if(a.I){d=0;switch(b){case "1p":d=T.Xa.Tc;break;case "2p":d=T.Xa.Xc;break;case "coin":d=T.Xa.Ec;break;case "left":d=T.Xa.Vc;break;case "right":d=T.Xa.Wc;break;case "fire":d=T.Xa.Uc}d&&(a=a.I,b=d,a.G&=~b,c&&(a.G|=b))}return!0} +function ee(a){for(var b=0,c=-1;bc||c>e)c=e}else{ce(a,d,!1);b=0;continue}}b++}0<=c&&setTimeout(function(){ee(a)},c)}m.qd=function(a,b){var c=this.G;0<=this.w&&(this.w>3)*a.aa,!zb(a.u,a.Ta,a.P,3)))return!1;a.P?(a.pc=a.D.createImageData(b,c),a.rc=16/a.$a|0,ke(a,a.P>>1)):ke(a,(a.ba+1)*a.va);a.L=document.createElement("canvas");a.L.width=b;a.L.height=c;a.qb=a.L.getContext("2d");a.ea={};a.ka=1<=a.jc?8:16,f=8>(7>4)*c)}return k}fe.prototype.Da=function(){return!0};fe.prototype.na=function(a,b,c){var d=this;if("led"==a||"rled"==a)return this.Mb[b]=c,!0;switch(b){case "fullScreen":return this.N[b]=c,this.j&&this.j.fb?c.onclick=function(){d.fb()}:c.parentNode.removeChild(c),!0}return!1}; +fe.prototype.fb=function(){var a=!1;if(this.j){if(this.j.fb){a="100%";if(screen&&screen.width&&screen.height){var b=screen.width/screen.height,c=this.Z/this.O;b>c&&(a=Math.round(c/b*100)+"%")}this.oc?(this.M.style.width=a,this.M.style.width=a,this.M.style.display="block",this.M.style.margin="auto"):(this.j.style.width=a,this.j.style.height="auto");this.j.style.backgroundColor="black";this.j.fb();a=!0}this.ia&&this.ia.focus()}return a}; +function ie(a,b){!b&&a.j&&(a.oc?a.M.style.width=a.M.style.height="":a.j.style.width=a.j.style.height="");jb(a,"notifyFullScreen("+b+")")}function ke(a,b){a.qc=b;a.ha=!1;if(void 0===a.G||a.G.length!=a.qc)a.G=Array(a.qc)}function me(a,b,c,d,e){d=a.w?(b.height-c-1)*b.width+d:c+d*b.width;e&&1==a.ra&&(208<=c&&236>c?e=a.ka+0:28<=c&&72>c&&(e=a.ka+1));a=a.ga[e];d*=a.length;b.data[d]=a[0];b.data[d+1]=a[1];b.data[d+2]=a[2];b.data[d+3]=a[3]} +function Mc(a,b){var c=!0;if(!b){a.ab&&(120==a.ab?a.sc&1?(Gd(a.b,2),c=!1):Gd(a.b,1):Gd(a.b,4));if(c&&a.ha&&a.P){for(var d=a.u,e=a.P,f=!0,h=a.Ta>>>d.qa;0>=1);;){var u=Cb(a.u,p++);if(127==(u&127)){var r=Cb(a.u,p++),d=r&96,c=(r&15)<<8|Cb(a.u,p),c=c+ +(r&16?8192:16384);break}if(l>4)*u.la,A=void 0,Q=void 0,aa=void 0,Y=void 0,ua=u.pa,Eb=u.la;B?(A=x*r.pa,Q=e*r.la,aa=r.pa,Y=r.la):(A=x*r.kc,Q=e*r.lc,aa=r.kc,Y=r.lc);u.pa>r.pa&&(A*=2,aa*=2);u.la>r.la&&(0==q&&(y+=r.la),Eb=r.la);B?B.drawImage(u.canvas,X,y,ua,Eb,A,Q,aa,Y): +(A+=0,Q+=0,r.D.drawImage(u.canvas,X,y,ua,Eb,A,Q,aa,Y))}g++}h++}e++}}a.ha=!0;!b&&a.rb&&1==g&&(a.G[k]=-1,g=0);a.rb=!1;(g||b)&&a.qb&&a.D.drawImage(a.L,0,a.eb,a.J,a.aa-a.la,0,0,a.Fd,a.Gd)}else{f=a.Ta;h=f+a.P;l=k=g=0;c=a.J;q=0;d=a.aa;p=e=0;x=a.$a;r=(1<>8|(B&255)<<8);k>u&r,me(a,a.pc,k++,l,y),u+=x;k>q&&(q=k);l=e&&(e=l+1)}f+=2;g++;if(k>=a.J&&(k=0,l++,l>a.aa))break}a.ha= +!0;cMissing <canvas> support. Please try a newer web browser.";break}e.setAttribute("class","pcjs-canvas");e.setAttribute("width",d.screenWidth);e.setAttribute("height",d.screenHeight);e.style.backgroundColor=d.screenColor;e.style.height="auto";0<=ta().indexOf("MSIE")&&(c.onresize=function(a,b,c,d){return function(){b.style.height= +(a.clientWidth*d/c|0)+"px"}}(c,e,d.screenWidth,d.screenHeight),c.onresize());var f=+(d.aspect||Va.aspect);f&&.3<=f&&3.33>=f&&(La("onresize",function(a,b,c){return function(){b.style.height=(a.clientWidth/c|0)+"px"}}(c,e,f)),window.onresize());c.appendChild(e);f=document.createElement("textarea");Aa("iOS")&&(f.setAttribute("autocapitalize","off"),f.setAttribute("autocorrect","off"));c.appendChild(f);var h=e.getContext("2d"),d=new fe(d,e,h,f,c);hb(d,c)}}); +function ne(a){this.da=+a.adapter;switch(this.da){case 0:this.ea=0;this.ha=2;break;default:v("Unrecognized serial adapter #"+this.da);return}this.j=this.w=null;this.ga=a.tabSize;this.ba=a.charBOL;this.D=0;this.Z=!1;w.call(this,"SerialPort",a,ne,8388608);var b=a.binding;if("console"==b)this.w="";else{var c;a=oe;b&&(void 0===c&&(c="Panel"),(c=gb(c,this.id))&&(b=c.N[b])&&this.na(null,a,b))}this.G="";this.K=this.L=null;this.exports={connect:this.ic,receiveData:this.Pb}}bb(ne); +var pe=[50,75,110,134.5,150,200,300,600,1200,1800,2E3,2400,3600,4800,9600,19200],qe=[!1,0,0,133,142,39,238],oe="buffer";m=ne.prototype; +m.na=function(a,b,c,d){var e=this;switch(b){case oe:return this.N[b]=this.j=c,c.onkeydown=function(a){a=a||window.event;var b=a.keyCode;if(8===b||a.ctrlKey&&65<=b&&90>=b)a.preventDefault&&a.preventDefault(),64");if(2==b.length){var c=ma(b[0]);if(c!=this.Ya)return;b=ma(b[1]);if(this.K=fb(b)){var d=this.K.exports;if(d){var e=d.connect;e&&e.call(this.K);if(this.L=d.receiveData){this.status(this.Cb+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}};m.Da=function(a,b){if(!b)if(this.ic(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0}; +m.Ha=function(a){return a?this.save():!0};m.reset=function(){ue(this)};m.save=function(){var a=new H(this),b=0,c=[];c[b++]=this.Ma;c[b++]=this.P;c[b++]=this.aa;c[b++]=this.Ca;c[b++]=this.J;c[b++]=this.O;c[b]=this.M;I(a,0,c);return a.data()};m.restore=function(a){return ue(this,a[0])};function ue(a,b){var c=0;void 0===b&&(b=qe);a.Ma=b[c++];a.P=b[c++];a.aa=b[c++];a.Ca=b[c++];a.J=b[c++];a.O=b[c++];a.M=b[c];return!0} +function ve(a,b){var c=a.M&b;b&15||(c>>=4);var c=pe[c],d=((a.J&12)>>2)+6;a.J&16&&d++;d+=((a.J&192)>>6)+1>>1;return 1E3/Math.round(c/d)}function re(a,b){jb(a,"receiveByte("+da(b)+"), status="+da(a.Ca));return a.Z||a.Ca&2?!1:(a.P=b,a.Ca|=2,Gd(a.b,a.ha),!0)}m.Pb=function(a){null!=a&&(this.G="number"!=typeof a?a:this.G+String.fromCharCode(a));this.G&&(re(this,this.G.charCodeAt(0))&&(this.G=this.G.substr(1)),this.G&&this.b&&Lc(this.b,this.ia,ve(this,15)));return!0}; +m.kd=function(a,b){var c=this.P;D(this,a,null,b,"DATA",c);this.Ca&=-3;return c};m.jd=function(a,b){var c=this.Ca;D(this,a,null,b,"STATUS",c);return c}; +m.ud=function(a,b,c){D(this,a,b,c,"DATA");this.aa=b;this.Ca&=-6;jb(this,"transmitByte("+da(b)+")");if(19==b)this.Z=!0;else if(17==b)this.Z=!1;else if(this.L&&this.L.call(this.K,b),this.j)8==b?(this.j.value=this.j.value.slice(0,-1),0":String.fromCharCode(b),c=a.length,9==b?(b=this.ga||8,c=b-this.D%b,this.ga&&(a=la("",c))):13==b&&(this.D=c=0,a="\n"),this.ba&&!this.D&&c&&(a=String.fromCharCode(this.ba)+a),this.j.value+=a,this.j.scrollTop=this.j.scrollHeight,this.D+= +c);else if(null!=this.w){if(10==b||1024<=this.w.length)this.g(this.w),this.w="";10!=b&&(this.w+=String.fromCharCode(b))}this.b&&Lc(this.b,this.ka,ve(this,240))};m.td=function(a,b,c){D(this,a,b,c,"CONTROL");this.Ma?(this.O=b,this.O&64&&(this.Ma=!1)):(this.J=b,this.Ma=!0)};m.sd=function(a,b,c){D(this,a,b,c,"BAUDRATES");this.M=b};var se={0:ne.prototype.kd,1:ne.prototype.jd},te={0:ne.prototype.ud,1:ne.prototype.td,2:ne.prototype.sd}; +Ma(function(){for(var a=C(document,"pc8080","serial"),b=0;b>>d.u.qa;k=1}d.g("blockid physical blockaddr used size type");d.g("-------- --------- ---------- ------ ------ ----");for(var c=-1,l=0;k--;){var p=b[g];p.type==c?l++||d.g("..."):(c=p.type,l=Bb[c],p&&d.g(n(p.id)+" %"+n(g<>>e.qa;f!=e.u?e.X[h].Rb(f,b&65535,d):(e.X[h++].zb(f,b&255,d),e.X[h&e.K].zb(0,b>>8&255,d+1));c&&Ie(a,c);Dc(this.b,!0)}};function W(a){return{F:a,Oa:!1}}function Je(a){return[a.F,a.Oa]}function Ke(a){return{F:a[0],Oa:a[1]}} +function He(a,b,c){var d;c=(c?a.M:a.$a).F;if(void 0!==b){d=b=Le(a,b);var e;if(d.match(/^[a-z_][a-z0-9_]*$/i))for(d=d.toUpperCase(),c=0;cc&&(c=ra(Ee,a.substr(b,1))));return c}function Re(a,b){var c=0,d=Se(a,b);if(void 0!==d)switch(b){case 7:case 0:case 1:case 2:case 3:case 4:case 5:case 6:c=2;break;case 8:case 9:case 10:case 11:case 12:case 13:case 14:c=4}return c?n(d,c):"??"} +function Se(a,b){var c;if(0<=b){var d=a.b;switch(b){case 7:c=d.i;break;case 0:c=d.S;break;case 1:c=d.T;break;case 8:c=Uc(d);break;case 2:c=d.U;break;case 3:c=d.V;break;case 9:c=Wc(d);break;case 4:c=d.W;break;case 5:c=d.Y;break;case 10:c=J(d);break;case 6:c=d.$(J(d));break;case 11:c=d.ma;break;case 12:c=d.R;break;case 13:c=Tc(d);break;case 14:c=Tc(d)&255|d.i<<8}}return c} +function Te(a,b){b=Le(a,b);for(var c=0,d,e;0<=(c=b.indexOf("@",c));)e=Qe(b,c+1),0<=e&&(b=b.substr(0,c)+Re(a,e)+b.substr(c+1+Ee[e].length)),c++;for(c=0;0<=(c=b.indexOf("#",c));)e=b.substr(c+1,2),d=ca(e,16),null!=d&&32<=d&&128>d?(d=e+" '"+String.fromCharCode(d)+"'",b=b.replace("#"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("$",c));)e=b.substr(c+1,9),(d=He(a,e))?(d=e+' "'+Pe(a,d)+'"',b=b.replace("$"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("^",c));)e=b.substr(c+1,9),(d=He(a,e))?(Ie(d),d=e+' "'+ +Pe(a,d,11)+'"',b=b.replace("^"+e,d),c+=d.length):c++;return b}m.message=function(a,b){b&&(a+=" at "+Z(W(this.b.R).F));if(this.sa&1073741824)this.ka.push(a);else if(!this.ia||a!=this.ia)if(this.ia=a,this.sa&-2147483648&&(this.oa(),a+=" (cpu halted)"),this.g(a),this.b){var c=this.b;c.P=0;c.j-=c.b;c.b=0;Dc(c)}}; +function ib(a,b,c,d,e,f,h,g){g|=256;null!=f&&(a.sa&g)!=g||a.message(b.Ya+"."+(null!=d?"outPort":"inPort")+"("+t(c)+","+(f?f:"unknown")+(null!=d?","+da(d):"")+")"+(null!=h?": "+da(h):"")+(null!=e?" at "+Z(e):""))} +function ze(a){var b;if(Hd(a)){if(!a.L||!a.L.length){a.L=Array(1E3);for(b=0;b>>d.qa],!1)}a.O=["br"];if(void 0!==a.I)for(b=1;b>>d.qa],!0);a.I=["bw"];a.ab=0}m.Za=function(a,b,c){var d=!0;c||wf(this,a,b,!1,!0);if(a!=this.j){var e=Ge(b);if(-1===e)this.g("invalid address: "+Z(b.F)),d=!1;else{var f=this.u;f.X[e>>>f.qa].Za(e&f.u,a==this.I)}}d&&(a.push(b),c?b.Oa=!0:(xf(this,a,a.length-1,"set"),ze(this)));return d}; +function wf(a,b,c,d,e){var f=!1;c=Ge(c);for(var h=1;h>>d.qa],b==a.I));g.Oa||ze(a);break}}return f}function yf(a,b){for(var c=1;c>24,4);break;case 3:y=n(u.Sa(B,2),4);break;default:u="imm("+t(r)+")";break a}8086==u.style&&r&64?y="["+y+"]":r&16||(y=(u.style==xe?"$":"0x")+y);u=y}else r& +16?(u=(q&3840)>>8,r=Ee[u],8086==a.style&&q&64&&(6==u&&(r="HL"),r="["+r+"]"),u=r):r&128&&(u=(f>>3&7).toString());if(!u||!u.length){g="INVALID";break}0=":6,">":6,"<=":6,"<":6,">>>":7,">>":7,"<<":7,"-":8,"+":8,"%":9,"/":9,"*":9}; +function Ff(a,b,c){for(c=c||-1;c--&&b.length;){var d=b.pop();if(2>a.length)return!1;var e=a.pop(),f=a.pop();switch(d){case "*":d=f*e;break;case "/":if(!e)return!1;d=f/e;break;case "%":if(!e)return!1;d=f%e;break;case "+":d=f+e;break;case "-":d=f-e;break;case "<<":d=f<>":d=f>>e;break;case ">>>":d=f>>>e;break;case "<":d=f":d=f>e?1:0;break;case ">=":d=f>=e?1:0;break;case "==":d=f==e?1:0;break;case "!=":d=f!=e?1:0;break;case "&":d=f&e;break; +case "^":d=f^e;break;case "|":d=f|e;break;case "&&":d=f&&e?1:0;break;case "||":d=f||e?1:0;break;default:return!1}a.push(d|0)}return!0} +function Me(a,b,c){var d;if(b){b=Le(a,b);for(var e=0,f=!1,h=b,g=[],k=[],l=b.split(/(\|\||&&|\||^|&|!=|==|>=|>>>|>>|>|<=|<<|<|-|\+|%|\/|\*)/);e>=1;h=p+"b"+h;d>>=8}d="0x"+n(c)+" "+c+". ("+h+")"}a.g((null!=b?b+": ":"")+d);return e}function If(a,b){if(b)return Hf(a,b,a.da[b]);var c=0;for(b in a.da)Hf(a,b,a.da[b]),c++;return 0b[0]?1:a[0]>>0;for(b=0;b>>0,g=f.rd;if(e>=h&&e>8&255;case "C":d.T=g&255;break;case "D":d.U= +g&255;break;case "DE":d.U=g>>8&255;case "E":d.V=g&255;break;case "H":d.W=g&255;break;case "HL":d.W=g>>8&255;case "L":d.Y=g&255;break;case "SP":d.ma=g&65535;break;case "PC":G(d,g);a.M=W(d.R);break;case "PS":Rc(d,g);break;case "PSW":Rc(d,g&255|d.ta&-256);d.i=g>>8;break;case "CF":d.ca=g?d.ca|256:d.ca&255;break;case "PF":g?ad(d)||(d.fa^=1):ad(d)&&(d.fa^=1);break;case "AF":d.xa=g?~d.fa&16|d.xa&-17:d.fa&16|d.xa&-17;break;case "ZF":d.ca=g?d.ca&-256:d.ca|255;break;case "SF":g?dd(d)||(d.fa^=192):dd(d)&&(d.fa^= +192);break;case "IF":d.ta=g?d.ta|512:d.ta&-513;break;default:a.g("unknown register: "+e);return}if(!h){a.g("invalid value: "+f);return}Dc(d);a.g("updated registers:")}a.g(Df(a));c&&(a.M=W(d.R),uf(a,Z(a.M.F)))}}function Pf(a,b){b=ma(b);var c=b.match(/^(['"])(.*?)\1$/);c?a.g(Te(a,c[2])):Me(a,b,!0)}function Qf(a,b,c){var d="t"!=b;c=Gf(a,c,null,!0)||1;var e=1==c?0:1;"tc"==b&&(e=c,c=1);Ba(c,function(){return lb(a,!0)&&a.mb(e,d,!1)},function(){Dc(a.b);lb(a,!1)})} +function uf(a,b,c,d){if(b=He(a,b,!0)){void 0===d&&(d=1);var e=256;if(void 0!==c){d=He(a,c,!0);if(!d||d.Fg[0].indexOf("+"))){var l=g[0]+":";g[2]&&(l+=" "+g[2]);a.g(l)}g[3]&&(h=g[3],f=null);f=Af(a,b,h,f);a.g(f);a.M=b;e-=b.F-k;c++}}} +function Oe(a,b,c,d){if(c)if(b){0>a.D&&a.w.length&&(a.D=0);if(0>a.D||b!=a.w[a.D])a.w.splice(0,0,b),a.D=0;a.D--}else a.ba?b="end":b=a.w[a.D+1];a=[];if(b){b=b.toLowerCase().replace(/""/g,"'");c=0;var e=null;d=d||";";for(var f=0;f<=b.length;f++){var h=b.charAt(f);if('"'==h||"'"==h)e?h==e&&(e=null):e=h;else if(h==d&&!e||!h)a.push(ma(b.substring(c,f))),c=f+1}}return a} +function zf(a,b,c){var d=!0;try{b.length&&"end"!=b?c||a.g(">> "+b):(a.ba&&(a.g("ended assemble at "+Z(a.aa.F)),a.M=a.aa,a.ba=!1),b="");var e=b.charAt(0);if('"'==e||"'"==e)return!0;a.ia=null;if(pb(a)&&0l||"z"Ga.length&&(a.g("note: only "+Ga.length+" available"),ia=Ga.length);ba-=ia;0>ba&&(null==Ga[Ga.length-1].F?(ia=ba+ia,ba=0):ba+=Ga.length);var md=[];"call"== +af&&(ob=1E5,md=["CALL"]);for(void 0!==$e&&a.g(ia+" instructions earlier:");0=Ga.length&&(ba=0);a.eb=ia;cf++;ob--}}cf||(a.g("no "+bf+"history available"),a.eb=void 0)}else{var pc=He(a,Y);if(pc){var qc=0;ua&&("l"==ua.charAt(0)&&(ua=ua.substr(1)||Eb),qc=Gf(a,ua)>>>0,65536>4||1;kg--&&0uc?String.fromCharCode(uc):".";sc--}Xa&&(Xa+="\n");Xa+=Y+" "+Lb+(0==Kb?" "+od:"")}Xa&&a.g(Xa);a.$a=pc}}}}break;case "e":if("else"==f[0])break;var vc=1,ff=255,gf=a.$,hf=a.ua;"ew"==f[0]&&(vc=2,ff=65535,gf=a.Sa,hf=a.Ib);var jf=vc<<1,kf=f[1];if(null==kf)a.g("edit memory commands:"), +a.g("\teb [a] [...] edit bytes at address a"),a.g("\tew [a] [...] edit words at address a");else{var wc=He(a,kf);if(wc)for(var xc=2;xcvd;){for(var Ya=null,qg=256;65536>Ob.F>>>0;){mf.F= +a.Sa(Ob,2);if(null==Ob.F||!qg--)break;for(var rg=a,zc=mf,nf=null,Pb=zc.F,of=Pb,wd=1;6>=wd&&Pb;wd++){if(2\nLicense: GPL version 3 or later ");for(b=0;bUf){if(Wf(d,this.L)){this.I=new H(this,"1.24.2","failsafe");Wf(this.I)&&(bg(this,d),a=2,cg(this.I));I(this.I,"timestamp",qa());dg(this.I);var e=this.B&&!this.K;if(1==a||va("Click OK to restore the previous PC8080 machine state, or CANCEL to reset the machine.")){if(c=$f(d)){var f=ag(d,"code"),h=ag(d,"data");f&&("ok"==f?Wf(d,h):("error"==f&& +"no machine state"!=h?(this.ja("Error: "+h),"unable to verify user"==h&&(za("user",""),this.j=null)):this.g(f+": "+h),cg(d),Wf(d)?(c=$f(d),e=!0):c=!1))}e&&Zf(this,c?d:null)}else 2==a&&d.clear()}else Zf(this);delete this.L;delete this.M}e=eb(this.id);for(f=0;fa[1];a=a[2];this.ga=!0;this.C.wa=!0;var d=this.N.power;d&&(d.textContent="Shutdown");this.b&&(eg(this,this.b,b,c,a),Ec(this.b));this.Z&&(bg(this,b),b.clear());!c&&this.I&&(this.I.clear(),delete this.I);this.w=0}; +function bg(a,b){if(va("There may be a problem with your PC8080 machine.\n\nTo help us diagnose it, click OK to send this PC8080 machine state to http://www.pcjs.org.")){var c=a.j||"",d=b.toString(),e={app:"PC8080",ver:"1.24.2"};e.url=a.ea;e.user=c;e.type="bug";e.data=d;sa("http://www.pcjs.org/api/v1/report",e,!0)}} +function Rf(a,b,c){var d,e="none";if(a.w)return null;a.w--;var f=new H(a,"1.24.2"),h=new H(a,"1.24.2","validate"),g=qa();I(h,"timestamp",g);I(f,"timestamp",g);I(f,"version","1.24.2");I(f,"url",window?window.location.href:null);I(f,"browser",ta());a.b&&a.b.Ha&&(c&&a.b.oa(),d=a.b.Ha(b,c),"object"===typeof d&&I(f,a.b.id,d),c&&(a.b.C.wa=!1,!1===d&&(e=null)));for(var g=eb(a.id),k=0;kg.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(g=window.location.pathname+g);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(g?' url="'+g+'"':""))}e||(a=a.replace(/().*?(<\/xsl:variable>)/,"$1pc8080$2")); +g=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(g=new window.ActiveXObject("Microsoft.XMLDOM"),g.async=!1,g.loadXML(a)):g=(new window.DOMParser).parseFromString(a,"text/xml")}catch(q){g=null,a=q.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");sa(e,null,!0,function(f,h,g){if(g||!h)c(a,"unable to resolve XML reference: "+d[0]+" ("+g+")");else{if(f=d[3])if(g=h.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var k=g[0],l,p=/( [a-z]+=)(['"])(.*?)\2/g;l=p.exec(f);)k=0>k.indexOf(l[1])?k.replace(">",l[0]+">"):k.replace(new RegExp(l[1]+"(['\"])(.*?)\\1"),l[0]);g[0]!=k&&(h=h.replace(g[0],k))}else{c(a,"missing <"+d[1]+"> in "+e);return}h=h.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],h);yg(a,b,c)}})}else c(a,null)} +function zg(a,b,c,d){function e(a){if(void 0===g){var b=h&&C(h,"machine-warning");g=b&&b[0]||h}g&&(g.innerHTML=ka(a))}function f(a){e("Error: "+a);k&&(--ig||Pa(!0));k=!1}var h,g,k=!0;ig++;cb[a]={};try{if(h=document.getElementById(a)){var l;if("object"==typeof resources&&(l=resources.css)){var p=document.head||document.getElementsByTagName("head")[0],q=document.createElement("style");q.type="text/css";q.styleSheet?q.styleSheet.cssText=l:q.appendChild(document.createTextNode(l));p.appendChild(q)}c|| +(c="/versions/pc8080/1.24.2/components.xsl");l=function(d,g){g?wg(c,null,null,!1,e,function(d,k){if(k)if(db(a,c,d),e("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var l=g.transformNode(k);l?(h.outerHTML=l,--ig||Pa(!0)):f("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(l=new XSLTProcessor,l.importStylesheet(k),(l=l.transformToFragment(g,document))?h.parentNode?(h.parentNode.replaceChild(l,h),--ig||Pa(!0)):f("invalid machine element: "+ +a):f("transformToFragment failed")):f("unable to transform XML: unsupported browser");else f(d)}):f(d)};"<"!=b.charAt(0)?wg(b,a,d,!0,e,l):xg(b,null,a,d,!1,e,l)}else f("missing machine element: "+a)}catch(x){f(x.message)}return k}window.embedPC8080=function(a,b,c,d){Pa(!1);return zg(a,b,c,d)};window.enableEvents=Pa;window.sendEvent=Qa;})(); diff --git a/versions/pc8080/1.24.2/pc8080.js b/versions/pc8080/1.24.2/pc8080.js new file mode 100644 index 000000000..ad7408a96 --- /dev/null +++ b/versions/pc8080/1.24.2/pc8080.js @@ -0,0 +1,162 @@ +(function(){var k;function aa(a){var b=16,c;if(a){b||(b=16);if("$"==a.charAt(0))b=16,a=a.substr(1);else if("0x"==a.substr(0,2))b=16,a=a.substr(2);else{var d=a.charAt(a.length-1).toLowerCase();"h"==d?(b=16,d=null):"."==d&&(b=10,d=null);null==d&&(a=a.substr(0,a.length-1))}var e,d=a,f=b;(f&&10!=f?16==f?null!==d.match(/^[0-9a-f]+$/i):2==f&&null!==d.match(/^[01]+$/i):null!==d.match(/^[0-9]+$/))&&!isNaN(e=parseInt(a,b))&&(c=e|0)}return c} +function m(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function ba(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("&");0":">",'"':""","'":"'"};function ga(a){return a.replace(/[&<>"']/g,function(a){return fa[a]})}function ha(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")}var ia={0:"NUL",1:"SOH",2:"STX",3:"ETX",4:"EOT",5:"ENQ",6:"ACK",7:"BEL",8:"BS",9:"TAB",11:"VT",12:"FF",13:"CR",14:"SO",15:"SI",16:"DLE",17:"XON",18:"DC2",19:"XOFF",20:"DC4",21:"NAK",22:"SYN",23:"ETB",24:"CAN",25:"EM",26:"SUB",27:"ESC",28:"FS",29:"GS",30:"RS",31:"US"},ja=Date.now||function(){return+new Date}; +function la(){function a(a){return(10>a?"0":"")+a}var b=new Date;return b.getFullYear()+"-"+a(b.getMonth()+1)+"-"+a(b.getDate())+" "+a(b.getHours())+":"+a(b.getMinutes())+":"+a(b.getSeconds())} +function ma(a,b,c,d){var e=0,f=null,h=null;if("object"==typeof resources&&(f=resources[a]))return d&&d(a,f,e),[f,e];if(c&&"function"==typeof resources)return resources(a,function(b,c){d&&d(a,b,c)}),h;var g=window.XMLHttpRequest?new window.XMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");c&&(g.onreadystatechange=function(){4===g.readyState&&(f=g.responseText,200==g.status||!g.status&&f.length&&"file:"==(window?window.location.protocol:"file:")||(e=g.status||-1),d&&d(a,f,e))});if(b&&"object"== +typeof b){var l="",n;for(n in b)b.hasOwnProperty(n)&&(l&&(l+="&"),l+=n+"="+encodeURIComponent(b[n]));l=l.replace(/%20/g,"+");g.open("POST",a,!!c);g.setRequestHeader("Content-type","application/x-www-form-urlencoded");g.send(l)}else g.open("GET",a,!!c),"bytes"==b&&g.overrideMimeType("text/plain; charset=x-user-defined"),g.send();c||(f=g.responseText,200!=g.status&&(e=g.status||-1),d&&d(a,f,e),h=[f,e]);return h}function ea(){return"http://"+(window?window.location.host:"www.pcjs.org")} +function p(a){window&&window.alert(a)}function na(a){var b=!1;window&&(b=window.confirm(a));return b}var oa=null;function pa(){if(null==oa){var a=!1;if(window)try{window.localStorage.setItem("PCjs.localStorage","PCjs.localStorage"),a="PCjs.localStorage"==window.localStorage.getItem("PCjs.localStorage"),window.localStorage.removeItem("PCjs.localStorage")}catch(b){a=!1}oa=a}return oa}function qa(a){var b;if(window)try{b=window.localStorage.getItem(a)}catch(c){}return b} +function ra(a,b){try{return window.localStorage.setItem(a,b),!0}catch(c){}return!1}function sa(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}var ta={init:[],show:[],exit:[]},ua=!1,va=!1,wa=!0;function xa(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function ya(a){ta.init.push(a)} +function za(a){if(wa)try{for(var b=0;bb?this.Ta=this.id:(this.Ua=this.id.substr(0,b),this.Ta=this.id.substr(b+1));this[a]=c;this.l={ha:!1,Ma:!1,gb:!1,Y:!1,Aa:!1};this.Za=null;this.l.Aa=!1;this.A={};this.O=null;r.push(this)}var Ea=void 0,Fa={}; +if(window){Ea||(Ea=window.location.search.substr(1));for(var Ga,Ha=/\+/g,Ia=/([^&=]+)=?([^&]*)/g;Ga=Ia.exec(Ea);)Fa[decodeURIComponent(Ga[1].replace(Ha," "))]=decodeURIComponent(Ga[2].replace(Ha," "))}function Ja(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b} +function w(a,b){b||(b=q);a.prototype=Ja(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var Ka=window.PCjs.Machines||(window.PCjs.Machines={}),r=window.PCjs.Components||(window.PCjs.Components=[])}else Ka={},r=[];function La(a,b,c){Ka[a]&&b&&(Ka[a][b]=c)}function Aa(a,b,c){b||p((c?c+": ":"")+a)} +function Ma(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b=this.i?10:20>=this.i?12:24>=this.i?14:15;this.c=1<>2;this.f=this.c-1;this.m=this.u/this.c|0;this.s=this.m-1;this.v=[];this.o=[];this.B=[];this.C=[];a=new D;Ya(a,this.O);this.b=Array(this.m);for(b=0;b>>a.j;0f&&(n=f);if(g&&g.size){if(g.type==d){if(e+f<=g.Ia)return g.fb+=g.Ia-e,g.Ia=e,!0;if(e>=g.Ia+g.fb){n=g.size-(e-l);n>f&&(n=f);g.fb=e-g.Ia+n;e=l+a.c;f-=n;h++;continue}}return $a(1,e,f)}e=new D(e,n,a.c,d);Ya(e,a.O,g);a.b[h++]=e;e=l+a.c;f-=n}return 0>=f?(a.status(Math.floor(c/1024)+"Kb "+ab[d]+" at "+("0x"+m(b,4))),!0):$a(2,b,c)} +Xa.prototype.K=function(a){return this.b[(a&this.g)>>>this.j].Qa(a&this.f,a)};function bb(a,b){return a.b[(b&a.g)>>>a.j].eb(b&a.f,b)}function cb(a,b){var c=b&a.f,d=(b&a.g)>>>a.j;return c!=a.f?a.b[d].Oc(c,b):a.b[d++].Qa(c,b)|a.b[d&a.s].Qa(0,b+1)<<8}Xa.prototype.$=function(a,b){this.b[(a&this.g)>>>this.j].Ra(a&this.f,b&255,a)};function eb(a,b,c){a.b[(b&a.g)>>>a.j].Gb(b&a.f,c&255,b)} +function fb(a,b,c){var d=b&a.f,e=(b&a.g)>>>a.j;d!=a.f?a.b[e].Pc(d,c&65535,b):(a.b[e++].Ra(d,c&255,b),a.b[e&a.s].Ra(0,c>>8&255,b+1))}function gb(a,b,c,d){void 0===d&&(d=0);if(c)for(var e in c){var f=a,h=+e+d,g=c[e].bind(b);if(void 0!==g)for(var l=+e+d;l<=h;l++)void 0!==f.v[l]?p("Input port 0x"+m(l,4)+" already registered"):f.v[l]=[g,!1]}} +function hb(a,b,c,d){void 0===d&&(d=0);if(c)for(var e in c){var f=a,h=+e+d,g=c[e].bind(b);if(void 0!==g)for(var l=+e+d;l<=h;l++)void 0!==f.o[l]?p("Output port 0x"+m(l,4)+" already registered"):f.o[l]=[g,!1]}}function $a(a,b,c){p("Memory block error ("+a+": "+m(b)+","+m(c)+")");return!1}var ib;if(Sa){var jb=new ArrayBuffer(2);(new DataView(jb)).setUint16(0,256,!0);ib=256===(new Uint16Array(jb))[0]}else ib=!1;var kb=ib; +function D(a,b,c,d){this.id=lb+=2;this.a=null;this.Ia=a;this.fb=b;this.size=c||0;this.type=d||mb;this.c=d==nb;Ya(this);this.na=this.wb=!1;if(c)if(Sa)this.j=new ArrayBuffer(c),this.A=new DataView(this.j,0,c),this.b=new Uint8Array(this.j,0,c),this.i=new Uint16Array(this.j,0,c>>1),this.a=new Int32Array(this.j,0,c>>2),ob(this,kb?pb:qb);else{this.a=Array(c>>2);for(a=0;a>2),b=0;b>8,c)},C:function(a){return this.a[a>> +2]>>>((a&3)<<3)&255},I:function(a){var b=a>>2;a=(a&3)<<3;var c=this.a[b]>>a;return 24>a?c&65535:c&255|(this.a[b+1]&255)<<8},R:function(a,b){var c=a>>2,d=(a&3)<<3;this.a[c]=this.a[c]&~(255<>2,d=(a&3)<<3;24>d?this.a[c]=this.a[c]&~(65535<>8);this.na=!0},w:function(a,b){return this.eb(a,b)},H:function(a,b){return this.Eb(a,b)},N:function(a,b,c){this.c||this.Gb(a,b,c)},W:function(a, +b,c){this.c||this.X(a,b,c)},u:function(a){return this.b[a]},B:function(a){return this.b[a]},G:function(a){return this.A.getUint16(a,!0)},L:function(a){return a&1?this.b[a]|this.b[a+1]<<8:this.i[a>>1]},J:function(a,b){this.b[a]=b;this.na=!0},P:function(a,b){this.b[a]=b;this.na=!0},U:function(a,b){this.A.setUint16(a,b,!0);this.na=!0},Z:function(a,b){a&1?(this.b[a]=b,this.b[a+1]=b>>8):this.i[a>>1]=b;this.na=!0}};function Ya(a,b,c){a.O=b;a.f=a.g=0;c&&((a.f=c.f)&&sb(a,tb,!1),(a.g=c.g)&&ub(a,tb,!1))} +function ub(a,b,c){c&&a.g||(a.Ra=!a.c&&b[2]||a.o,a.Pc=!a.c&&b[3]||a.s);if(c||void 0===c)a.Gb=b[2]||a.o,a.X=b[3]||a.s}function sb(a,b,c){c&&a.f||(a.Qa=b[0]||a.m,a.Oc=b[1]||a.v);if(c||void 0===c)a.eb=b[0]||a.m,a.Eb=b[1]||a.v}function ob(a,b){b||(b=vb);sb(a,b,void 0);ub(a,b,void 0)}var vb=[],rb=[D.prototype.C,D.prototype.I,D.prototype.R,D.prototype.da],tb=[D.prototype.w,D.prototype.H,D.prototype.N,D.prototype.W]; +if(Sa)var qb=[D.prototype.u,D.prototype.G,D.prototype.J,D.prototype.U],pb=[D.prototype.B,D.prototype.L,D.prototype.P,D.prototype.Z];function wb(a,b){q.call(this,"CPU",a,wb);var c=a.multiplier||1;this.ma=a.cycles||b;this.J=c;this.Da=Math.round(this.ma/1E4)/100;this.W=this.Da*this.J;this.l.oa=!1;this.l.yb=!1;this.l.vb=a.autoStart;this.l.xb=!1;this.l.Xa=!1;this.ta=this.X=0;this.ua=a.csStart;this.Z=a.csInterval;this.da=a.csStop;this.H=[];this.ab=this.jb.bind(this);C(this)}w(wb);var xb=["power","reset"]; +k=wb.prototype;k.qa=function(a,b,c,d){this.v=a;this.j=b;this.O=d;for(b=0;ba.P/a.W&&(b=1);a.J=b;b=a.Da*a.J;if(a.W!=b){a.W=b;b=a.W.toFixed(2)+"Mhz";var d=a.A.setSpeed;d&&(d.textContent=b);a.ca("target speed: "+b)}c&&a.v&&Ib(a.v)}Fb(a,a.N);a.N=0;a.I=ja();a.R=0;Gb(a)}function Kb(a,b){var c=a.H.length;a.H.push([-1,b]);return c}function Lb(a,b,c){var d=-1;0<=b&&b=this.ma&&Gb(this,!0);this.pa=0;this.sa=ja();this.R&&(a=this.sa-this.R,a>this.Na&&(this.I+=a,this.I>this.sa&&(this.I=this.sa)));try{do{for(var c=this.l.Xa?1:this.wa,d=this.H.length-1;0<=d;d--){var e=this.H[d];0>e[0]||c>e[0]&&(c=e[0])}this.Fb(c);var f=this.C-this.a; +a=f;for(var h=this.H.length-1;0<=h;h--){var g=this.H[h];0>g[0]||(g[0]-=a,0>=g[0]&&(g[0]=-1,g[1]()))}this.pa+=f;this.N+=f;Fb(this,0,!0);a=f;this.l.Xa&&(b=!1,this.ta=this.ta+this.Ab()|0,this.X-=a,0>=this.X&&(this.X+=this.Z,b=!0),0<=this.da&&this.da<=Hb(this)&&(this.Z=this.da=-1,Ab(this),Db(this),b=!0),b&&this.ca(Hb(this)+" cycles: checksum="+m(this.ta)));this.la-=f;if(0>=this.la){this.la+=this.wa;15<=++this.Oa&&(this.v&&this.v.Ba(),this.Oa=0);break}}while(this.l.oa)}catch(l){Db(this);Bb(this);this.v&& +this.v.stop(ja(),Hb(this));Qa(this,!1);c=l.stack||l.message;this.l.Aa=!0;this.M(c);return}c=setTimeout;d=this.ab;this.R=ja();e=this.Na;this.pa&&(e=Math.round(e*this.pa/this.wa));e=e-(this.R-this.sa);if(f=this.R-this.I)this.P=Math.round(this.N/(10*f))/100,864E5<=f&&(this.U=0,Eb(this));if(0>e||this.Pe&&(this.I-=e),e=0;this.Ea+=this.pa;this.R+=e;c(d,e)}else Bb(this),this.v&&this.v.stop(ja(),Hb(this))};k.Fb=function(){return 0}; +function Db(a){a.l.Ma&&(a.l.gb=!0);a.C-=a.a;a.a=0;Fb(a,a.N);a.N=0;if(a.l.oa){a.l.oa=!1;a.L&&a.L.stop();var b=a.A.run;b&&(b.textContent="Run")}a.l.Ya=void 0}function Bb(a){if(a.v){for(var b=a.v,c=0;c>8&255;a.D=b&255}function Wb(a){return a.f<<8|a.F}function Xb(a,b){a.f=b>>8&255;a.F=b&255}function I(a){return a.g<<8|a.i} +function J(a,b){a.g=b>>8&255;a.i=b&255}function E(a,b){a.o=b&65535}function K(a){return a.m&256?1:0}function L(a,b){a.m=a.m&255|b}function Yb(a){return Ta[a.s&255]?4:0}function Tb(a){return a.G&-214|(a.s&128?128:0)|(a.m&255?0:64)|((a.s^a.w)&16?16:0)|Yb(a)|K(a)}function Rb(a,b){a.m=a.s=a.w=0;b&1&&(a.m|=256);b&4||(a.s|=1);b&16&&(a.w|=16);b&64||(a.m|=255);b&128&&(a.s^=192);a.G=a.G&-726|b&512|2}function M(a,b){a.w=a.b^b;return a.s=(a.m=a.b+b)&255} +function Zb(a,b){a.w=a.b^b;return a.s=(a.m=a.b+b+(a.m&256?1:0))&255}function $b(a,b){a.m=a.s=a.w=a.b&b;(a.b|b)&8&&(a.w^=16);return a.m}function ac(a,b){a.w=b^255;b=a.s=b+255&255;a.m=a.m&-256|b;return b}function bc(a,b){a.w=b;b=a.s=b+1&255;a.m=a.m&-256|b;return b}function cc(a,b){return a.s=a.m=a.w=a.b|b}function N(a,b){b^=255;a.w=a.b^b;return a.s=(a.m=a.b+b+1^256)&255}function dc(a,b){b^=255;a.w=a.b^b;return a.s=(a.m=a.b+b+(a.m&256?0:1)^256)&255}function ec(a,b){return a.s=a.m=a.w=a.b^b}k.K=function(a){return this.j.K(a)}; +k.$=function(a,b){this.j.$(a,b)};function O(a){var b=a.K(a.o);E(a,a.o+1);return b}function P(a){var b=cb(a.j,a.o);E(a,a.o+2);return b}function Q(a){var b=cb(a.j,a.u);a.u=a.u+2&65535;return b}function S(a,b){a.u=a.u-2&65535;fb(a.j,a.u,b)}function fc(a){if(a.a&&a.B&255&&a.G&512){for(var b=0;8>b&&!(a.B&1<b?255:1<>8;L(this,a&256);this.a-=4},hc,function(){var a;J(this,a=I(this)+Ub(this));L(this,a>>8&256);this.a-=10},function(){this.b=this.K(Ub(this));this.a-=7},function(){Vb(this,Ub(this)-1);this.a-=5},function(){this.D= +bc(this,this.D);this.a-=5},function(){this.D=ac(this,this.D);this.a-=5},function(){this.D=O(this);this.a-=7},function(){var a=this.b<<8&256;this.b=(a|this.b)>>1;L(this,a);this.a-=4},hc,function(){Xb(this,P(this));this.a-=10},function(){this.$(Wb(this),this.b);this.a-=7},function(){Xb(this,Wb(this)+1);this.a-=5},function(){this.f=bc(this,this.f);this.a-=5},function(){this.f=ac(this,this.f);this.a-=5},function(){this.f=O(this);this.a-=7},function(){var a=this.b<<1;this.b=a&255|K(this);L(this,a&256); +this.a-=4},hc,function(){var a;J(this,a=I(this)+Wb(this));L(this,a>>8&256);this.a-=10},function(){this.b=this.K(Wb(this));this.a-=7},function(){Xb(this,Wb(this)-1);this.a-=5},function(){this.F=bc(this,this.F);this.a-=5},function(){this.F=ac(this,this.F);this.a-=5},function(){this.F=O(this);this.a-=7},function(){var a=this.b<<8;this.b=(K(this)<<8|this.b)>>1;L(this,a&256);this.a-=4},hc,function(){J(this,P(this));this.a-=10},function(){var a=P(this);fb(this.j,a,I(this));this.a-=16},function(){J(this, +I(this)+1);this.a-=5},function(){this.g=bc(this,this.g);this.a-=5},function(){this.g=ac(this,this.g);this.a-=5},function(){this.g=O(this);this.a-=7},function(){var a=0,b=K(this);if((this.s^this.w)&16||9<(this.b&15))a|=6;if(b||154<=this.b)a|=96,b=1;this.b=M(this,a);L(this,b?256:0);this.a-=4},hc,function(){var a;J(this,a=I(this)+I(this));L(this,a>>8&256);this.a-=10},function(){var a;a=P(this);a=cb(this.j,a);J(this,a);this.a-=16},function(){J(this,I(this)-1);this.a-=5},function(){this.i=bc(this,this.i); +this.a-=5},function(){this.i=ac(this,this.i);this.a-=5},function(){this.i=O(this);this.a-=7},function(){this.b=~this.b&255;this.a-=4},hc,function(){this.u=P(this)&65535;this.a-=10},function(){this.$(P(this),this.b);this.a-=13},function(){this.u=this.u+1&65535;this.a-=5},function(){var a=I(this);this.$(a,bc(this,this.K(a)));this.a-=10},function(){var a=I(this);this.$(a,ac(this,this.K(a)));this.a-=10},function(){this.$(I(this),O(this));this.a-=10},function(){this.m|=256;this.a-=4},hc,function(){var a; +J(this,a=I(this)+this.u);L(this,a>>8&256);this.a-=10},function(){this.b=this.K(P(this));this.a-=13},function(){this.u=this.u-1&65535;this.a-=5},function(){this.b=bc(this,this.b);this.a-=5},function(){this.b=ac(this,this.b);this.a-=5},function(){this.b=O(this);this.a-=7},function(){L(this,K(this)?0:256);this.a-=4},function(){this.a-=5},function(){this.c=this.D;this.a-=5},function(){this.c=this.f;this.a-=5},function(){this.c=this.F;this.a-=5},function(){this.c=this.g;this.a-=5},function(){this.c=this.i; +this.a-=5},function(){this.c=this.K(I(this));this.a-=7},function(){this.c=this.b;this.a-=5},function(){this.D=this.c;this.a-=5},function(){this.a-=5},function(){this.D=this.f;this.a-=5},function(){this.D=this.F;this.a-=5},function(){this.D=this.g;this.a-=5},function(){this.D=this.i;this.a-=5},function(){this.D=this.K(I(this));this.a-=7},function(){this.D=this.b;this.a-=5},function(){this.f=this.c;this.a-=5},function(){this.f=this.D;this.a-=5},function(){this.a-=5},function(){this.f=this.F;this.a-= +5},function(){this.f=this.g;this.a-=5},function(){this.f=this.i;this.a-=5},function(){this.f=this.K(I(this));this.a-=7},function(){this.f=this.b;this.a-=5},function(){this.F=this.c;this.a-=5},function(){this.F=this.D;this.a-=5},function(){this.F=this.f;this.a-=5},function(){this.a-=5},function(){this.F=this.g;this.a-=5},function(){this.F=this.i;this.a-=5},function(){this.F=this.K(I(this));this.a-=7},function(){this.F=this.b;this.a-=5},function(){this.g=this.c;this.a-=5},function(){this.g=this.D;this.a-= +5},function(){this.g=this.f;this.a-=5},function(){this.g=this.F;this.a-=5},function(){this.a-=5},function(){this.g=this.i;this.a-=5},function(){this.g=this.K(I(this));this.a-=7},function(){this.g=this.b;this.a-=5},function(){this.i=this.c;this.a-=5},function(){this.i=this.D;this.a-=5},function(){this.i=this.f;this.a-=5},function(){this.i=this.F;this.a-=5},function(){this.i=this.g;this.a-=5},function(){this.a-=5},function(){this.i=this.K(I(this));this.a-=7},function(){this.i=this.b;this.a-=5},function(){this.$(I(this), +this.c);this.a-=7},function(){this.$(I(this),this.D);this.a-=7},function(){this.$(I(this),this.f);this.a-=7},function(){this.$(I(this),this.F);this.a-=7},function(){this.$(I(this),this.g);this.a-=7},function(){this.$(I(this),this.i);this.a-=7},function(){var a=this.o-1;if(this.ra.length)for(var b=0;b>>=f)&l;if(void 0!==h&&h[0])h[0](a,l,d);f+=g<<3;a+=g;e-=g}this.a-=10},function(){var a=P(this);K(this)||(S(this,this.o),E(this,a),this.a-=6);this.a-=11},function(){S(this,Wb(this));this.a-=11},function(){this.b=N(this,O(this));this.a-=7},function(){S(this,this.o);E(this,16);this.a-=11},function(){K(this)&&(E(this,Q(this)),this.a-=6);this.a-=5},jc,function(){var a=P(this);K(this)&&E(this,a);this.a-=10},function(){for(var a=O(this),b=this.j,c=this.o+-2&65535,d=1,e=0, +f=0;0>8;this.a-=10},function(){var a=P(this);this.s&128||E(this,a);this.a-=10},function(){this.G&=-513;this.a-=4},function(){var a=P(this);this.s&128||(S(this,this.o),E(this,a),this.a-=6);this.a-=11},function(){S(this, +Tb(this)&255|this.b<<8);this.a-=11},function(){this.b=cc(this,O(this));this.a-=7},function(){S(this,this.o);E(this,48);this.a-=11},function(){this.s&128&&(E(this,Q(this)),this.a-=6);this.a-=5},function(){this.u=I(this)&65535;this.a-=5},function(){var a=P(this);this.s&128&&E(this,a);this.a-=10},function(){this.G|=512;this.a-=4;fc(this)},function(){var a=P(this);this.s&128&&(S(this,this.o),E(this,a),this.a-=6);this.a-=11},kc,function(){N(this,O(this));this.a-=7},function(){S(this,this.o);E(this,56); +this.a-=11}];function U(a){q.call(this,"ChipSet",a,U);var b=a.model;b&&!lc[b]&&Aa("Unrecognized ChipSet model: "+b);this.c=lc[b]||{};a.sound&&(this.I=null,window&&(this.I=window.AudioContext||window.webkitAudioContext),this.I&&new this.I);C(this)}w(U); +var W={aa:1978.1,jc:{ba:0,Uc:1,Yc:16,ed:32,od:64,nd:128,Ga:14},za:{ba:1,Lb:1,ec:2,ac:4,bc:16,cc:32,dc:64,Ga:8},kc:{ba:2,Tc:3,xd:4,Vc:8,jd:16,kd:32,ld:64,Wc:128,Ga:0},sd:{ba:3},qd:{ba:2,fd:7},ud:{ba:3,yd:1,td:2,md:4,cd:8,Xc:16,Qc:32},rd:{ba:4},vd:{ba:5,Zc:1,$c:2,ad:4,bd:8,zd:16}},X={aa:100,ja:{ba:66,tb:1,Zb:2,$b:4,hd:8,gd:16,rb:32,qb:64,nb:128},Kb:{ba:66,INIT:0},xa:{ba:194,Sc:0,mb:16,fc:32,sb:48,Pb:0,Qb:32},Sa:{ba:162,pd:0,Sb:0,Ob:0,Rb:0,Nb:0},ka:{dd:{ba:98},Ca:{Ib:0,Hb:1,hc:2,lc:4,Mb:5,gc:6,wd:7}, +Va:16383}},lc={SI1978:W,VT100:X};U.prototype.V=function(){return!1};U.prototype.qa=function(a,b,c,d){this.j=b;this.a=c;this.O=d;this.v=a;this.m=Va(a,"Keyboard");this.Z=Va(a,"SerialPort");this.video=Va(a,"Video");gb(b,this,this.c.bb);hb(b,this,this.c.cb)};U.prototype.fa=function(a,b){if(!b)if(!a)this.reset();else if(!this.restore(a))return!1;return!0};U.prototype.ia=function(a){return a?this.save():!0};W.INIT=[[W.jc.Ga,W.za.Ga,W.kc.Ga,0,0,0,0]]; +X.INIT=[[X.Kb.INIT,X.ja.Zb|X.ja.$b],[X.xa.Pb,X.xa.Qb],[X.Sa.Sb,X.Sa.Ob,X.Sa.Rb,X.Sa.Nb],[0,0,0,0,[11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11776,11784,11918,11776,11984,11888,11776,11808,11776,12E3,12E3,11901,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], +[11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11904,11776,11784,11918,11808,11984,11856,11776,11808,11776,12E3,12E3,11881,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]];k=U.prototype;k.reset=function(){this.c.INIT&&!this.restore(this.c.INIT)&&this.M("reset error")}; +k.save=function(){var a=new F(this);switch(this.c.aa){case W.aa:G(a,0,[this.W,this.g,this.X,this.C,this.L,this.R,this.U]);break;case X.aa:G(a,0,[this.J,this.u]),G(a,1,[this.o,this.s]),G(a,2,[this.f,this.G,this.P,this.N]),G(a,3,[this.B,this.b,this.w,this.H,this.i])}return a.data()}; +k.restore=function(a){var b;if(a&&(b=a[0])&&b.length)switch(this.c.aa){case W.aa:return this.W=b[0],this.g=b[1],this.X=b[2],this.C=b[3],this.L=b[4],this.R=b[5],this.U=b[6],!0;case X.aa:return this.J=b[0],this.u=b[1],b=a[1],this.o=b[0],this.s=b[1],b=a[2],this.f=b[0],this.G=b[1],this.P=b[2],this.N=b[3],b=a[3],this.B=b[0],this.b=b[1],this.w=b[2],this.H=b[3],this.i=b[4],!0}return!1};k.start=function(){};k.stop=function(){};k.qc=function(){return this.W};k.rc=function(){return this.g};k.sc=function(){return this.X}; +k.pc=function(){return this.C>>8-this.L&255};k.Cc=function(a,b){this.L=b};k.Ec=function(a,b){this.R=b};k.Dc=function(a,b){this.C=b<<8|this.C>>8};k.Fc=function(a,b){this.U=b};k.Gc=function(){};function mc(a){var b=0,c=0,d=~a.B;for(a=0;10>a;a++)d&1&&(b=9-a),d>>=1;for(a=0;10>a;a++)d&1&&(c=9-a),d>>=1;return 10*b+c} +k.tc=function(){var a=this.u,a=a&~X.ja.qb;if((Hb(this.a)&64)<<1&&(a|=X.ja.qb,a!=this.u)){var b,c;b=this.w&1;switch(this.w>>1&7){case X.ka.Ca.Hb:this.B=this.B<<1|b;break;case X.ka.Ca.Mb:b=mc(this);this.i[b]=X.ka.Va;break;case X.ka.Ca.Ib:this.b=this.b<<1|b;break;case X.ka.Ca.lc:b=mc(this);c=this.b&X.ka.Va;this.i[b]=c;break;case X.ka.Ca.gc:b=mc(this);c=this.i[b];null==c&&(c=X.ka.Va);this.b=c;break;case X.ka.Ca.hc:this.b<<=1,this.H=this.b&X.ka.Va+1}}a&=~X.ja.rb;this.H&&(a|=X.ja.rb);a&=~X.ja.nb;if(b=this.m){b= +this.m;if(c=b.f)c=b.a,c=Hb(b.a)>=b.m+c.ma*c.J/1E3*1.2731488;c&&(b.f=!1);b=!b.f}b&&(a|=X.ja.nb);a&=~X.ja.tb;this.Z&&this.Z.ea&1&&(a|=X.ja.tb);return this.u=a};k.Hc=function(a,b){this.J=b};k.Kc=function(a,b){this.w=b};k.Jc=function(a,b){var c=b&3;switch(b>>2&3){case 0:this.f=this.f&-4|c;break;case 1:this.f=this.f&-13|c<<2;if(this.video){var c=this.video,d=this.f;c.pa!==d&&((c.pa=d)?Mb(c,!0):c.sa=!0)}break;case 2:switch(c){case 0:this.G=~this.G;break;case 2:case 3:this.P=3-c}break;case 3:this.N=c}}; +k.Ic=function(a,b){if(b&X.xa.fc)b&=X.xa.sb,this.s!=b&&(this.s=b,this.video&&(this.video.Db=this.s==X.xa.sb?50:60));else if(b&=X.xa.mb,this.o!=b&&(this.o=b,this.video)){var c=this.video,d=this.o==X.xa.mb?132:80;c.H=d;c.T=c.wa;80>8&255,a.b[d++]=h[c]>>16&255,a.b[d++]=h[c]>>24&255;else a.b=e;a.i=e.symbols;if(!a.b.length){p("Empty ROM: "+b);return}if(1==a.b.length){p(a.b[0]);return}}catch(g){a.M("ROM data error: "+g.message);return}else for(b=c.replace(/\n/gm, +" ").replace(/ +$/,"").split(" "),a.b=Array(b.length),e=0;e>>f.j;0>>=f.j;0d?a.j.push({kb:b,hb:Date.now(),Wa:!1}):(a.j[d].hb=Date.now(),a.j[d].Wa=!1);else if(0<=d){if(!a.j[d].Wa){var e=a.j[d].hb;if(e&&100>Date.now()-e)return a.j[d].Wa=!0,Cc(a),!0}a.j.splice(d,1)}if(a.L){d=0;switch(b){case "1p":d=W.za.ac;break;case "2p":d=W.za.ec;break;case "coin":d=W.za.Lb;break;case "left":d=W.za.cc;break;case "right":d=W.za.dc;break;case "fire":d=W.za.bc}d&&(a=a.L,b=d,a.g&=~b,c&&(a.g|=b))}return!0} +function Cc(a){for(var b=0,c=-1;bc||c>e)c=e}else{Ac(a,d,!1);b=0;continue}}b++}0<=c&&setTimeout(function(){Cc(a)},c)}k.uc=function(){var a=this.g;0<=this.c&&(this.c>3)*a.G,!Za(a.j,a.da,a.B,3)))return!1;a.B?(a.La=a.f.createImageData(b,c),a.Oa=16/a.la|0,Ic(a,a.B>>1)):Ic(a,(a.H+1)*a.W);a.s=document.createElement("canvas");a.s.width=b;a.s.height=c;a.ra=a.s.getContext("2d");a.I={};a.R=1<=a.wa?8:16,f=8>(7>4)*c)}return l}Dc.prototype.fa=function(){return!0};Dc.prototype.V=function(a,b,c){var d=this;if("led"==a||"rled"==a)return this.ua[b]=c,!0;switch(b){case "fullScreen":return this.A[b]=c,this.b&&this.b.Fa?c.onclick=function(){d.Fa()}:c.parentNode.removeChild(c),!0}return!1}; +Dc.prototype.Fa=function(){var a=!1;if(this.b){if(this.b.Fa){a="100%";if(screen&&screen.width&&screen.height){var b=screen.width/screen.height,c=this.C/this.w;b>c&&(a=Math.round(c/b*100)+"%")}this.Ka?(this.u.style.width=a,this.u.style.width=a,this.u.style.display="block",this.u.style.margin="auto"):(this.b.style.width=a,this.b.style.height="auto");this.b.style.backgroundColor="black";this.b.Fa();a=!0}this.P&&this.P.focus()}return a}; +function Gc(a,b){!b&&a.b&&(a.Ka?a.u.style.width=a.u.style.height="":a.b.style.width=a.b.style.height="")}function Ic(a,b){a.Na=b;a.N=!1;if(void 0===a.i||a.i.length!=a.Na)a.i=Array(a.Na)}function Kc(a,b,c,d,e){d=a.c?(b.height-c-1)*b.width+d:c+d*b.width;e&&1==a.U&&(208<=c&&236>c?e=a.R+0:28<=c&&72>c&&(e=a.R+1));a=a.J[e];d*=a.length;b.data[d]=a[0];b.data[d+1]=a[1];b.data[d+2]=a[2];b.data[d+3]=a[3]} +function Mb(a,b){var c=!0;if(!b){a.ma&&(120==a.ma?a.$a&1?(gc(a.a,2),c=!1):gc(a.a,1):gc(a.a,4));if(c&&a.N&&a.B){for(var d=a.j,e=a.B,f=!0,h=a.da>>>d.j;0>=1);;){var u=bb(a.j,x++);if(127==(u&127)){var y=bb(a.j,x++),d=y&96,c=(y&15)<<8|bb(a.j,x),c=c+(y&16? +8192:16384);break}if(n>4)*u.S,R=void 0,ka=void 0,Ca=void 0,db=void 0,zc=u.T,Jb=u.S;v?(R=B*y.T,ka=e*y.S,Ca=y.T,db=y.S):(R=B*y.Da,ka=e*y.Ea,Ca=y.Da,db=y.Ea);u.T>y.T&&(R*=2,Ca*=2);u.S>y.S&&(0==t&&(H+=y.S),Jb=y.S);v?v.drawImage(u.canvas,V,H,zc,Jb,R,ka,Ca,db):(R+=0,ka+=0,y.f.drawImage(u.canvas, +V,H,zc,Jb,R,ka,Ca,db))}g++}h++}e++}}a.N=!0;!b&&a.sa&&1==g&&(a.i[l]=-1,g=0);a.sa=!1;(g||b)&&a.ra&&a.f.drawImage(a.s,0,a.pa,a.o,a.G-a.S,0,0,a.vc,a.wc)}else{f=a.da;h=f+a.B;n=l=g=0;c=a.o;t=0;d=a.G;x=e=0;B=a.la;y=(1<>>v.j;v=V!=v.f?v.b[H].Eb(V,u):v.b[H++].eb(V,u)|v.b[H&v.s].eb(0,u+1)<<8;if(a.N&&v===a.i[g])l+=a.Oa;else{a.i[g]=v;(u=x)&&(v=v>>8|(v&255)<<8);l>u&y,Kc(a,a.La,l++,n,H),u+=B;l>t&&(t=l);n=e&& +(e=n+1)}f+=2;g++;if(l>=a.o&&(l=0,n++,n>a.G))break}a.N=!0;cMissing <canvas> support. Please try a newer web browser.";break}e.setAttribute("class","pcjs-canvas");e.setAttribute("width",d.screenWidth);e.setAttribute("height",d.screenHeight);e.style.backgroundColor=d.screenColor;e.style.height="auto";0<=(window?window.navigator.userAgent:"").indexOf("MSIE")&&(c.onresize=function(a, +b,c,d){return function(){b.style.height=(a.clientWidth*d/c|0)+"px"}}(c,e,d.screenWidth,d.screenHeight),c.onresize());var f=+(d.aspect||Fa.aspect);f&&.3<=f&&3.33>=f&&(xa("onresize",function(a,b,c){return function(){b.style.height=(a.clientWidth/c|0)+"px"}}(c,e,f)),window.onresize());c.appendChild(e);f=document.createElement("textarea");sa("iOS")&&(f.setAttribute("autocapitalize","off"),f.setAttribute("autocorrect","off"));c.appendChild(f);var h=e.getContext("2d"),d=new Dc(d,e,h,f,c);Pa(d,c)}}); +function Lc(a){this.H=+a.adapter;switch(this.H){case 0:this.I=0;this.N=2;break;default:p("Unrecognized serial adapter #"+this.H);return}this.b=this.c=null;this.J=a.tabSize;this.G=a.charBOL;this.f=0;this.B=!1;q.call(this,"SerialPort",a,Lc);var b=a.binding;if("console"==b)this.c="";else{var c;a=Mc;b&&(void 0===c&&(c="Panel"),(c=Oa(c,this.id))&&(b=c.A[b])&&this.V(null,a,b))}this.g="";this.i=this.o=null;this.exports={connect:this.Bb,receiveData:this.ib}}w(Lc); +var Nc=[50,75,110,134.5,150,200,300,600,1200,1800,2E3,2400,3600,4800,9600,19200],Oc=[!1,0,0,133,142,39,238],Mc="buffer";k=Lc.prototype; +k.V=function(a,b,c,d){var e=this;switch(b){case Mc:return this.A[b]=this.b=c,c.onkeydown=function(a){a=a||window.event;var b=a.keyCode;if(8===b||a.ctrlKey&&65<=b&&90>=b)a.preventDefault&&a.preventDefault(),64");if(2==b.length){var c=ha(b[0]);if(c!=this.Ta)return;b=ha(b[1]);if(this.i=Na(b)){var d=this.i.exports;if(d){var e=d.connect;e&&e.call(this.i);if(this.o=d.receiveData){this.status(this.Ua+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}};k.fa=function(a,b){if(!b)if(this.Bb(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0}; +k.ia=function(a){return a?this.save():!0};k.reset=function(){Sc(this)};k.save=function(){var a=new F(this),b=0,c=[];c[b++]=this.ha;c[b++]=this.w;c[b++]=this.C;c[b++]=this.ea;c[b++]=this.m;c[b++]=this.u;c[b]=this.s;G(a,0,c);return a.data()};k.restore=function(a){return Sc(this,a[0])};function Sc(a,b){var c=0;void 0===b&&(b=Oc);a.ha=b[c++];a.w=b[c++];a.C=b[c++];a.ea=b[c++];a.m=b[c++];a.u=b[c++];a.s=b[c];return!0} +function Tc(a,b){var c=a.s&b;b&15||(c>>=4);var c=Nc[c],d=((a.m&12)>>2)+6;a.m&16&&d++;d+=((a.m&192)>>6)+1>>1;return 1E3/Math.round(c/d)}function Pc(a,b){return a.B||a.ea&2?!1:(a.w=b,a.ea|=2,gc(a.a,a.N),!0)}k.ib=function(a){null!=a&&(this.g="number"!=typeof a?a:this.g+String.fromCharCode(a));this.g&&(Pc(this,this.g.charCodeAt(0))&&(this.g=this.g.substr(1)),this.g&&this.a&&Lb(this.a,this.P,Tc(this,15)));return!0};k.oc=function(){var a=this.w;this.ea&=-3;return a};k.nc=function(){return this.ea}; +k.Bc=function(a,b){this.C=b;this.ea&=-6;if(19==b)this.B=!0;else if(17==b)this.B=!1;else if(this.o&&this.o.call(this.i,b),this.b)if(8==b)this.b.value=this.b.value.slice(0,-1),0":String.fromCharCode(b);var d=c.length;9==b?(d=this.J||8,d=d-this.f%d,this.J&&(c=" ".slice(0,d))):13==b&&(this.f=d=0,c="\n");this.G&&!this.f&&d&&(c=String.fromCharCode(this.G)+c);this.b.value+=c;this.b.scrollTop=this.b.scrollHeight;this.f+= +d}else if(null!=this.c){if(10==b||1024<=this.c.length)this.ca(this.c),this.c="";10!=b&&(this.c+=String.fromCharCode(b))}this.a&&Lb(this.a,this.R,Tc(this,240))};k.Ac=function(a,b){this.ha?(this.u=b,this.u&64&&(this.ha=!1)):(this.m=b,this.ha=!0)};k.zc=function(a,b){this.s=b};var Qc={0:Lc.prototype.oc,1:Lc.prototype.nc},Rc={0:Lc.prototype.Bc,1:Lc.prototype.Ac,2:Lc.prototype.zc};ya(function(){for(var a=A(document,"pc8080","serial"),b=0;b\nLicense: GPL version 3 or later ");for(b=0;bWc){if(Yc(d,this.s)){this.i=new F(this,"1.24.2","failsafe");Yc(this.i)&&(dd(this,d),a=2,ed(this.i));G(this.i,"timestamp",la());fd(this.i);var e=this.b&&!this.v;if(1==a||na("Click OK to restore the previous PC8080 machine state, or CANCEL to reset the machine.")){if(c=bd(d)){var f=cd(d,"code"),h=cd(d,"data");f&&("ok"==f?Yc(d,h):("error"==f&& +"no machine state"!=h?(this.M("Error: "+h),"unable to verify user"==h&&(ra("user",""),this.c=null)):this.ca(f+": "+h),ed(d),Yc(d)?(c=bd(d),e=!0):c=!1))}e&&ad(this,c?d:null)}else 2==a&&d.clear()}else ad(this);delete this.s;delete this.u}e=Ma(this.id);for(f=0;fa[1];a=a[2];this.J=!0;this.l.Y=!0;var d=this.A.power;d&&(d.textContent="Shutdown");this.a&&(gd(this,this.a,b,c,a),Cb(this.a));this.C&&(dd(this,b),b.clear());!c&&this.i&&(this.i.clear(),delete this.i);this.f=0}; +function dd(a,b){if(na("There may be a problem with your PC8080 machine.\n\nTo help us diagnose it, click OK to send this PC8080 machine state to http://www.pcjs.org.")){var c=a.c||"",d=b.toString(),e={app:"PC8080",ver:"1.24.2"};e.url=a.I;e.user=c;e.type="bug";e.data=d;ma("http://www.pcjs.org/api/v1/report",e,!0)}} +function hd(a,b,c){var d,e="none";if(a.f)return null;a.f--;var f=new F(a,"1.24.2"),h=new F(a,"1.24.2","validate"),g=la();G(h,"timestamp",g);G(f,"timestamp",g);G(f,"version","1.24.2");G(f,"url",window?window.location.href:null);G(f,"browser",window?window.navigator.userAgent:"");a.a&&a.a.ia&&(c&&Db(a.a),d=a.a.ia(b,c),"object"===typeof d&&G(f,a.a.id,d),c&&(a.a.l.Y=!1,!1===d&&(e=null)));for(var g=Ma(a.id),l=0;lg.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(g=window.location.pathname+g);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(g?' url="'+g+'"':""))}e||(a=a.replace(/().*?(<\/xsl:variable>)/,"$1pc8080$2")); +g=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(g=new window.ActiveXObject("Microsoft.XMLDOM"),g.async=!1,g.loadXML(a)):g=(new window.DOMParser).parseFromString(a,"text/xml")}catch(t){g=null,a=t.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");ma(e,null,!0,function(f,h,g){if(g||!h)c(a,"unable to resolve XML reference: "+d[0]+" ("+g+")");else{if(f=d[3])if(g=h.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var l=g[0],n,x=/( [a-z]+=)(['"])(.*?)\2/g;n=x.exec(f);)l=0>l.indexOf(n[1])?l.replace(">",n[0]+">"):l.replace(new RegExp(n[1]+"(['\"])(.*?)\\1"),n[0]);g[0]!=l&&(h=h.replace(g[0],l))}else{c(a,"missing <"+d[1]+"> in "+e);return}h=h.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],h);od(a,b,c)}})}else c(a,null)} +function pd(a,b,c,d){function e(a){if(void 0===g){var b=h&&A(h,"machine-warning");g=b&&b[0]||h}g&&(g.innerHTML=ga(a))}function f(a){e("Error: "+a);l&&(--ld||Ba(!0));l=!1}var h,g,l=!0;ld++;Ka[a]={};try{if(h=document.getElementById(a)){var n;if("object"==typeof resources&&(n=resources.css)){var x=document.head||document.getElementsByTagName("head")[0],t=document.createElement("style");t.type="text/css";t.styleSheet?t.styleSheet.cssText=n:t.appendChild(document.createTextNode(n));x.appendChild(t)}c|| +(c="/versions/pc8080/1.24.2/components.xsl");n=function(d,g){g?md(c,null,null,!1,e,function(d,l){if(l)if(La(a,c,d),e("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var n=g.transformNode(l);n?(h.outerHTML=n,--ld||Ba(!0)):f("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(n=new XSLTProcessor,n.importStylesheet(l),(n=n.transformToFragment(g,document))?h.parentNode?(h.parentNode.replaceChild(n,h),--ld||Ba(!0)):f("invalid machine element: "+ +a):f("transformToFragment failed")):f("unable to transform XML: unsupported browser");else f(d)}):f(d)};"<"!=b.charAt(0)?md(b,a,d,!0,e,n):nd(b,null,a,d,!1,e,n)}else f("missing machine element: "+a)}catch(B){f(B.message)}return l}window.embedPC8080=function(a,b,c,d){Ba(!1);return pd(a,b,c,d)};window.enableEvents=Ba;window.sendEvent=Da;})(); diff --git a/versions/pcx86/1.24.2/common.css b/versions/pcx86/1.24.2/common.css new file mode 100644 index 000000000..6b1c0f887 --- /dev/null +++ b/versions/pcx86/1.24.2/common.css @@ -0,0 +1,265 @@ +@CHARSET "UTF-8"; +/** + @author Jeff Parsons (@jeffpar) + @website http://www.pcjs.org/ + @created 2013-05-05 + @modified 2014-02-23 + @license http://www.gnu.org/licenses/gpl.html + */ +body { + margin: 0; + background: #202020; +} +h1, h2 { + margin-top: 0; + color: #cccccc; +} +h1, h2, h3, h4 { + word-wrap: break-word; +} + +h4 a { + color: #cccccc !important; +} +p { + line-height: 1.5em; +} +img { + max-width: 100%; +} +a img { + vertical-align: bottom; +} +pre, code { + color: #000000; + background-color: #cccccc; + font-family: Monaco, Consolas, "Lucida Console", monospace; + font-size: 12px; +} +pre { + margin: 1em 2em; + padding: 1em; + border-radius: 5px; + overflow: auto; +} +code { + padding: 1px; +} +pre a, code a { + color: #006400 !important; +} +.common { + width: 100%; + margin: 0 auto; + color: #cccccc; +} +.common a { + + color: #7fc07f; + text-decoration: none; +} +.common hr { + border-color: #808080; +} +.common a:hover { + text-decoration: underline; +} +.common, .machine { + font-family: "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif; + font-size: 15px; +} +.machine { + margin: 15px; + overflow: hidden; +} +.c1pjs { + overflow: visible; +} +.machine-placeholder { + text-align: center; + font-weight: bold; +} +.common-top { + background: #202020; + font-size: small; +} +.common-top-left { + float: left; + width: 60%; +} +.common-top-left ul { + line-height: 1.5em; + list-style-type: none; + margin: 0; + padding: 1em 1em 1em 9px; + overflow: hidden; +} +.common-top-left ul li { + display: block; + float: left; +} +.common-top-left ul li a { + border-right: 1px solid #6f6f6f; + padding: 2px 6px 2px 6px; +} +.common-top-left ul li:last-child a { + border-right: none; +} +.common-top-right { + float: right; + width: 40%; +} +.common-top-right p { + float: right; + margin: 0; + padding: 1em; +} +.common-middle { + clear: both; + padding: 1px 1em 1px 1em; + background: #404040; +} +.common-sidebar { + float: left; + font-size: small; + width: 140px; + padding-bottom: 20px; + overflow: hidden; + white-space: nowrap; + word-wrap: break-word; +} +.common-list { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} +.common-list li { + + padding-bottom: 7px; +} +.common-list-data { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} +.common-list-data li { + line-height: 1.5em; +} +.common-list-data-items, .common-list-data-subitems { + font-size: x-small; + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + padding-left: 2em; +} +.common-list-data-items li, .common-list-data-subitems li { + padding-bottom: 0; +} +.common-main { + margin-left: 150px; + +} +.common-main blockquote { + text-align: justify; +} +.common-image-gallery { + margin: 0 auto; + text-align: center; +} +.common-image-gallery:after { + content: ''; + display: block; +} +.common-image-frame { + display: inline-block; + margin: 8px; + text-align: center; +} +.common-image-link { + padding: 5px; + border: 1px solid black; + border-radius: 5px; + background-color: #FAEBD7; +} +.common-image-label { + font-size: x-small; +} +.common-bottom { + clear: both; + padding-top: 1em; +} +.common-bottom:after { + content: ''; + display: block; + clear: both; +} +.common-reference { + float: left; + font-size: x-small; +} +.common-reference a { + text-decoration: none; +} +.common-copyright { + float: right; + font-size: x-small; +} +.common-copyright a { + text-decoration: none; +} +.md-list { +} +.md-list li { + line-height: 1.5em; + margin-bottom: 1em; +} +.md-list li p { + padding-left: 2em; +} +.md-list-compact { +} +.md-list-compact li { + margin-bottom: 0; +} +.md-list-none { + list-style-type: none; + padding-left: 2em; +} +.md-list-none li { + margin-bottom: 0; +} +@media screen and (max-width: 900px) { + + .common-sidebar { + width: 100%; + white-space: normal; + } + .common-list { + padding-left: 0; + } + .common-list-data { + padding-left: 0; + } + .common-sidebar h4, .common-list li, .common-list-data li, .common-list-data-items li { + width: 130px; + float: left; + overflow: hidden; + vertical-align: top; + padding-right: 1em; + margin-top: 0; + } + .common-list-data-subitems { + display: none; + } + .common-main { + clear: both; + margin-left: 0; + padding-left: 0; + padding-right: 0; + } + .md-list-none { + padding-left: 1em; + } +} diff --git a/versions/pcx86/1.24.2/common.xsl b/versions/pcx86/1.24.2/common.xsl new file mode 100644 index 000000000..0ebd3f54e --- /dev/null +++ b/versions/pcx86/1.24.2/common.xsl @@ -0,0 +1,58 @@ + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +

    Powered by JavaScript and GitHub

    +
    +
    +
    + + +
    +

    + +
    +
    + +
    diff --git a/versions/pcx86/1.24.2/components.css b/versions/pcx86/1.24.2/components.css new file mode 100644 index 000000000..0e0842602 --- /dev/null +++ b/versions/pcx86/1.24.2/components.css @@ -0,0 +1,159 @@ +@CHARSET "UTF-8"; + + +*:not(input,textarea) { + -webkit-user-select: none; +} +.pcjs-embed { +} +.pcjs-embed:after { + clear:both; +} +.pcjs-machine { +} +.pcjs-name, .pcjs-menu { + clear: both; + font-weight: bold; + padding-bottom: 4px; +} +.pcjs-menu { + float: left; +} +.pcjs-canvas { + width: 100%; + height: auto; +} +.pcjs-container { + color: #000000; + position: relative; +} +.pcjs-label { + font-size: small; + line-height: 19px; + vertical-align: middle; + float: left; + font-family: "Lucida Console", monospace; +} +.pcjs-controls textarea { + font-family: Monaco, monospace; + font-size: x-small; +} +.pcjs-fieldset { + border: none; + margin: 0; + padding: 0; +} +.pcjs-flag { + font-family: "Lucida Console", monospace; + font-size: small; + text-align: center; + line-height: 19px; + vertical-align: middle; +} +.pcjs-register { + font-family: "Lucida Console", monospace; + font-size: small; + text-align: center; + line-height: 19px; + vertical-align: middle; + border: 1px solid black; +} +.pcjs-switches { + float: left; +} +.pcjs-bitBucket { + float: left; + width: 19px; + height: 38px; +} +.pcjs-bitCell { + float: left; + width: 19px; + height: 19px; + margin-right: -1px; + margin-bottom: -1px; + border: 1px solid black; + text-align: center; + line-height: 19px; +} +.pcjs-bitCellLeft { + border-left: 1px solid black; +} +.pcjs-bitLabel { + font-size: xx-small; + text-align: center; +} +.pcjs-description, .pcjs-status { + font-size: x-small; + line-height: 2em; +} +.pcjs-key { + border: 1px solid black; + font-size: x-small; + text-align: center; + position: absolute; + height: 34px; + line-height: 34px; + background-color: #ffffff; +} +.pcjs-led { + float: left; + width: 8px; + height: 8px; + margin: 4px; + border: 1px solid black; + text-align: center; + line-height: 19px; + background-color: #000000; +} +.pcjs-rled { + float: left; + width: 8px; + height: 8px; + margin: 4px; + border: 1px solid black; + border-radius: 50%; + text-align: center; + line-height: 19px; + background-color: #000000; +} +.pcjs-screen { + clear: both; + height: auto; + position: relative; + line-height: 0; +} +.pcjs-screen textarea { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + opacity: 0; + border: 0; + padding: 0; + line-height: 0; +} +.pcjs-reference { + float: left; + font-size: x-small; +} +.pcjs-reference a { + text-decoration: none; +} +.pcjs-copyright { + float: right; + font-size: x-small; +} +.pcjs-copyright a { + text-decoration: none; +} + +@media screen and (max-width: 900px) { + .pcjs-textarea { + width: 100% !important; + } + .pcjs-registers { + width: 100% !important; + } +} diff --git a/versions/pcx86/1.24.2/components.xsl b/versions/pcx86/1.24.2/components.xsl new file mode 100644 index 000000000..e98fb4cb7 --- /dev/null +++ b/versions/pcx86/1.24.2/components.xsl @@ -0,0 +1,1242 @@ + + + + + + + + + + + pc + pcjs + pcx86 + PCx86 + 1.24.2 + www.pcjs.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + float: + + + + js + + + +
    + + + + + + + + + + js + + + "" + + + + + +
    +
    + + + + + + + + + + + + + + + , + + + + + + + + + + + + + .machine + . + . + + + + + + + + + + + + + + + + + + + + ,comment:'' + + + + + + border:1px solid black;border-radius:15px; + border:; + + + + + + left:; + + + + + + top:; + + + + + + + + width:; + width:;max-width:; + width:auto;max-width:; + + + + + + + + height:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto;clear:both; + position:; + position:relative; + + + + + overflow:auto;width:100%; + background-color:; + + + + - -component + +
    + + + + + + +
    + + + + + + + + --object -screen + + +
    +
    + +
    + +
    +
    + + + + +
    + + +
    [XML]
    + +
    + + +
    +
    +
    +
    + + + + + text-align:center; + + + +

    +
    + + +
    +
    + + + + + + +
    +
    + + + + type:'' + + + binding:'' + + + value:'' + + + + border:1px solid black; + border:; + + + + + + width:; + + + + + + height:; + + + + + + left:; + + + + + + top:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto; + position:; + position:relative; + float:left; + + + + + + + + + + + + + + + + + + +
    + + + font-size:; + + + + + -label + + + + width:; + width:; + + + + + + + + text-align:right; + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    + + + + +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + ; + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8088 + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + 1 + + + + + + + null + + + + + + + -1 + + + + + + + -1 + + + + + + + -1 + + + + + + ,model:'',stepping:'',fpu:,cycles:,multiplier:,autoStart:,csStart:,csInterval:,csStop: + + + + + + + + + + + + + + + 8087 + + + + + + + + + + + + ,model:'',stepping:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + true + + + + + + false + + + + + + {} + + + + + + + + + + + + + + + + + chipset + ,model:'',scaleTimers:,sw1:'',sw2:'',sound:,floppies:,monitor:'',rtcDate:'' + + + + + + + + + + + + + + + + + + + + keyboard + ,model:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + parallel + ,adapter:,binding:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 0 + + + + + + + 0 + + + + + serial + ,adapter:,binding:'',tabSize:,charBOL: + + + + + + + + + + + + + + + + + + + + mouse + ,serial:'' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fdc + ,autoMount:'',sortBy:'' + + + + + + + + + + + + + + + + + + + + + xt + + + + + hdc + ,drives:'',type:'' + + + + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + null + + + + + + + + + + + + + + + + + + false + + + + + rom + ,addr:,size:,alias:,file:'',notify:'',writable: + + + + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + true + + + + + ram + ,addr:,size:,test: + + + + + + + + + + + + + + + + + + + + + null + + + + + + + 256 + + + + + + + 224 + + + + + + + black + + + + + + 0 + + + + + + 0 + + + + + + false + + + + + + 1bpp + + + + + + 0 + + + + + + 0 + + + + + + 1 + + + + + + 0 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + false + + + + + + 1 + + + + + + 1 + + + + + + + 80 + + + + + + + 25 + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + 0 + + + + + + null + + + + + + 0 + + + + + + 60 + + + + + video + ,model:'',mode:,screenWidth:,screenHeight:,screenColor:'',screenRotate:,bufferAddr:,bufferRAM:,bufferFormat:'',bufferCols:,bufferRows:,bufferBits:,bufferLeft:,bufferRotate:,memory:,switches:'',scale:,cellWidth:,cellHeight:,charCols:,charRows:,fontROM:'',fontColor:'',touchScreen:'',autoLock:,aspectRatio:,smoothing:,interruptRate:,refreshRate: + + + + + + + + + + + + + + + + + + + + + + + + + + debugger + ,commands:'',messages:'' + + + + + + + + + + + + + + panel + + + + + + + + + + + + + + + + + + + + + true + + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + computer + ,autoPower:,busWidth:,resume:,state:'' + + + + + + + +
    diff --git a/versions/pcx86/1.24.2/document.css b/versions/pcx86/1.24.2/document.css new file mode 100644 index 000000000..7072b406e --- /dev/null +++ b/versions/pcx86/1.24.2/document.css @@ -0,0 +1,162 @@ +@CHARSET "UTF-8"; + +.page { + margin: 2% 2%; + padding: 2% 2%; + min-width: 30em; + overflow: auto; + font-size: large; + font-family: Helvetica, Arial, sans-serif; + background: #303030; + color: #ccc; + +} +.page-header { +} +.page-header-title { + text-align: center; + +} +.page a { + color: #7fc07f; + text-decoration: none; +} +a.footlink, a.paralink { + text-decoration: none; +} +a.footlink:link, a.paralink:link { + color: blue; +} +a.footlink:visited, a.paralink:visited { + color: blue; +} +.galleryitem { + float: left; + width: 200px; +} +.item { + float: left; + width: 2em; + text-indent: 1em; +} +.list { + margin-left: 3em; + text-indent: 0; + text-align: justify; +} +ul { + list-style: none; +} +div.pnumber { + float: left; + width: 2em; + text-indent: 1em; +} +div.pitem { + margin-left: 10em; +} +p.indent, .justified p { + text-indent: 2em; + text-align: justify; + line-height: 1.5em; +} +p.noindent { + text-indent: 0; + text-align: justify; +} +p.center, .center { + text-align: center; +} +li.para { + margin-top: 1em; + margin-bottom: 1em; +} +.left { + text-align: left; +} +.right { + text-align: right; +} +blockquote.tag { + font-size: small; + font-family: Monaco, Fixed, monospace; + margin-top: 0; + margin-bottom: 0; +} +.blockquote { + padding-left: 1em; + text-indent: 0; + text-align: justify; +} +.italics { + font-style: italic; +} +.medium { + font-size: medium; +} +.small { + font-size: x-small; +} +.smallcaps { + font-variant: small-caps; +} +.strike { + text-decoration: line-through; +} +.summation, .bracelist { + display: inline-block; + position: relative; + vertical-align: middle; + text-align: center; + margin-bottom: 0.5ex; + text-indent: 0; +} +.bracelist-symbol { + font-size: 3em; + vertical-align: -40%; +} +.summation .summation-lower, .summation .summation-upper, .bracelist-item { + display: block; + font-size: 75%; + text-align: center; +} +.summation .summation-upper { + margin-bottom: 0; + margin-left: 0.8ex; + font-style: italic; +} +.summation .summation-lower{ + margin-bottom: -0.6ex; + font-style: italic; +} +.summation .summation-symbol { + font-size: 2em; +} +p sup { + vertical-align: baseline; + position: relative; + bottom: .5em; + font-size: small; +} +p sub { + vertical-align: baseline; + position: relative; + bottom: -.5em; + font-size: small; +} +.footnote { + font-size: medium; + text-indent: 1em; + text-align: justify; + margin-top: .5em; +} +.image-right { + float: right; + margin-left: 1em; + margin-top: 1em; + margin-bottom: 1em; +} +.image-caption { + font-size: small; + text-align: center; +} \ No newline at end of file diff --git a/versions/pcx86/1.24.2/document.xsl b/versions/pcx86/1.24.2/document.xsl new file mode 100644 index 000000000..e71127dc4 --- /dev/null +++ b/versions/pcx86/1.24.2/document.xsl @@ -0,0 +1,452 @@ + + + + + +]> + + + + + + + + + +

    +
    + + + + + + + +

    +
    + +

    +
    +
    +
    + + + + + + +
    +
    + + +
    + +   + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + +

    +
    + + +

    +
    + + +

    +
    + + +
    +
    + + +
    +
    + + + + + + + + + + + + + + +
    +
    + + +
    +
    + + +
  • +
    + + +
    image
    +
    + + +
    +
    + + + + +
    {.}
    +
    + +
    {.}
    +
    +
    +
    + + + + + + + + + + < + > + + + + × + + ÷ + σ + + + + + + + + + + + + { + + + + + + + + + + [] + + + + +
    + +
    +
    + + + , and + + + + + MDY + + + + + + + + + + + + + + + + + + + + January + February + March + April + May + June + July + August + September + October + November + December + + + , + + + + + +

    + +
    +
    + + +
    + {.}
    +
    +
    +
    + + + +

    Timeline

    +
    + +

    +
    +
    + +
    +
    + + + + + + + + + +

    +
    + +
    +
    +
    + + + +

    People

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + +

    +
      + +
    +
    + + + + + + + + + + +
  • + +
  • +
    + + + +

    +
    +

    + +

    +
    +
    + + + + false + + + + + + [Original] + + + + + + + + + + [] + + +
    by
    + + +
    + [Source: + + + + + + + ] +
    +
    +
    + + + +

    Resources

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + + +

    +
    +
      + +
    +
    + + +
  • +
    + + + +

    +
    +
    + +
    +
    + + + +

    +
    + +
    + + + +

    +
    +
      + +
    +
    + + + + + +
      + +
    +
    + + + + +
  • +
    + +
  • +
    + +
  • +
    +
    +
    + + +
  • +
    + + + + + + + + + + +
    + < ="" + + ></> + ></> + /> + +
    +
    + +
    diff --git a/versions/pcx86/1.24.2/machine.xsl b/versions/pcx86/1.24.2/machine.xsl new file mode 100644 index 000000000..fc02b5280 --- /dev/null +++ b/versions/pcx86/1.24.2/machine.xsl @@ -0,0 +1,49 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    +
    + + + + js + , + +
    +
    + +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pcx86/1.24.2/manifest.xsl b/versions/pcx86/1.24.2/manifest.xsl new file mode 100644 index 000000000..d2ecaf884 --- /dev/null +++ b/versions/pcx86/1.24.2/manifest.xsl @@ -0,0 +1,247 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Document Manifest

    +
    +
      + + + + None + + + + + + + + + + + + + + + + +
    +
    +
    +

    + +
    +
    +
    + + +
    + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Software Manifest

    +
    +
      + + + + None + + + + + Unknown + + + + + None + + + + + None + + + + + + + + + + + + + UpdatedReleased + + Unknown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +

    No default machine specified for '' in manifest.xml

    +
    + +
    +
    +
    + + + + -dbg + + + + + + +
    + + + + + Unknown + +
  • +
      + + + + + + + + +
    • + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
      • + + + + + + +
      • +
        +
      +
      +
    • +
      + + + + + + + + +
    +
  • +
    +
    + +
    diff --git a/versions/pcx86/1.24.2/outline.xsl b/versions/pcx86/1.24.2/outline.xsl new file mode 100644 index 000000000..acf4ec337 --- /dev/null +++ b/versions/pcx86/1.24.2/outline.xsl @@ -0,0 +1,47 @@ + + + + +]> + + + + + + + + + + + + + + + + + + <xsl:value-of select="title"/><xsl:text> | </xsl:text><xsl:value-of select="$SITEHOST"/> + + + + + +
    +
    + +
    +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pcx86/1.24.2/pcx86-dbg.js b/versions/pcx86/1.24.2/pcx86-dbg.js new file mode 100644 index 000000000..10e9f3ca6 --- /dev/null +++ b/versions/pcx86/1.24.2/pcx86-dbg.js @@ -0,0 +1,819 @@ +(function(){var m,aa,ba={163840:[40,1,8],184320:[40,1,9],327680:[40,2,8],368640:[40,2,9],737280:[80,2,9],1228800:[80,2,15],1474560:[80,2,18],2949120:[80,2,36],21368320:[615,4,17]}; +function ca(a,b){var c;if(a){b||(b=16);if("$"==a.charAt(0))b=16,a=a.substr(1);else if("0x"==a.substr(0,2))b=16,a=a.substr(2);else{var d=a.charAt(a.length-1).toLowerCase();"h"==d?(b=16,d=null):"."==d&&(b=10,d=null);null==d&&(a=a.substr(0,a.length-1))}var e,d=a,f=b;(f&&10!=f?16==f?null!==d.match(/^[0-9a-f]+$/i):2==f&&null!==d.match(/^[01]+$/i):null!==d.match(/^[0-9]+$/))&&!isNaN(e=parseInt(a,b))&&(c=e|0)}return c} +function da(a,b){var c="";void 0===b?b=32:32>=1;return c}function ea(a,b){var c="";if(!b||4>=8;return c}function r(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function t(a){return"0x"+r(a,2)} +function u(a){return"0x"+r(a,4)}function fa(a,b){var c=a,d=a.lastIndexOf("/");0<=d&&(c=a.substr(d+1));d=c.indexOf("&");0":">",'"':""","'":"'"};function la(a){return a.replace(/[&<>"']/g,function(a){return ka[a]})} +function ma(a,b,c){return c?(" "+a).slice(-b):(a+" ").slice(0,b)}function na(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")}var oa={0:"NUL",1:"SOH",2:"STX",3:"ETX",4:"EOT",5:"ENQ",6:"ACK",7:"BEL",8:"BS",9:"TAB",11:"VT",12:"FF",13:"CR",14:"SO",15:"SI",16:"DLE",17:"XON",18:"DC2",19:"XOFF",20:"DC4",21:"NAK",22:"SYN",23:"ETB",24:"CAN",25:"EM",26:"SUB",27:"ESC",28:"FS",29:"GS",30:"RS",31:"US"}; +function pa(a,b,c){var d=0,e=a.length,f=0;for(void 0===c&&(c=function(a,b){return a>b?1:a>1,h;h=c(b,a[g]);0a?"0":"")+a}var b=new Date;return b.getFullYear()+"-"+a(b.getMonth()+1)+"-"+a(b.getDate())+" "+a(b.getHours())+":"+a(b.getMinutes())+":"+a(b.getSeconds())}var sa=[31,28,31,30,31,30,31,31,30,31,30,31]; +function ta(a,b){var c=0,d=1,e;for(e in a){if(d>=arguments.length)break;var f=a[e],g=arguments[d++],c=c&~f.oh|g<>a.shift}function va(a,b){var c;if(Array.prototype.indexOf)return a.indexOf(b,c);c=c||0;0>c&&(c+=a.length);0>c&&(c=0);for(var d=a.length;cb?this.zd=this.id:(this.fe=this.id.substr(0,b),this.zd=this.id.substr(b+1));this[a]=c;this.la={bf:!1,bd:!1,dh:!1,cc:!1,ud:!1};this.ug=null;this.la.ud=!1;this.qa={};this.ha=null;this.wc=d||0;Ya.push(this)}var Za=void 0,$a={}; +if(window){Za||(Za=window.location.search.substr(1));for(var ab,cb=/\+/g,db=/([^&=]+)=?([^&]*)/g;ab=db.exec(Za);)$a[decodeURIComponent(ab[1].replace(cb," "))]=decodeURIComponent(ab[2].replace(cb," "))}function eb(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b} +function fb(a,b){b||(b=Wa);a.prototype=eb(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var gb=window.PCjs.Machines||(window.PCjs.Machines={}),Ya=window.PCjs.Components||(window.PCjs.Components=[])}else gb={},Ya=[];function hb(a,b,c){gb[a]&&b&&(gb[a][b]=c)}function ib(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b=this.x&&a=this.y&&b=c>>2);d?(b=new Fb(a.x,a.y,a.ad,a.A*b/c|0),a.y+=b.A,a.A-=b.A):(b=new Fb(a.x,a.y,a.ad*b/c|0,a.A),a.x+=b.ad,a.ad-=b.ad);return b}m=Cb.prototype;m.Pb=function(a,b,c,d){return this.X&&this.X.Pb(a,b,c,d)||this.F&&this.F.Pb(a,b,c,d)||this.B&&this.B.Pb(a,b,c,d)||this.ha&&this.ha.Pb(a,b,c,d)?!0:this.parent.Pb.call(this,a,b,c,d)}; +m.Ic=function(a,b,c,d){this.X=a;this.ga=b;this.F=c;this.ha=d;this.B=Hb(a,"Keyboard")};m.ic=function(a,b){b||Ib();return!0};m.hc=function(){return!0};m.ke=function(a,b){a.button||(this.ea=b?0:-1,Jb(this,a,b))};m.If=function(a){Jb(this,a)}; +function Jb(a,b,c){var d=1280/null.offsetWidth,e=720/null.offsetHeight,f=null.getBoundingClientRect(),d=(b.clientX-f.left)*d|0;b=(b.clientY-f.top)*e|0;null==c&&(a.ea||(a.ea=Math.abs(a.L-d)>Math.abs(a.V-b)?1:2),1==a.ea?b=a.V:2==a.ea&&(d=a.L));a.L=d;a.V=b;if(0<=d&&1280>d&&0<=b&&720>b){a:{c=d;if(960>c&&a.A&&a.A.Qe)for(f=0;fd&&(f=d);c=f;break a}c=-1}if(-1!==c&&(c&=-16,c!=a.Ca)){b=c;if(a.context&&a.ia&&a.ka){e=a.ia.width;a.ka.fillStyle="black";a.ka.fillRect(0,360,e,360);Lb(a,378,a.ia,a.ka);a.pa=a.Da.width/24|0;if(null==b)Mb(a,"Mouse over memory to dump");else for(Mb(a,"0x"+r(b),null,0,1),f=1;16>=f;f++){d="";for(g=1;8>=g;g++){var h;h=a.ga;var k=b++;h=h.sa[(k&h.Hb)>>>h.La].te(k&h.A,k);Mb(a,r(h,2),null,1);d+=32<=h&&128>h?String.fromCharCode(h):"."}Mb(a,d,null,0,1)}a.context.drawImage(a.ia,0,360,e,360,a.rb,a.Db,a.Pa,a.cb)}a.Ca= +c}}}m.qd=function(){};function Nb(a,b,c,d){a.A.Bf[a.A.Ci++]={Tk:b,Vd:c,type:d};return ta(Kb,b,c,0,d)}function Lb(a,b,c,d){var e,f=null.style.color,g=a.Oa=10;a.C=g;a.U=b;a.W=a.wa=18;e||(e=a.ua||a.wa+"px Monaco, Lucida Console, Courier New");a.fa=a.ua=e;c&&(a.Da=c);d&&(a.N=d,a.Fa=f||"white")} +function Mb(a,b,c,d,e){a.N.font=a.fa;a.N.fillStyle=a.Fa;a.N.fillText(b,a.C,a.U);a.C+=a.pa;null!=c&&(16!=a.Tb?b=c.toString():(b=8>a.Ka?"0x":"",b+=r(c,a.Ka)),a.N.fillText(b,a.C,a.U),a.C+=a.pa);d&&(a.C+=a.pa*d);e&&(a.C=a.Oa,a.U+=(a.W+2)*(e||1))}function Ib(){for(var a=!1,b=pb(document,"pcx86","panel"),c=0;c=this.N?12:24>=this.N?14:15;this.Sb=1<>2;this.A=this.Sb-1;this.U=this.W/this.Sb|0;this.ga=this.U-1;this.B=[];this.C=[];this.L=this.V=!1;this.aa=[];this.ea=[];a=new B;Pb(a,this.ha);this.sa=Array(this.U);for(b=0;b>>a.La;0g&&(n=g);if(k&&k.size){if(k.type==d&&k.controller==e){if(f+g<=k.Ea)return k.Oe+=k.Ea-f,k.Ea=f,!0;if(f>=k.Ea+k.Oe){n=k.size-(f-l);n>g&&(n=g);k.Oe=f-k.Ea+n;f=l+a.Sb;g-=n;h++;continue}}return Xb(a,1,f,g)}f=new B(f,n,a.Sb,d,e);Pb(f,a.ha,k);a.sa[h++]=f;f=l+a.Sb;g-=n}return 0>=g?(Yb(a.F),a.F.la.Fb||a.status(Math.floor(c/1024)+"Kb "+Zb[d]+" at "+r(b)),!0):Xb(a,2,b,c)} +function Ub(a,b){if(32==a.N)b?a.X&&($b(a,1048576,1048576,a.X),a.X=null):a.X||(a.X=ac(a,1048576,1048576),$b(a,1048576,1048576,ac(a,0,1048576)));else if(20>>this.La;0>>a.La;0>>=a.La;0>>a.La;0>>this.La].pc(a&this.A,a)}; +m.na=function(a){var b=a&this.A,c=(a&this.Hb)>>>this.La;return b!=this.A?this.sa[c].sf(b,a):this.sa[c++].pc(b,a)|this.sa[c&this.ga].pc(0,a+1)<<8};function ic(a,b){var c=b&a.A,d=(b&a.Hb)>>>a.La;return c!=a.A?a.sa[d].dg(c,b):a.sa[d++].te(c,b)|a.sa[d&a.ga].te(0,b+1)<<8}m.oa=function(a){var b=a&this.A,c=(a&this.Hb)>>>this.La;if(b>>this.La].sc(a&this.A,b&255,a)};m.jb=function(a,b){var c=a&this.A,d=(a&this.Hb)>>>this.La;c!=this.A?this.sa[d].zf(c,b&65535,a):(this.sa[d++].sc(c,b&255,a),this.sa[d&this.ga].sc(0,b>>8&255,a+1))};function jc(a,b,c){var d=b&a.A,e=(b&a.Hb)>>>a.La;d!=a.A?a.sa[e].ri(d,c&65535,b):(a.sa[e++].xf(d,c&255,b),a.sa[e&a.ga].xf(0,c>>8&255,b+1))} +m.nb=function(a,b){var c=a&this.A,d=(a&this.Hb)>>>this.La;if(c>>=8};m.Ui=function(){return null};function kc(a,b){if(void 0===b)return a.L=!a.L,a.L;void 0===a.B[b]&&(a.B[b]=[null,!1]);a.B[b][1]=!a.B[b][1];return a.B[b][1]} +function lc(a,b,c,d){void 0===d&&(d=0);for(var e in c){var f=a,g=+e+d,h=c[e].bind(b);if(void 0!==h)for(var k=+e+d;k<=g;k++)void 0!==f.B[k]?w("Input port "+u(k)+" already registered"):f.B[k]=[h,!1]}}function mc(a,b,c,d){for(var e=0,f=0;0>>=f)&k;if(void 0!==g){if(g[0])g[0](b,k,e);a.ha&&a.V!=g[1]&&rc(a.ha,b,k)}else a.ha&&(qb(a.ha,a,b,k,e),a.V&&rc(a.ha,b,k));f+=h<<3;b+=h;c-=h}}function Xb(a,b,c,d,e){b="Memory block error ("+b+": "+r(c)+","+r(d)+")";e?a.ha?a.ha.message(b):a.log(b):w(b);return!1}var sc;if(xb){var xc=new ArrayBuffer(2);(new DataView(xc)).setUint16(0,256,!0);sc=256===(new Uint16Array(xc))[0]}else sc=!1;var ec=sc; +function B(a,b,c,d,e,f){this.id=yc+=2;this.da=null;this.C=0;this.Ea=a;this.Oe=b;this.size=c||0;this.type=d||zc;this.N=d==dc;this.controller=null;this.F=f;Pb(this);this.Wa=this.Pi=!1;if(c)if(e)this.controller=e,a=e.Ti(a),this.da=a[0],this.C=a[1],bc(this,e.ih());else if(xb)this.X=new ArrayBuffer(c),this.qa=new DataView(this.X,0,c),this.Ya=new Uint8Array(this.X,0,c),this.ge=new Uint16Array(this.X,0,c>>1),this.da=new Int32Array(this.X,0,c>>2),bc(this,ec?fc:gc);else{this.da=Array(c>>2);for(e=0;e>8&65280|a>>>24);return a} +B.prototype={constructor:B,parent:null,jh:function(a){this.Ea=a},save:function(){var a,b;if(this.controller)a=null;else if(xb)for(a=Array(this.size>>2),b=0;b>8,c)},U:function(a,b, +c){this.sc(a++,b&255,c++);this.sc(a++,b>>8&255,c++);this.sc(a++,b>>16&255,c++);this.sc(a,b>>>24,c)},Fa:function(a){return this.da[a>>2]>>>((a&3)<<3)&255},sb:function(a){var b=a>>2;a=(a&3)<<3;var c=this.da[b]>>a;return 24>a?c&65535:c&255|(this.da[b+1]&255)<<8},$a:function(a){var b=a>>2;a=(a&3)<<3;var c=this.da[b];a&&(c=c>>>a|this.da[b+1]<<32-a);return c},tc:function(a,b){var c=a>>2,d=(a&3)<<3;this.da[c]=this.da[c]&~(255<>2,d=(a&3)<<3;24>d?this.da[c]=this.da[c]& +~(65535<>8);this.Wa=!0},Wc:function(a,b){var c=a>>2,d=(a&3)<<3;if(d){var e=-1<>>32-d}else this.da[c]=b;this.Wa=!0},Da:function(a,b){this.ha&&null!=this.Ea&&Fc(this.ha,this.Ea+a)||this.F&&Gc(this.F,b,1,!1);return this.te(a,b)},rb:function(a,b){this.ha&&null!=this.Ea&&Fc(this.ha,this.Ea+a,2)||this.F&&Gc(this.F,b,2,!1);return this.dg(a,b)},Pa:function(a,b){this.ha&& +null!=this.Ea&&Fc(this.ha,this.Ea+a,4)||this.F&&Gc(this.F,b,4,!1);return this.ki(a,b)},bc:function(a,b,c){this.ha&&null!=this.Ea&&Hc(this.ha,this.Ea+a)||this.F&&Gc(this.F,c,1,!0);this.N?this.L(a,b,c):this.xf(a,b,c)},td:function(a,b,c){this.ha&&null!=this.Ea&&Hc(this.ha,this.Ea+a,2)||this.F&&Gc(this.F,c,2,!0);this.N?this.L(a,b,c):this.ri(a,b,c)},Vc:function(a,b,c){this.ha&&null!=this.Ea&&Hc(this.ha,this.Ea+a,4)||this.F&&Gc(this.F,c,4,!0);this.N?this.L(a,b,c):this.ua(a,b,c)},Ja:function(a,b){this.yb.da[this.A]|= +this.ga;this.zb.da[this.B]|=this.ga;return this.Dd.pc(a,b)},Jb:function(a,b){this.yb.da[this.A]|=this.ga;this.zb.da[this.B]|=this.ga;return this.Dd.sf(a,b)},fb:function(a,b){this.yb.da[this.A]|=this.ga;this.zb.da[this.B]|=this.ga;return this.Dd.Od(a,b)},Cc:function(a,b,c){this.yb.da[this.A]|=this.ga;this.zb.da[this.B]|=this.V;this.Dd.sc(a,b,c)},Id:function(a,b,c){this.yb.da[this.A]|=this.ga;this.zb.da[this.B]|=this.V;this.Dd.zf(a,b,c)},jd:function(a,b,c){this.yb.da[this.A]|=this.ga;this.zb.da[this.B]|= +this.V;this.Dd.yf(a,b,c)},Ka:function(a,b){return Ic(this.F,b,!1).pc(a,b)},zd:function(a,b){return Ic(this.F,b,!1).sf(a,b)},gb:function(a,b){return Ic(this.F,b,!1).Od(a,b)},Uc:function(a,b,c){Ic(this.F,c,!0).sc(a,b,c)},Jd:function(a,b,c){Ic(this.F,c,!0).zf(a,b,c)},kd:function(a,b,c){Ic(this.F,c,!0).yf(a,b,c)},Ca:function(a){return this.Ya[a]},aa:function(a){return this.Ya[a]},Ga:function(a){this.yb.da[this.A]|=32;this.zb.da[this.B]|=32;this.pc=this.aa;return this.Ya[a]},Tb:function(a){return this.qa.getUint16(a, +!0)},pa:function(a){return a&1?this.Ya[a]|this.Ya[a+1]<<8:this.ge[a>>1]},Db:function(a){this.yb.da[this.A]|=32;this.zb.da[this.B]|=32;this.sf=this.pa;return a&1?this.Ya[a]|this.Ya[a+1]<<8:this.ge[a>>1]},Oa:function(a){return this.qa.getInt32(a,!0)},fa:function(a){return a&3?this.Ya[a]|this.Ya[a+1]<<8|this.Ya[a+2]<<16|this.Ya[a+3]<<24:this.da[a>>2]},cb:function(a){this.yb.da[this.A]|=32;this.zb.da[this.B]|=32;this.Od=this.fa;return a&3?this.Ya[a]|this.Ya[a+1]<<8|this.Ya[a+2]<<16|this.Ya[a+3]<<24:this.da[a>> +2]},Ub:function(a,b){this.Ya[a]=b;this.Wa=!0},ra:function(a,b){this.Ya[a]=b;this.Wa=!0},uc:function(a,b){this.Ya[a]=b;this.yb.da[this.A]|=32;this.zb.da[this.B]|=96;this.sc=this.ra;this.Dd.Wa=!0},rd:function(a,b){this.qa.setUint16(a,b,!0);this.Wa=!0},ya:function(a,b){a&1?(this.Ya[a]=b,this.Ya[a+1]=b>>8):this.ge[a>>1]=b;this.Wa=!0},Hd:function(a,b){a&1?(this.Ya[a]=b,this.Ya[a+1]=b>>8):this.ge[a>>1]=b;this.yb.da[this.A]|=32;this.zb.da[this.B]|=96;this.zf=this.ya;this.Dd.Wa=!0},fe:function(a,b){this.qa.setInt32(a, +b,!0);this.Wa=!0},wa:function(a,b){a&3?(this.Ya[a]=b,this.Ya[a+1]=b>>8,this.Ya[a+2]=b>>16,this.Ya[a+3]=b>>24):this.da[a>>2]=b;this.Wa=!0},Xc:function(a,b){a&3?(this.Ya[a]=b,this.Ya[a+1]=b>>8,this.Ya[a+2]=b>>16,this.Ya[a+3]=b>>24):this.da[a>>2]=b;this.yb.da[this.A]|=32;this.zb.da[this.B]|=96;this.yf=this.wa;this.Dd.Wa=!0}};function Pb(a,b,c){a.ha=b;a.Ue=a.Ve=0;c&&(c.F&&(a.F=c.F),(a.Ue=c.Ue)&&Cc(a,Dc,!1),(a.Ve=c.Ve)&&Ec(a,Dc,!1))} +function Jc(a,b){b?0===--a.Ve&&(a.sc=a.N?a.L:a.xf,a.zf=a.N?a.W:a.ri,a.yf=a.N?a.U:a.ua):0===--a.Ue&&(a.pc=a.te,a.sf=a.dg,a.Od=a.ki)}function Ec(a,b,c){c&&a.Ve||(a.sc=!a.N&&b[3]||a.L,a.zf=!a.N&&b[4]||a.W,a.yf=!a.N&&b[5]||a.U);if(c||void 0===c)a.xf=b[3]||a.L,a.ri=b[4]||a.W,a.ua=b[5]||a.U}function Cc(a,b,c){c&&a.Ue||(a.pc=b[0]||a.ia,a.sf=b[1]||a.ka,a.Od=b[2]||a.ea);if(c||void 0===c)a.te=b[0]||a.ia,a.dg=b[1]||a.ka,a.ki=b[2]||a.ea} +function bc(a,b,c){b||(b=5==a.type?Kc:6==a.type?Lc:Mc);Cc(a,b,c);Ec(a,b,c)}var Mc=[],hc=[B.prototype.Fa,B.prototype.sb,B.prototype.$a,B.prototype.tc,B.prototype.Ed,B.prototype.Wc],Dc=[B.prototype.Da,B.prototype.rb,B.prototype.Pa,B.prototype.bc,B.prototype.td,B.prototype.Vc],Lc=[B.prototype.Ja,B.prototype.Jb,B.prototype.fb,B.prototype.Cc,B.prototype.Id,B.prototype.jd],Kc=[B.prototype.Ka,B.prototype.zd,B.prototype.gb,B.prototype.Uc,B.prototype.Jd,B.prototype.kd]; +if(xb)var gc=[B.prototype.Ca,B.prototype.Tb,B.prototype.Oa,B.prototype.Ub,B.prototype.rd,B.prototype.fe],fc=[B.prototype.aa,B.prototype.pa,B.prototype.fa,B.prototype.ra,B.prototype.ya,B.prototype.wa],Nc=[B.prototype.Ga,B.prototype.Db,B.prototype.cb,B.prototype.uc,B.prototype.Hd,B.prototype.Xc]; +function Oc(a,b){Wa.call(this,"CPU",a,Oc,1);var c=a.cycles||b,d=a.multiplier||1;this.Y={};this.Y.Kd=c;this.Y.Zd=d;this.Y.wg=Math.round(this.Y.Kd/1E4)/100;this.Y.Fe=this.Y.wg*this.Y.Zd;this.la.Fb=!1;this.la.gh=!1;this.la.Mi=a.autoStart;this.la.Qi=!1;this.la.Ze=!1;this.Y.Jf=this.Y.lf=0;this.Y.Kf=a.csStart;this.Y.kf=a.csInterval;this.Y.mf=a.csStop;this.si=this.Le.bind(this);ub(this)}fb(Oc);var Pc=["power","reset"];m=Oc.prototype; +m.Ic=function(a,b,c,d){this.X=a;this.ga=b;this.ha=d;for(b=0;b=a.Y.lf&&(a.Y.lf+=a.Y.kf,c=!0);0<=a.Y.mf&&a.Y.mf<=Zc(a)&&(a.Y.kf=a.Y.mf=-1,Tc(a),a.Wb(),c=!0);c&&a.O(Zc(a)+" cycles: checksum="+r(a.Y.Jf))}} +m.Pb=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.qa[b]=c;a=!0;break;case "run":this.qa[b]=c;c.onclick=function(){var a;if(a=d.X)if(a=d.X,a.la.cc)a=!0;else{var b=null,c,h=ib(a.id);for(c=0;cc&&(c=60);2>c&&(c=2);var d=1;b&&1a.Y.wg&&(c=Math.round(c/a.Y.Zd));return c}function Rc(a){a.Y.qe=0;a.uc=a.Ub=a.fb=a.A=0;Tc(a);$c(a,1)} +function $c(a,b,c){var d=!1;if(void 0!==b){.8>a.Y.qe/a.Y.Fe?b=1:d=!0;a.Y.Zd=b;b=a.Y.wg*a.Y.Zd;if(a.Y.Fe!=b){a.Y.Fe=b;b=a.Y.Fe.toFixed(2)+"Mhz";var e=a.qa.setSpeed;e&&(e.textContent=b);a.O("target speed: "+b)}c&&a.X&&a.X.yd()}bd(a,a.Ub);a.Ub=0;a.Y.jf=qa();a.Y.Ge=0;cd(a);return d} +m.Le=function(a){if(rb(this,!0)){if(!this.la.Fb){$c(this);this.X&&this.X.start(this.Y.jf,Zc(this));this.la.Fb=!0;this.la.gh=!0;this.N&&this.N.start();var b=this.qa.run;b&&(b.textContent="Halt");this.X&&(this.X.qd(!0),a&&this.X.yd(!0))}this.Y.uh>=this.Y.Kd&&cd(this,!0);this.Y.Nf=0;this.Y.xg=qa();this.Y.Ge&&(a=this.Y.xg-this.Y.Ge,a>this.Y.$i&&(this.Y.jf+=a,this.Y.jf>this.Y.xg&&(this.Y.jf=this.Y.xg)));try{do{var c=this.la.Ze?1:this.Y.nm;if(this.N){dd(this.N);var d=this.N;a=c;var e=d.V[0];if(e.Be){var f= +(Zc(d.F,d.ka)-e.xd)/d.gb|0,g=ed(d,0)-f;6==e.mode&&(g-=f);var h=g*d.gb|0;6==e.mode&&(h>>=1);a>h&&(a=h)}var c=a,k=this.N;a=c;if(k.A&&k.A[11]&64){var l=k.ua-Zc(k.F,k.ka);0l&&(a=l)}c=a}try{this.wf(c)}catch(q){if("number"!=typeof q)throw q;}var n=this.fb-this.A;this.Ub+=n;this.Y.Nf+=n;bd(this,0,!0);Yc(this,n);this.Y.Mf-=n;0>=this.Y.Mf&&(this.Y.Mf+=this.Y.bj,this.X&&fd(this.X));this.Y.Lf-=n;0>=this.Y.Lf&&(this.Y.Lf+=this.Y.aj,this.X&&this.X.qd());this.Y.nf-=n;if(0>=this.Y.nf){this.Y.nf+=this.Y.th; +break}}while(this.la.Fb)}catch(q){this.Wb();Wc(this);this.X&&this.X.stop(qa(),Zc(this));rb(this,!1);wb(this,q.stack||q.message);return}c=setTimeout;d=this.si;this.Y.Ge=qa();e=this.Y.$i;this.Y.Nf&&(e=Math.round(e*this.Y.Nf/this.Y.th));e-=this.Y.Ge-this.Y.xg;if(f=this.Y.Ge-this.Y.jf)this.Y.qe=Math.round(this.Ub/(10*f))/100,864E5<=f&&(this.uc=0,this.N&&dd(this.N,!0),$c(this));if(0>e||this.Y.qethis.id&&C.call(e,b&&3==this.id?10:13,a&65532)}return-1};m.jm=function(a){var b=this.F;a=b.Mc+(a<<2);var c=b.na(a);b.ca&=-769;return this.load(b.na(a+2))+c|0}; +m.im=function(a){var b=this.F;a<<=3;var c=b.Mc+a|0;if(7<=(b.Ud-c|0))return this.C=!0,a=jd(this,c,a),-1!==a&&(a+=this.Yf),a;C.call(b,13,a|2);return-1};m.Fi=function(a){return this.Aa+a|0};m.Hi=function(a){return this.Aa+a|0};m.Ei=function(a,b){return(a>>>0)+b<=this.Zb?this.Aa+a|0:this.qg()};m.Lk=function(a,b){return(a>>>0)+b>this.Zb?this.Aa+a|0:this.qg()};m.qg=function(){C.call(this.F,13,0);return-1};m.Gi=function(a,b){return(a>>>0)+b<=this.Zb?this.Aa+a|0:this.rg()}; +m.Mk=function(a,b){return(a>>>0)+b>this.Zb?this.Aa+a|0:this.rg()};m.rg=function(){C.call(this.F,13,0);return-1};function kd(a,b,c,d,e){a.Z=b;a.Aa=d;a.Ta=e;a.Zb=(e>>>0)+1;a.wb=c;a.type=c&7936;a.ext=c>>16&192;a.Xb=(b&4?a.F.Bc.Aa:a.F.Ec)+(b&65528)|0;4>a.id&&hd(a,!0)}function ld(a,b,c){var d=a.F,e=d.na(b+2),f=d.na(b)|(e&255)<<16,d=d.na(b+4);a.Z=c;a.Aa=f;a.Ta=d;a.Zb=(d>>>0)+1;a.wb=e;a.type=e&7936;a.ext=0;a.Xb=b;4>a.id&&hd(a,!0)} +function jd(a,b,c,d){var e=a.F;if(!d&&c===a.A.Z)return a.Z=c,a.Aa=a.A.Aa,a.Ta=a.A.Ta,a.Zb=(a.A.Ta>>>0)+1,a.wb=a.A.wb,a.type=a.A.type,a.ext=a.A.ext,a.Xb=a.A.Xb,a.A.Z=-1,hd(a,!0,!0,!1),a.Aa;a.A.Z=-1;var f=e.na(b+0),g=e.na(b+4),h=g&7936,k=e.na(b+2)|(g&255)<<16,l=e.na(b+6),n=c&65528;if(80386<=e.ja){var q=f,k=k|(l&65280)<<16,f=f|(l&15)<<16;l&128&&(f=f<<12|4095)}switch(a.id){case 1:var p=a.C;a.df=!1;if(p&&1==c&&a.B.length){var z=a.B[a.Yf-1];if(z&&!z())return-1}var F=c&3,v=(g&24576)>>13,z=-1,E,H;n||b>=e.Ec&& +b=a.Lb&&(F>a.Lb&&(z=D(e),md(e,D(e),!0),G(e,z),a.df=!0),z=0);else{if(256==h||2304==h)return nd(a,c,p)?a.Aa:-1;if(1024==h)z=2,H=0,Fh||2048==(h&2560))return C.call(e,13,c&65532),-1;if(!(g&32768))return C.call(e,11,c&65532),-1}break;case 3:if(!n||4096>h||512!=(h&2560))return C.call(e,13,c&65532),-1;if(!(g&32768))return C.call(e,12,c&65532),-1; +break;case 4:p=h&-513;if(!n||256!=p&&2304!=p)return C.call(e,13,c&65532),-1;2304==p&&(a.vi=k+e.na(k+100+2)|0,a.Hk=k+a.Ta|0);break;case 6:if(!(h&4096)&&768>>0)+1,a.wb=g,a.type=h,a.ext=l,a.Xb=b,hd(a,!0,!0,!1));return k} +function nd(a,b,c){var d=a.F,e=a.Lb,f=d.Sa.Z,g=d.Sa.Aa;if(!c){if(!(d.Sa.type&512))return C.call(d,13,b&65532),!1;d.jb(d.Sa.Xb+4,d.Sa.wb&=-513)}if(-1===d.Sa.load(b))return!1;var h=d.Sa.Aa;if(!1!==c){if(d.Sa.type&512)return C.call(d,13,b&65532),!1;d.jb(d.Sa.Xb+4,d.Sa.wb|=512)}d.Sa.type=d.Sa.type&-513|d.Sa.wb&512;256==d.Sa.type||768==d.Sa.type?(d.jb(g+14,K(d)),d.jb(g+16,zd(d)),d.jb(g+18,d.G),d.jb(g+20,d.I),d.jb(g+22,d.M),d.jb(g+24,d.H),d.jb(g+26,I(d)),d.jb(g+28,d.P),d.jb(g+30,d.K),d.jb(g+32,d.J),d.jb(g+ +34,d.Xa.Z),d.jb(g+36,d.va.Z),d.jb(g+38,d.ta.Z),d.jb(g+40,d.vb.Z),d.Bc.load(d.na(h+42)),Ad(d,d.na(h+16)|(c?16384:0)),d.G=d.na(h+18),d.I=d.na(h+20),d.M=d.na(h+22),d.H=d.na(h+24),d.P=d.na(h+28),d.K=d.na(h+30),d.J=d.na(h+32),d.Xa.load(d.na(h+34)),d.vb.load(d.na(h+40)),Bd(d,d.na(h+14),d.na(h+36)),b=38,g=26,a.Lb>>0)+1)}; +function hd(a,b,c,d){void 0===c&&(c=!!(a.F.Za&1));a.cd=!1;if(c)if(a.load=a.vg,a.Zi=a.im,a.mc=a.Ei,a.nc=a.Gi,void 0===d&&(d=!!(a.F.ca&131072)),d)a.load=a.X,a.mc=a.ga,a.nc=a.qa,a.Lb=a.Gc=3,a.ba=a.Oc=2,a.R=a.Ba=65535,a.Ta=65535,a.Zb=a.Ta+1,a.Oc=a.ba,a.Xb=-1,a.df=!1;else{if(!(a.Z&-4))a.mc=a.qg,a.nc=a.rg;else if(a.type&4096){6144==(a.type&6656)&&(a.mc=a.qg);if(a.type&2048||!(a.type&512))a.nc=a.rg;1024==(a.type&3072)&&(a.mc==a.Ei&&(a.mc=a.Lk),a.nc==a.Gi&&(a.nc=a.Mk),a.cd=!0);b&&6>a.id&&a.Z&-4&&-1!==a.Xb&& +(c=a.Xb+5,d=a.F.Qa(c),d&1||a.F.qc(c,d|1))}b&&(a.Lb=a.Z&3,a.Gc=(a.wb&24576)>>13,80386>a.F.ja||!(a.ext&64)?(a.ba=2,a.R=65535):(a.ba=4,a.R=-1),a.Oc=a.ba,a.Ba=a.R)}else a.load=a.nh,a.Zi=a.jm,a.mc=a.Fi,a.nc=a.Hi,a.Lb=a.Gc=0,a.Xb=-1,a.df=!1} +function Dd(a){this.ja=+a.model||8088;var b=a.stepping;this.Uc=this.ja+(b?ca(b,16):0);b=0;switch(this.ja){default:b=4772727;break;case 80286:b=6E6;break;case 80386:b=16E6}Oc.call(this,a,b);this.Zf=61442;this.Cc=1792;this.Xf=28672;this.Ed=4;this.ra=255;this.B=80286<=this.ja?zb:yb;this.W=Ed;this.cg=Fd;this.ig=Gd;this.jg=Hd;if(80186<=this.ja&&(this.W=Ed.slice(),this.cg=Fd.slice(),this.ig=Gd.slice(),this.ra=31,this.W[15]=Id,this.W[96]=Jd,this.W[97]=Kd,this.W[98]=Ld,this.W[99]=Id,this.W[100]=Id,this.W[101]= +Id,this.W[102]=Id,this.W[103]=Id,this.W[104]=Md,this.W[105]=Nd,this.W[106]=Od,this.W[107]=Pd,this.W[108]=Qd,this.W[109]=Rd,this.W[110]=Sd,this.W[111]=Td,this.W[192]=Ud,this.W[193]=Yd,this.W[200]=Zd,this.W[201]=$d,this.W[241]=ae,this.cg[7]=ge,this.ig[7]=ge,80286<=this.ja)){this.Zf=2;this.Cc|=28672;this.Ed=0;this.W[15]=he;this.tc=ie.slice();for(a=0;a=this.Uc&&(this.tc[166]=qe,this.tc[167]=re)}}this.Jd=[];this.me=[];this.oe=0;Rc(this);this.la.Xd=this.la.Oi=!1;this.Rg=0;this.ld=this.sa=[];this.La=this.Sb=this.Fa=this.Hd=this.jd=this.Hb=this.Db=0;se(this)}fb(Dd,Oc);function te(a,b,c,d){Jc((d?a.ld:a.sa)[b>>>a.La],c);d&&Yb(a)} +function ue(a){var b;if(a.sa===a.ld){a.sa=Array(a.Hd);a.ne=new B(null,0,0,5,null,a);Pb(a.ne,a.ha);for(b=0;ba.pe&&(a.bg[a.pe++]=d);a.sa[b]=a.ne}a.Id=[]}function Yb(a){a.Za&-2147483648&&ue(a)} +function Ic(a,b,c,d){var e=(b&-4194304)>>>20,f=a.ld[(a.Qd+e&a.Hb)>>>a.La],g=f.Od(e);if(!(g&1))return d||ve.call(a,b,!1,c),a.kd;if(!(g&4)&&3==a.pa)return d||ve.call(a,b,!0,c),a.kd;var h=(b&4190208)>>>10,g=a.ld[((g&-4096)+h&a.Hb)>>>a.La],k=g.Od(h);if(!(k&1))return d||ve.call(a,b,!1,c),a.kd;if(!(k&4)&&3==a.pa)return d||ve.call(a,b,!0,c),a.kd;c=a.ld[((k&-4096)+(b&4095)&a.Hb)>>>a.La];if(d)return c;d=b>>>a.La;k=a.sa[d];b=b&-4096;var l;0>2;b.zb=g;b.B=h>>2;xb&&ec&&c.da&&!c.controller&&!c.Ue&&!c.Ve?(b.Ya=c.Ya,b.ge=c.ge,b.da=c.da,bc(b,Nc)):(b.ga=c?Bc(32):0,b.V=c?Bc(96):0,bc(b,Lc));Pb(b,a.ha,k);a.sa[d]=b;a.Id.push(d);return b}function we(a){a.sa!==a.ld&&(a.sa=a.ld,a.ne=null,a.Id=null,a.kd=null)}m=Dd.prototype;m.reset=function(){this.la.Fb&&this.Wb();se(this);Rc(this);this.la.ud=!1}; +function xe(a,b){var c;switch(b){case 0:c=a.G;break;case 1:c=a.I;break;case 2:c=a.M;break;case 3:c=a.H;break;case 4:c=I(a);break;case 5:c=a.P;break;case 6:c=a.K;break;case 7:c=a.J}return c}function ye(a,b,c){switch(b){case 0:a.G=c;break;case 1:a.I=c;break;case 2:a.M=c;break;case 3:a.H=c;break;case 4:G(a,c);break;case 5:a.P=c;break;case 6:a.K=c;break;case 7:a.J=c}} +function se(a){a.G=0;a.H=0;a.I=0;a.M=0;a.gb=0;a.P=0;a.K=0;a.J=0;a.cb=!1;a.ia=a.wa=0;a.aa=0;a.kg=0;a.L=0;a.Za=65520;a.Mc=0;a.Ud=1023;a.ca=a.Pa=0;a.Wc=a.td=a.Vc=a.Xc=0;a.rb=-1;a.bc=a.sb=-1;a.se=a.U=-1;a.va=new gd(a,1,"CS");a.vb=new gd(a,2,"DS");a.Xa=new gd(a,2,"ES");a.ta=new gd(a,3,"SS");G(a,0);md(a,0);if(80386<=a.ja){switch(a.Uc){case 80562:case 80563:a.M=771;break;case 80578:a.M=772;break;case 80594:a.M=773;break;case 80595:case 80596:a.M=776}a.Za=16;a.li=0;a.ue=0;a.Qd=0;a.Ja=[0,0,0,0,null,null,0, +0];a.Ce=[null,null,null,null,null,null,0,0];a.Nb=new gd(a,2,"FS");a.Ob=new gd(a,2,"GS");we(a)}a.rf=new gd(a,0,"NULL");a.ka=a.vb;a.Ka=a.ta;a.S=a.Ia=0;a.D=a.C=-1;a.$b=a.rf;a.ua=0;if(80286>a.ja)Bd(a,0,65535);else{a.Ec=0;a.Bd=65535;a.Bc=new gd(a,5,"LDT",!0);a.Sa=new gd(a,4,"TSS",!0);a.Da=new gd(a,6,"VER",!0);Bd(a,65520,61440);var b,c=K(a);b=a.va;var d=-65536;80386>b.F.ja&&(d&=16777215);b=b.Aa=d;a.Ha=b+c|0;a.hf=(b>>>0)+(a.va.Ta>>>0)+1}Ad(a,0);od(a)} +function ze(a){2==a.Oc?(a.dc=a.na,a.Oa=Ae,a.$a=Be,a.Jb=Ce,2==a.ba?(a.V=De,a.ea=Ee,a.ya=Fe):(a.V=Ge,a.ea=He,a.ya=Ie)):(a.dc=a.oa,a.Oa=Le,a.$a=Me,a.Jb=Ne,2==a.ba?(a.V=Oe,a.ea=Pe,a.ya=Qe):(a.V=Re,a.ea=Se,a.ya=Te))}function ud(a,b){a.ba!=b&&(a.Ia|=1024,a.ba=b,a.R=2==b?65535:-1,df(a))}function df(a){2==a.ba?(a.Ga=32768,a.tb=a.na,a.rc=a.jb,2==a.Oc?(a.V=De,a.ea=Ee,a.ya=Fe):(a.V=Oe,a.ea=Pe,a.ya=Qe)):(a.Ga=-2147483648,a.tb=a.oa,a.rc=a.nb,2==a.Oc?(a.V=Ge,a.ea=He,a.ya=Ie):(a.V=Re,a.ea=Se,a.ya=Te))} +function ef(a){a.Oc=a.va.Oc;a.Ba=a.va.Ba;ze(a);a.ba=a.va.ba;a.R=a.va.R;df(a);a.Ia&=-3073}m.Si=function(){var a=this.G+this.H+this.I+this.M+I(this)+this.P+this.K+this.J|0;return a=a+K(this)+this.va.Z+this.vb.Z+this.ta.Z+this.Xa.Z+zd(this)|0};function ff(a,b,c){void 0===a.Jd[b]&&(a.Jd[b]=[]);a.Jd[b].push(c)}function gf(a,b,c){void 0!==c&&(null==a.me[b]&&a.oe++,a.me[b]=c)}function hf(a,b){var c=a.me[b];null!=c&&(c(--a.oe),delete a.me[b])} +function jf(a,b){for(var c=a.Ja[7],d=c>>16,e=0;4>e;e++){if(c&3){var f=!!(d&1),g=a.Ja[e],g=g&~(d>>2&3);b?a.sa[g>>>a.La].Td(g&a.Fa,f,a):Jc(a.sa[g>>>a.La],f)}c>>=2;d>>=4}}function Gc(a,b,c,d){if(!(a.S&8192)&&a.Ja[7]&255){c--;var e=a.Ja[7],f=e>>16;d=d?1:0==d?3:0;for(var g=0;4>g;g++){if(e&3&&(f&3)==d){var h=f>>2;if(b+c>=a.Ja[g]&&b<=a.Ja[g]+h){a.Ja[6]|=1<>=2;f>>=4}}} +function od(a,b,c){void 0===b&&(b=!!(a.Za&1));void 0===c&&(c=!!(a.ca&131072));a.jg=b&&!c?kf:Hd;hd(a.va,!1,b,c);hd(a.vb,!1,b,c);hd(a.ta,!1,b,c);hd(a.Xa,!1,b,c);80386<=a.ja&&(hd(a.Nb,!1,b,c),hd(a.Ob,!1,b,c));ef(a)} +m.save=function(){var a=new lf(this);N(a,0,[this.G,this.H,this.I,this.M,I(this),this.P,this.K,this.J]);var b=K(this),c=this.va.save(),d=this.vb.save(),e=this.ta.save(),f=this.Xa.save(),g;null!=this.Ec?(g=[this.Za,this.Ec,this.Bd,this.Mc,this.Ud,this.Bc.save(),this.Sa.save(),this.Pa],80386<=this.ja&&(g.push(this.li),g.push(this.ue),g.push(this.Qd),g.push(this.Ja),g.push(this.Ce))):g=null;b=[b,c,d,e,f,g,zd(this)];80386<=this.ja&&(b.push(this.Nb.save()),b.push(this.Ob.save()));N(a,1,b);N(a,2,[this.ka.kc, +this.Ka.kc,this.S,this.Ia,this.ua,this.D,this.C]);N(a,3,[0,this.uc,this.Y.Zd]);b=this.ga;c=!!(this.Za&-2147483648);d=0;e=[];(f=!b.X&&b.zg==b.Hb)||Ub(b,!0);for(g=0;g>>0)+(a.va.Ta>>>0)+1;a.pa=a.va.Lb;ef(a)}function Bd(a,b,c,d){var e=a.va;e.Yf=b;e.C=d;b=e.load(c);return-1!==b?(of(a,b+(a.va.Yf&a.va.R)),a.va.df):null} +function pf(a,b){var c=(a.Ha>>>0)+b;c>a.hf&&(8088>=a.ja||a.va.Ta==a.va.Ba?c=a.va.Aa+(c-a.hf&a.R):C.call(a,13,0));return c|0}function qf(a){a.Ha=a.se}function I(a){return a.gb&~a.ta.Ba|a.fa-a.ta.Aa}function G(a,b){a.gb=b;a.fa=a.ta.Aa+(b&a.ta.Ba)|0}function rf(a,b,c,d,e,f){if(63!=(e&63)&&e!=a.resultType){var g=(e^a.resultType)&a.resultType;g&&(g&1&&sf(a),g&2&&tf(a),g&4&&uf(a),g&8&&vf(a),g&16&&wf(a),g&32&&xf(a))}f?(a.Wc=d,a.Vc=b):(a.Wc=b,a.Vc=d);a.td=c;a.Xc=d;a.resultType=e} +function yf(a,b,c,d,e){a.resultType=c|26;a.Xc=b;d?zf(a):Af(a);e?Bf(a):Cf(a);return b}function Df(a,b,c,d){c&d?zf(a):Af(a);(b^c)&d?Bf(a):Cf(a)}function Ef(a){return sf(a)?1:0}function sf(a){a.resultType&1&&(a.ca&=-2,(a.Wc^(a.Wc^a.td)&(a.td^a.Vc))&a.resultType&-2147450752&&(a.ca|=1),a.resultType&=-2);return a.ca&1}function tf(a){a.resultType&2&&(a.ca&=-5,38505>>((a.Xc^a.Xc>>4)&15)&1&&(a.ca|=4),a.resultType&=-3);return a.ca&4} +function uf(a){a.resultType&4&&(a.ca&=-17,(a.Vc^a.Wc^a.td)&16&&(a.ca|=16),a.resultType&=-5);return a.ca&16}function vf(a){a.resultType&8&&(a.ca&=-65,a.Xc&((a.resultType&-2147450752)-1|a.resultType&-2147450752)||(a.ca|=64),a.resultType&=-9);return a.ca&64}function wf(a){a.resultType&16&&(a.ca&=-129,a.Xc&a.resultType&-2147450752&&(a.ca|=128),a.resultType&=-17);return a.ca&128} +function xf(a){a.resultType&32&&(a.ca&=-2049,(a.Wc^a.Vc)&(a.td^a.Vc)&a.resultType&-2147450752&&(a.ca|=2048),a.resultType&=-33);return a.ca&2048}function Af(a){a.resultType&=-2;a.ca&=-2}function Ff(a){a.resultType&=-5;a.ca&=-17}function Gf(a){a.resultType&=-9;a.ca&=-65}function Cf(a){a.resultType&=-33;a.ca&=-2049}function zf(a){a.resultType&=-2;a.ca|=1}function Hf(a){a.resultType&=-5;a.ca|=16}function If(a){a.resultType&=-9;a.ca|=64}function Bf(a){a.resultType&=-33;a.ca|=2048} +function zd(a){return a.ca&-2262|sf(a)|tf(a)|uf(a)|vf(a)|wf(a)|xf(a)}function Jf(a,b){b=b|a.Za&1|65520;a.Za=a.Za&-65536|b&65535;a.Za&1&&od(a,!0)}function Ad(a,b,c){a.Za&1||(b&=~a.Xf);void 0===c&&(c=a.pa);c?b=b&-12289|a.ca&12288:a.Pa=(b&12288)>>12;c>a.Pa&&(b=b&-513|a.ca&512);a.resultType=128;a.ca=a.ca&~(a.Cc|2261)|b&(a.Cc|2261)|a.Zf;a.ca&256&&(a.ua|=2,a.S|=4)} +function Kf(a,b,c,d){var e=0;if(a.Za&1&&(a.pa>a.Pa||a.ca&131072)&&a.Sa.vi)for(var f=a.Sa.vi+(b>>>3),e=(1<>>=8,f++;return e?(A(a,256)&&y(a,"checkIOPM("+u(b)+","+c+","+(d?"input":"output")+"): trapped",!0,!0),C.call(a,13,0),!1):!0} +m.Pb=function(a,b,c){var d=!1;switch(b){case "EAX":case "EBX":case "ECX":case "EDX":case "ESP":case "EBP":case "ESI":case "EDI":case "EIP":case "AX":case "BX":case "CX":case "DX":case "SP":case "BP":case "SI":case "DI":case "IP":case "PC":case "CS":case "DS":case "SS":case "ES":case "FS":case "GS":case "CR0":case "CR2":case "CR3":case "PS":case "C":case "P":case "A":case "Z":case "S":case "T":case "I":case "D":case "V":this.qa[b]=c;this.Rg++;d=!0;break;default:d=this.parent.Pb.call(this,a,b,c)}return d}; +function Lf(a,b,c,d){var e=(d?a.ld:a.sa)[(b&a.Db)>>>a.La];e&&5==e.type&&(e=Ic(a,b,!1,!0));if(e){var f=b&a.Fa;if(!c||1==c)return e.te(f,b);if(2==c)return f>>this.La].pc(a&this.Fa,a)}; +m.na=function(a){var b=a&this.Fa,c=(a&this.Db)>>>this.La;this.A-=this.B.Gg;if(b>>this.La;if(b>>this.La].sc(a&this.Fa,b&255,a)}; +m.jb=function(a,b){var c=a&this.Fa,d=(a&this.Db)>>>this.La;this.A-=this.B.Gg;c>8&255,a+1))};m.nb=function(a,b){var c=a&this.Fa,d=(a&this.Db)>>>this.La;this.A-=this.B.Gg;if(c>>=8}}; +function Mf(a,b,c){a.$b=b;a.Ca=c&a.Ba;a.D=b.mc(a.Ca,1);return a.S&1?0:a.Qa(a.D)}function Q(a,b){return Mf(a,a.ka,b)}function Nf(a,b){return Mf(a,a.Ka,b)}function Of(a,b,c){a.$b=b;a.Ca=c&a.Ba;a.D=b.mc(a.Ca,a.ba);return a.S&1?0:a.tb(a.D)}function R(a,b){a.$b=a.ka;a.Ca=b&a.Ba;a.D=a.$b.mc(a.Ca,2);return a.S&1?0:a.na(a.D)}function Pf(a,b){a.$b=a.Ka;a.Ca=b&a.Ba;a.D=a.$b.mc(a.Ca,2);return a.S&1?0:a.na(a.D)}function S(a,b){a.$b=a.ka;a.Ca=b&a.Ba;a.D=a.$b.mc(a.Ca,4);return a.S&1?0:a.oa(a.D)} +function Qf(a,b){a.$b=a.Ka;a.Ca=b&a.Ba;a.D=a.$b.mc(a.Ca,4);return a.S&1?0:a.oa(a.D)}function Rf(a,b){a.S&2||a.qc(a.$b.nc(a.Ca,1),b)}function Sf(a,b){a.S&2||a.jb(a.$b.nc(a.Ca,2),b)}function Tf(a,b){a.S&2||a.nb(a.$b.nc(a.Ca,4),b)}function vd(a,b,c){return a.tb(b.mc(c,a.ba))}m.xa=function(){var a=pf(this,1),b=this.Qa(this.Ha);this.Ha=a;return b};function Uf(a){var b=pf(a,2),c=a.na(a.Ha);a.Ha=b;return c}function T(a){var b=pf(a,a.Oc),c=a.dc(a.Ha);a.Ha=b;return c} +m.Ma=function(){var a=pf(this,this.ba),b=this.tb(this.Ha);this.Ha=a;return b};m.T=function(){var a=pf(this,1),b=this.Qa(this.Ha)<<24>>24;this.Ha=a;return b};function D(a){var b=a.tb(a.fa);a.fa=a.fa+a.ba|0;var c=a.Ng-a.fa|0;0>c&&0<=(a.Ng^a.fa)&&(8088>=a.ja||!a.ta.cd&&a.ta.Ta==a.ta.Ba||a.ta.cd&&!a.ta.Ta?G(a,a.fa-a.ta.Aa&a.ta.Ba):-1>c&&C.call(a,12,0));return b} +function wd(a,b,c,d){c=a.fa-c|0;0>(c-a.rd|0)&&0<=(a.rd^c)&&(8088>=a.ja||!a.ta.cd&&a.ta.Ta==a.ta.Ba||a.ta.cd&&!a.ta.Ta?(G(a,c-a.ta.Aa&a.ta.Ba),c=a.fa):C.call(a,12,0));switch(d){case 1:a.qc(c,b);break;case 2:a.jb(c,b);break;case 4:a.nb(c,b)}a.fa=c}function J(a,b){var c=a.fa-a.ba|0;0>(c-a.rd|0)&&0<=(a.rd^c)&&(8088>=a.ja||!a.ta.cd&&a.ta.Ta==a.ta.Ba||a.ta.cd&&!a.ta.Ta?(G(a,c-a.ta.Aa&a.ta.Ba),c=a.fa):C.call(a,12,0));a.rc(c,b);a.fa=c} +function Vf(a,b,c){var d=4;1==b.length&&(d=1,c=c?1:0);if(80386>a.ja)2this.ja?0:1,e=0;2>e;e++){switch(d){case 0:if(this.ua&1&&this.ca&512){var f=Xf(this.N);if(-1<=f&&(this.ua&=-2,0<=f)){this.ua&=-5;Yf.call(this, +f);d=!0;break a}}break;case 1:if(this.ua&2){this.ua&=-3;80386<=this.ja&&(this.Ja[6]|=16384);Yf.call(this,1);d=!0;break a}}d=1-d}d=!1}if(d&&!a){this.O("interrupt dispatched");this.S=0;break}if(this.ua&4){this.S=this.A=0;break}}if(b){if(Zf(this.ha,this.Ha,c)){this.Wb();break}c=1}this.S=0;this.W[this.xa()].call(this)}while(0>11;dg(this);eg(this,a[b++]);for(c=0;c=fg&&gg(a,13))}function dg(a){a.ma&=-129;a.ma&~a.jc&63&&(a.ma|=128);if(a.ma&128&&!(a.jc&128))return a=a.N,a.ja>=fg?hg(a,13):a.ya&0||Yf.call(a.F,2),!0;a=a.N;a.ja>=fg&&gg(a,13);return!1}function ig(a,b){80387<=a.ja||(b&=-65);a.ma|=b;return dg(a)} +function bg(a){return a.ma|a.B<<11}function jg(a,b){return isFinite(b)?!0:!ig(a,Infinity===b?8:16)}function kg(a,b,c){var d=null;null!=b&&null!=c&&(d=b+c,jg(a,d)||(d=null));return d}function lg(a,b,c){var d=null;null!=b&&null!=c&&(d=b-c,jg(a,d)||(d=null));return d}function mg(a,b,c){var d=null;null!=b&&null!=c&&(d=b*c,jg(a,d)||(d=null));return d}function ng(a,b,c){var d=null;null==b||null==c||!c&&ig(a,2)||(d=b/c,jg(a,d)||(d=null));return d} +function og(a,b,c){if(null!=b&&null!=c){var d=0;isNaN(b)||isNaN(c)?d=17664:(b-=c,0>b?d=256:0===b&&(d=16384));a.ma=a.ma&-18177|d;return!0}return!1}function Bg(a,b,c){if(null==b)return null;var d=a.jc&3072;0==d?(d=Math.round(b),.5===d-b&&d%2&&d--):d=1024==d||3072==d&&0=c){if(ig(a,1))return null;d=-c}else if(d<-c){if(ig(a,1))return null;d=-c}a.L[0]=d|0;2147483648d&&(a.L[1]=-1))}return d} +function Cg(a,b){var c=3;if(a.C&1<=c;c<<=1)3!=(b&3)&&(a.C|=c),b>>=2}function Dg(a){var b=a.B+0&7;return a.C&1<>16}function Ig(a){return a.F.oa(a.F.D)}function Jg(a){a.ua[0]=a.F.oa(a.F.D);return a.pa[0]}function Kg(a){a.L[0]=a.F.oa(a.F.D);a.L[1]=a.F.oa(a.F.D+4);return a.W[0]} +function Lg(a){a.ga[0]=a.F.oa(a.F.D);a.ga[1]=a.F.oa(a.F.D+4);a.ga[2]=a.F.na(a.F.D+8);return a.ga}m.pi=function(){this.F.nb(this.F.D,this.L[0])};m.rk=function(){this.F.nb(this.F.D,this.L[0]);this.F.nb(this.F.D+4,this.L[1])};m.tk=$f.prototype.pi;m.sk=$f.prototype.rk;function Mg(a){a.F.nb(a.F.D,a.ga[0]);a.F.nb(a.F.D+4,a.ga[1]);a.F.jb(a.F.D+8,a.ga[2])} +function Ng(a,b){var c=b[1],d=(b[2]&32768)>>4,e=b[2]&32767,f=b[0]>>>11|c<<21,c=c>>11&1048575;32767==e?e=2047:e&&(e+=-15360,0>=e&&(e=2047,f=c=0));a.L[0]=f;a.L[1]=c|(d|e)<<20;return a.W[0]}function Gg(a,b,c){var d=c>>20&2047,e=2147483648|(c&1048575)<<11|b>>>21;2047==d?d=32767:d?d+=15360:e&=2147483647;a.ga[0]=b<<11;a.ga[1]=e;a.ga[2]=c>>16&32768|d;return a.ga}function Og(a,b){for(var c=0,d=1;b--;)c+=(a&15)*d,d*=10,a>>=4;return c}function Pg(a,b){for(var c=0,d=0;b--;)c|=a%10<>11;dg(a);eg(a,d.tb(b+=d.ba));!(d.Za&1)||d.ca&131072?(a.V=d.tb(b+=d.ba),c=d.tb(b+=d.ba),a.ia=c&2047,a.V|=(c&-4096)<<4,a.ea=-1,a.U=d.tb(b+=d.ba),a.U|=(d.tb(b+=d.ba)&-4096)<<4,a.fa=-1):(a.V=d.tb(b+=d.ba),c=d.tb(b+=d.ba),a.ea=c&65535,a.ia=c>>16&2047,a.U=d.tb(b+=d.ba),a.fa=d.tb(b+=d.ba)&65535);return b+d.ba} +function Tg(a,b){var c=a.F;c.rc(b,a.jc);c.rc(b+=c.ba,bg(a));c.rc(b+=c.ba,cg(a));if(!(c.Za&1)||c.ca&131072){var d=(a.ea<<4)+a.V;c.rc(b+=c.ba,d);c.rc(b+=c.ba,d>>4&-4096|a.ia);d=(a.fa<<4)+a.U;c.rc(b+=c.ba,d);c.rc(b+=c.ba,d>>4&-4096)}else c.rc(b+=c.ba,a.V),c.rc(b+=c.ba,a.ea|a.ia<<16),c.rc(b+=c.ba,a.U),c.rc(b+=c.ba,a.fa);return b+c.ba}var Ug=Math.log(10)/Math.LN2,Vg=Math.LOG2E,Wg=Math.PI,Xg=Math.log(2)/Math.LN10,Yg=Math.LN2,Zg=Math.pow(2,63);function $g(){this.ma&=-32896;dg(this)} +function ah(){og(this,U(this,0),U(this,this.A))}function bh(){og(this,U(this,0),U(this,this.A))&&Qg(this)}function ch(){bh.call(this)}function dh(){V(this,0,ng(this,U(this,0),Jg(this)))}function eh(){this.C&=~(1<>20&2047)-1023),this.L[1]=(this.L[1]|1072693248)&-1073741825,Rg(this,this.W[0]))},102:function(){this.B=this.B-1&7;this.ma&=-513},103:function(){this.B=this.B+1&7;this.ma&=-513},112:function(){V(this,0,U(this,0)%U(this,1))},113:function(){V(this,1,U(this, +1)*Math.log(U(this,0)+1)/Math.LN2)&&Qg(this)},114:function(){var a=U(this,0),b=null;if(0<=a||!ig(this,1))b=Math.sqrt(a),jg(this,b)||(b=null);V(this,0,b)},116:function(){V(this,0,Bg(this,U(this,0),Zg))},117:function(){var a=U(this,0),b=U(this,1);null!=a&&null!=b&&V(this,0,a*Math.pow(2,0>>0);Rg(this,a)},6:function(){var a=Bg(this,Qg(this));null!=a&&(this.ga[0]= +Pg(a,8),this.ga[1]=Pg(a/1E8,8),this.ga[2]=Pg(a/1E16,2),0>a&&(this.ga[2]|=32768),Mg(this))},7:function(){null!=Bg(this,U(this,0),Zg)&&(this.rk(),Qg(this))},48:function(){eh.call(this);Qg(this)},49:rh,50:mh,51:mh,52:ph}},th=[$g,fh,gh,hh,ih,jh,nh,kh,oh,ph];Sa(function(){for(var a=pb(document,"pcx86","fpu"),b=0;b>16,c=c<<16>>16,d=d<<16>>16);this.A-=this.B.ej;(bd)&&C.call(this,5);this.S|=2;return a}function Ch(a,b){var c=0;if(b){Gf(this);for(var d=1;d&this.R;){if(b&d){a=c;break}d<<=1;c++}}else If(this);this.A-=11+3*c;return a}function Dh(a,b){var c=0;if(b){Gf(this);for(var d=2==this.ba?15:31,e=1<>>=1;c++;d--}}else If(this);this.A-=11+3*c;return a} +function Eh(a,b){a&1<<(b&(2==this.ba?15:31))?zf(this):Af(this);this.A-=-1===this.D?3:6;this.S|=2;return a}function Fh(a,b){var c=1<<(b&(2==this.ba?15:31));a&c?zf(this):Af(this);this.A-=-1===this.D?6:8;return a^c}function Gh(a,b){var c=1<<(b&(2==this.ba?15:31));a&c?zf(this):Af(this);this.A-=-1===this.D?6:8;return a&~c}function Hh(a,b){var c=1<<(b&(2==this.ba?15:31));a&c?zf(this):Af(this);this.A-=-1===this.D?6:8;return a|c} +function Ih(a,b){if(-1===this.D)return Eh.call(this,a,b);var c=this.ba<<3;if(b>=c||b<-c)a=Of(this,this.$b,this.Ca+(b>>(2==this.ba?4:5))*this.ba);b=1<<(b&(2==this.ba?15:31));a&b?zf(this):Af(this);this.A-=6;this.S|=2;return a}function Jh(a,b){if(-1===this.D)return Fh.call(this,a,b);var c=this.ba<<3;if(b>=c||b<-c)a=Of(this,this.$b,this.Ca+(b>>(2==this.ba?4:5))*this.ba);b=1<<(b&(2==this.ba?15:31));a&b?zf(this):Af(this);this.A-=8;return a^b} +function Kh(a,b){if(-1===this.D)return Gh.call(this,a,b);var c=this.ba<<3;if(b>=c||b<-c)a=Of(this,this.$b,this.Ca+(b>>(2==this.ba?4:5))*this.ba);b=1<<(b&(2==this.ba?15:31));a&b?zf(this):Af(this);this.A-=8;return a&~b}function Lh(a,b){if(-1===this.D)return Hh.call(this,a,b);var c=this.ba<<3;if(b>=c||b<-c)a=Of(this,this.$b,this.Ca+(b>>(2==this.ba?4:5))*this.ba);b=1<<(b&(2==this.ba?15:31));a&b?zf(this):Af(this);this.A-=8;return a|b} +function Mh(a,b){rf(this,a,b,a-b|0,191,!0);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Bh:this.B.Vb;this.S|=2;return a}function Nh(a,b){rf(this,a,b,a-b|0,this.Ga|63,!0);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Bh:this.B.Vb;this.S|=2;return a} +function Oh(a){if(this.Tb){var b=this.Tb,c=this.kg,d=this.L,e=d>>3&7;b.A=d&7;var f=(3>(d>>6&3)?0:48)+e;(217==c||219==c)&&52<=f&&(f=e<<4|b.A);if(e=sh[c][f]){if(0>th.indexOf(e)){var f=b.F,g=f.se;8087==b.ja&&(f.Ia&16&&g++,f.Ia&32&&g++);b.ea=f.va.Z;b.V=g-f.va.Aa;-1!==f.D&&(b.fa=f.$b.Z,b.U=f.D-f.$b.Aa);b.ia=(c&7)<<8|d}e.call(b)}}this.A-=-1===this.D?2:8;return a}function Ph(a){if(80186>this.ja)return Qh.call(this,a);C.call(this,13,0);return a}function ge(a){C.call(this,6);return a} +function Qh(a){je.call(this);return a}function Rh(a,b){var c=Sh.call(this,this.T(),b);80386>this.ja&&(this.A-=12);return c}function Th(a,b){var c;a=this.Ma();c=2==this.ba?Sh.call(this,a,b):Uh.call(this,a,b);80386>this.ja&&(this.A-=12);return c}function Vh(a,b){var c=!1;0>b&&(b=-b|0,c=!c);0>a&&(a=-a|0,c=!c);Wh.call(this,a,b);c&&(this.ia=~this.ia+1|0,this.wa=~this.wa+(this.ia?0:1)|0)} +function Sh(a,b){var c=(a<<16>>16)*(b<<16>>16)|0;32767c?(zf(this),Bf(this)):(Af(this),Cf(this));this.A-=-1===this.D?9:12;return c&65535}function Uh(a,b){Vh.call(this,a,b);this.wa!=this.ia>>31?(zf(this),Bf(this)):(Af(this),Cf(this));this.A-=-1===this.D?9:12;return this.ia}function Xh(a,b){this.A-=14+(-1===this.D?0:2);Gf(this);-1!==this.Da.load(b)&&this.Da.Gc>=this.pa&&this.Da.Gc>=(b&3)&&(If(this),a=this.Da.wb&-256,2=this.pa)&&this.Da.Gc>=(b&3))return If(this),this.Da.Ta;Gf(this);return a}function di(a,b){if(-1===this.D)return je.call(this),a;md(this,this.na(this.D+this.ba));this.A-=this.B.pf;return b} +function ei(a,b){this.A-=-1===this.C?-1===this.D?this.B.Oj:this.B.Nj:this.B.Lj;return b}function fi(a,b){switch(this.L>>3&7){case 4:this.aa=this.G;break;case 5:this.aa=this.I;break;case 6:this.aa=this.M;break;case 7:this.aa=this.H}return b}function gi(a,b){return b} +function hi(a,b){var c=this.L>>3&7;switch(c){case 0:this.aa=this.G;break;case 2:this.aa=this.M;break;case 3:this.aa=this.H;break;default:if(80286==this.ja||80386==this.ja&&4!=c&&5!=c){C.call(this,6);break}switch(c){case 1:this.aa=this.I;break;case 4:this.aa=I(this);break;case 5:this.aa=this.P;break;case 6:this.aa=this.K;break;case 7:this.aa=this.J}}return ei.call(this,0,b)} +function ii(a,b){switch(this.L>>3&7){case 0:b=this.Xa.Z;break;case 1:b=this.va.Z;break;case 2:b=this.ta.Z;break;case 3:b=this.vb.Z;break;case 4:if(80386<=this.ja){b=this.Nb.Z;break}C.call(this,6);b=a;break;case 5:if(80386<=this.ja){b=this.Ob.Z;break}default:C.call(this,6),b=a}-1!==this.C&&ud(this,2);return ei.call(this,0,b)} +function Wh(a,b){if(a&-65536||b&-65536){var c=b&65535,d=b>>>16,e=a&65535,f=a>>>16,g=c*e,e=(g>>>16)+d*e,h=e>>>16,e=(e&65535)+c*f;this.ia=e<<16|g&65535;this.wa=h+((e>>>16)+d*f)|0}else this.ia=a*b|0,this.wa=0}function ji(a,b){this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return yf(this,a|b,128)}function Bi(a,b){this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return yf(this,a|b,this.Ga)&this.R} +function Ci(a,b){var c=a-b-Ef(this)|0;rf(this,a,b,c,191,!0);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return c&255}function Di(a,b){var c=a-b-Ef(this)|0;rf(this,a,b,c,this.Ga|63,!0);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return c&this.R}function Ei(){return xf(this)?1:0}function Fi(){return sf(this)?1:0}function Gi(){return sf(this)?0:1}function Hi(){return vf(this)?1:0}function Ii(){return vf(this)?0:1}function Ji(){return sf(this)||vf(this)?1:0} +function Ki(){return sf(this)||vf(this)?0:1}function Li(){return wf(this)?1:0}function Mi(){return wf(this)?0:1}function Ni(){return tf(this)?1:0}function Oi(){return tf(this)?0:1}function Pi(){return!wf(this)!=!xf(this)?1:0}function Qi(){return!wf(this)!=!xf(this)?0:1}function Ri(){return vf(this)||!wf(this)!=!xf(this)?1:0}function Si(){return vf(this)||!wf(this)!=!xf(this)?0:1}function Ti(a,b){return Ui.call(this,a,b,this.xa())}function Vi(a,b){return Wi.call(this,a,b,this.xa())} +function Xi(a,b){return Ui.call(this,a,b,this.I&31)}function Yi(a,b){return Wi.call(this,a,b,this.I&31)}function Zi(a,b){return $i.call(this,a,b,this.xa())}function aj(a,b){return bj.call(this,a,b,this.xa())}function cj(a,b){return $i.call(this,a,b,this.I&31)}function dj(a,b){return bj.call(this,a,b,this.I&31)}function ej(a,b){var c=a-b|0;rf(this,a,b,c,191,!0);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return c&255} +function fj(a,b){var c=a-b|0;rf(this,a,b,c,this.Ga|63,!0);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return c&this.R}function gj(a,b){yf(this,a&b,128);this.A-=-1===this.C?-1===this.D?this.B.ci:this.B.Uf:this.B.Uf;this.S|=2;return a}function hj(a,b){yf(this,a&b,this.Ga);this.A-=-1===this.C?-1===this.D?this.B.ci:this.B.Uf:this.B.Uf;this.S|=2;return a}function ij(a,b){var c=this.G&this.R,d=(1<<(this.I&31))-1;return a&~(d<>(this.G&this.R)&(1<<(this.I&31))-1&this.R}function kj(a,b){if(-1===this.D){switch(this.L&7){case 0:this.G=this.G&-256|a;break;case 1:this.I=this.I&-256|a;break;case 2:this.M=this.M&-256|a;break;case 3:this.H=this.H&-256|a;break;case 4:this.G=this.G&-65281|a<<8;break;case 5:this.I=this.I&-65281|a<<8;break;case 6:this.M=this.M&-65281|a<<8;break;case 7:this.H=this.H&-65281|a<<8}this.A-=this.B.ei}else this.C=this.D,Rf(this,a),this.A-=this.B.di;return b} +function lj(a,b){if(-1===this.D){switch(this.L&7){case 0:this.G=this.G&~this.R|a;break;case 1:this.I=this.I&~this.R|a;break;case 2:this.M=this.M&~this.R|a;break;case 3:this.H=this.H&~this.R|a;break;case 4:G(this,I(this)&~this.R|a);break;case 5:this.P=this.H&~this.R|a;break;case 6:this.K=this.K&~this.R|a;break;case 7:this.J=this.J&~this.R|a}this.A-=this.B.ei}else this.C=this.D,this.S&2||this.rc(this.$b.nc(this.Ca,this.ba),a),this.A-=this.B.di;return b} +function mj(a,b){var c=a^b;yf(this,c,128);this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return c}function nj(a,b){this.A-=-1===this.C?-1===this.D?this.B.yc:this.B.Vb:this.B.Nc;return yf(this,a^b,this.Ga)&this.R}function oj(a,b){var c=a[1]-b[1];c||(c=a[0]-b[0]);return c}function pj(a){var b=a-1|0;rf(this,a,1,b,this.Ga|62,!0);this.A-=2;return a&~this.R|b&this.R} +function qj(a,b,c){c>>>=0;if(!c||c<=b>>>0)return!1;var d=0,e=1;c=[c>>>0,0];for(a=[a>>>0,b>>>0];0>>=0,b[1]++);e+=e}do 0<=oj(a,c)&&(b=a,f=c,b[0]-=f[0],b[1]-=f[1],0>b[0]&&(b[0]>>>=0,b[1]--),d+=e),b=c,b[0]>>>=1,b[1]&1&&(b[0]=(b[0]|2147483648)>>>0),b[1]>>>=1,e/=2;while(1<=e);this.ia=d;this.wa=a[0];return!0}function rj(a){var b=a+1|0;rf(this,a,1,b,this.Ga|62);this.A-=2;return a&~this.R|b&this.R} +function sj(a){this.Za=a;od(this);this.Za&-2147483648?ue(this):we(this)}function Cd(a){this.Qd=a;Yb(this)}function tj(a){this.S|=1;this.$a.call(this,a);this.A-=-1===this.D?4:5}function Ui(a,b,c){if(c){16>>16-c)&65535;yf(this,a,32768,d&32768)}return a}function Wi(a,b,c){if(c){var d=a<>>32-c;yf(this,a,-2147483648,d&-2147483648)}return a} +function $i(a,b,c){if(c){16>>c-1;a=(d>>>1|b<<16-c)&65535;yf(this,a,32768,d&1)}return a}function bj(a,b,c){if(c){var d=a>>>c-1;a=d>>>1|b<<32-c;yf(this,a,-2147483648,d&1)}return a}function uj(){this.A-=-1===this.D?2:this.B.ak;return 1}function vj(){var a=this.I&255;this.A-=(-1===this.D?this.B.Wh:this.B.Vh)+(a<this.rb?(-1!=this.bc&&(this.bc!==this.va.Z&&(this.va.Lb=this.bc&3,nf(this,this.bc)),this.bc=-1),this.se!==this.Ha&&of(this,this.se),-1!=this.sb&&(this.sb!==this.ta.Z&&md(this,this.sb),this.sb=-1),-1!==this.U&&(this.U!==this.fa&&G(this,this.gb&~this.ta.Ba|this.U-this.ta.Aa),this.U=-1)):8!=this.rb?(b=0,a=8):(b=0,a=-1,se(this),e=d=!1)):of(this,this.se);var f=a,g=b,h=32,k=Lf(this,this.Ha);204!=k||this.Ud||(d=!1);this.ca&131072&&(6==f&&99== +k||13==f&&205==k)&&(d=!1);!1===d&&(h|=1);983040<=this.Ha&&1048575>=this.Ha&&(d=!1);A(this,h|-2147483648)&&(d=!0);if(A(this,h)||d){var l=this.la.Fb,f="Fault "+t(f)+(null!=g?" ("+u(g)+")":"")+" on opcode "+t(k);d&&l&&(f+=" (blocked)");this.ha?(y(this,f,d||h,!0),d&&(d=l,this.ha.Wb())):(this.Na(f),this.Wb())}if(d&&e)throw-1;if(e)throw this.rb=a,Aj.call(this,a,b,c),this.se=this.Ha,this.S=1==a?this.S|8192:this.S|4096,a;} +function ve(a,b,c){this.ue=a;a=0;b&&(a|=1);c&&(a|=2);3==this.pa&&(a|=4);C.call(this,14,a)}function Cj(a){var b=a.wb&7680;a.Z&65528&&(6144==b||7168==b||7168>b&&a.Gc>8&255;break;case 197:c=this.I>>8&255;break;case 198:c=this.M>>8&255;break;case 199:c=this.H>>8&255;break;default:c=0}var d=this.L>>3&7;switch(d){case 0:b=this.G&255;break;case 1:b=this.I&255;break;case 2:b=this.M&255;break;case 3:b=this.H&255;break;case 4:b=this.G>>8&255;break;case 5:b=this.I>>8&255;break;case 6:b=this.M>>8&255;break;case 7:b=this.H>>8&255;break;default:b=0}a=a.call(this,b,c);switch(d){case 0:this.G=this.G& +-256|a;break;case 1:this.I=this.I&-256|a;break;case 2:this.M=this.M&-256|a;break;case 3:this.H=this.H&-256|a;break;case 4:this.G=this.G&-65281|a<<8;break;case 5:this.I=this.I&-65281|a<<8;break;case 6:this.M=this.M&-65281|a<<8;break;case 7:this.H=this.H&-65281|a<<8}} +function Be(a){var b,c,d=(this.L=this.xa())&199;switch(d){case 0:b=Q(this,this.H+this.K);this.C=this.D;break;case 1:b=Q(this,this.H+this.J);this.C=this.D;break;case 2:b=Nf(this,this.P+this.K);this.C=this.D;break;case 3:b=Nf(this,this.P+this.J);this.C=this.D;break;case 4:b=Q(this,this.K);this.C=this.D;break;case 5:b=Q(this,this.J);this.C=this.D;break;case 6:b=Q(this,T(this));this.C=this.D;break;case 7:b=Q(this,this.H);this.C=this.D;break;case 64:b=Q(this,this.H+this.K+this.T());this.C=this.D;break; +case 65:b=Q(this,this.H+this.J+this.T());this.C=this.D;break;case 66:b=Nf(this,this.P+this.K+this.T());this.C=this.D;break;case 67:b=Nf(this,this.P+this.J+this.T());this.C=this.D;break;case 68:b=Q(this,this.K+this.T());this.C=this.D;break;case 69:b=Q(this,this.J+this.T());this.C=this.D;break;case 70:b=Nf(this,this.P+this.T());this.C=this.D;break;case 71:b=Q(this,this.H+this.T());this.C=this.D;break;case 128:b=Q(this,this.H+this.K+T(this));this.C=this.D;break;case 129:b=Q(this,this.H+this.J+T(this)); +this.C=this.D;break;case 130:b=Nf(this,this.P+this.K+T(this));this.C=this.D;break;case 131:b=Nf(this,this.P+this.J+T(this));this.C=this.D;break;case 132:b=Q(this,this.K+T(this));this.C=this.D;break;case 133:b=Q(this,this.J+T(this));this.C=this.D;break;case 134:b=Nf(this,this.P+T(this));this.C=this.D;break;case 135:b=Q(this,this.H+T(this));this.C=this.D;break;case 192:b=this.G&255;break;case 193:b=this.I&255;break;case 194:b=this.M&255;break;case 195:b=this.H&255;break;case 196:b=this.G>>8&255;break; +case 197:b=this.I>>8&255;break;case 198:b=this.M>>8&255;break;case 199:b=this.H>>8&255;break;default:b=0}switch(this.L>>3&7){case 0:c=this.G&255;break;case 1:c=this.I&255;break;case 2:c=this.M&255;break;case 3:c=this.H&255;break;case 4:c=this.G>>8&255;break;case 5:c=this.I>>8&255;break;case 6:c=this.M>>8&255;break;case 7:c=this.H>>8&255;break;default:c=0}a=a.call(this,b,c);switch(d){case 0:case 3:Rf(this,a);this.A-=this.B.ed;break;case 1:case 2:Rf(this,a);this.A-=this.B.fd;break;case 4:case 5:case 7:Rf(this, +a);this.A-=this.B.Jc;break;case 6:Rf(this,a);this.A-=this.B.Ld;break;case 64:case 67:case 128:case 131:Rf(this,a);this.A-=this.B.ec;break;case 65:case 66:case 129:case 130:Rf(this,a);this.A-=this.B.fc;break;case 68:case 69:case 70:case 71:case 132:case 133:case 134:case 135:Rf(this,a);this.A-=this.B.ib;break;case 192:this.G=this.G&-256|a;break;case 193:this.I=this.I&-256|a;break;case 194:this.M=this.M&-256|a;break;case 195:this.H=this.H&-256|a;break;case 196:this.G=this.G&-65281|a<<8;break;case 197:this.I= +this.I&-65281|a<<8;break;case 198:this.M=this.M&-65281|a<<8;break;case 199:this.H=this.H&-65281|a<<8}} +function Ce(a,b){var c,d=(this.L=this.xa())&199;switch(d){case 0:c=Q(this,this.H+this.K);this.C=this.D;break;case 1:c=Q(this,this.H+this.J);this.C=this.D;break;case 2:c=Nf(this,this.P+this.K);this.C=this.D;break;case 3:c=Nf(this,this.P+this.J);this.C=this.D;break;case 4:c=Q(this,this.K);this.C=this.D;break;case 5:c=Q(this,this.J);this.C=this.D;break;case 6:c=Q(this,T(this));this.C=this.D;break;case 7:c=Q(this,this.H);this.C=this.D;break;case 64:c=Q(this,this.H+this.K+this.T());this.C=this.D;break; +case 65:c=Q(this,this.H+this.J+this.T());this.C=this.D;break;case 66:c=Nf(this,this.P+this.K+this.T());this.C=this.D;break;case 67:c=Nf(this,this.P+this.J+this.T());this.C=this.D;break;case 68:c=Q(this,this.K+this.T());this.C=this.D;break;case 69:c=Q(this,this.J+this.T());this.C=this.D;break;case 70:c=Nf(this,this.P+this.T());this.C=this.D;break;case 71:c=Q(this,this.H+this.T());this.C=this.D;break;case 128:c=Q(this,this.H+this.K+T(this));this.C=this.D;break;case 129:c=Q(this,this.H+this.J+T(this)); +this.C=this.D;break;case 130:c=Nf(this,this.P+this.K+T(this));this.C=this.D;break;case 131:c=Nf(this,this.P+this.J+T(this));this.C=this.D;break;case 132:c=Q(this,this.K+T(this));this.C=this.D;break;case 133:c=Q(this,this.J+T(this));this.C=this.D;break;case 134:c=Nf(this,this.P+T(this));this.C=this.D;break;case 135:c=Q(this,this.H+T(this));this.C=this.D;break;case 192:c=this.G&255;break;case 193:c=this.I&255;break;case 194:c=this.M&255;break;case 195:c=this.H&255;break;case 196:c=this.G>>8&255;break; +case 197:c=this.I>>8&255;break;case 198:c=this.M>>8&255;break;case 199:c=this.H>>8&255;break;default:c=0}c=a[this.L>>3&7].call(this,c,b.call(this));switch(d){case 0:case 3:Rf(this,c);this.A-=this.B.ed;break;case 1:case 2:Rf(this,c);this.A-=this.B.fd;break;case 4:case 5:case 7:Rf(this,c);this.A-=this.B.Jc;break;case 6:Rf(this,c);this.A-=this.B.Ld;break;case 64:case 67:case 128:case 131:Rf(this,c);this.A-=this.B.ec;break;case 65:case 66:case 129:case 130:Rf(this,c);this.A-=this.B.fc;break;case 68:case 69:case 70:case 71:case 132:case 133:case 134:case 135:Rf(this, +c);this.A-=this.B.ib;break;case 192:this.G=this.G&-256|c;break;case 193:this.I=this.I&-256|c;break;case 194:this.M=this.M&-256|c;break;case 195:this.H=this.H&-256|c;break;case 196:this.G=this.G&-65281|c<<8;break;case 197:this.I=this.I&-65281|c<<8;break;case 198:this.M=this.M&-65281|c<<8;break;case 199:this.H=this.H&-65281|c<<8}} +function De(a){var b,c;switch((this.L=this.xa())&199){case 0:c=R(this,this.H+this.K);this.A-=this.B.ed;break;case 1:c=R(this,this.H+this.J);this.A-=this.B.fd;break;case 2:c=Pf(this,this.P+this.K);this.A-=this.B.fd;break;case 3:c=Pf(this,this.P+this.J);this.A-=this.B.ed;break;case 4:c=R(this,this.K);this.A-=this.B.Jc;break;case 5:c=R(this,this.J);this.A-=this.B.Jc;break;case 6:c=R(this,T(this));this.A-=this.B.Ld;break;case 7:c=R(this,this.H);this.A-=this.B.Jc;break;case 64:c=R(this,this.H+this.K+this.T()); +this.A-=this.B.ec;break;case 65:c=R(this,this.H+this.J+this.T());this.A-=this.B.fc;break;case 66:c=Pf(this,this.P+this.K+this.T());this.A-=this.B.fc;break;case 67:c=Pf(this,this.P+this.J+this.T());this.A-=this.B.ec;break;case 68:c=R(this,this.K+this.T());this.A-=this.B.ib;break;case 69:c=R(this,this.J+this.T());this.A-=this.B.ib;break;case 70:c=Pf(this,this.P+this.T());this.A-=this.B.ib;break;case 71:c=R(this,this.H+this.T());this.A-=this.B.ib;break;case 128:c=R(this,this.H+this.K+T(this));this.A-= +this.B.ec;break;case 129:c=R(this,this.H+this.J+T(this));this.A-=this.B.fc;break;case 130:c=Pf(this,this.P+this.K+T(this));this.A-=this.B.fc;break;case 131:c=Pf(this,this.P+this.J+T(this));this.A-=this.B.ec;break;case 132:c=R(this,this.K+T(this));this.A-=this.B.ib;break;case 133:c=R(this,this.J+T(this));this.A-=this.B.ib;break;case 134:c=Pf(this,this.P+T(this));this.A-=this.B.ib;break;case 135:c=R(this,this.H+T(this));this.A-=this.B.ib;break;case 192:c=this.G&65535;break;case 193:c=this.I&65535;break; +case 194:c=this.M&65535;break;case 195:c=this.H&65535;break;case 196:c=I(this)&65535;break;case 197:c=this.P&65535;break;case 198:c=this.K&65535;break;case 199:c=this.J&65535;break;default:c=0}var d=this.L>>3&7;switch(d){case 0:b=this.G&65535;break;case 1:b=this.I&65535;break;case 2:b=this.M&65535;break;case 3:b=this.H&65535;break;case 4:b=I(this)&65535;break;case 5:b=this.P&65535;break;case 6:b=this.K&65535;break;case 7:b=this.J&65535;break;default:b=0}a=a.call(this,b,c);switch(d){case 0:this.G= +this.G&-65536|a;break;case 1:this.I=this.I&-65536|a;break;case 2:this.M=this.M&-65536|a;break;case 3:this.H=this.H&-65536|a;break;case 4:G(this,I(this)&-65536|a);break;case 5:this.P=this.P&-65536|a;break;case 6:this.K=this.K&-65536|a;break;case 7:this.J=this.J&-65536|a}} +function Ee(a){var b,c,d=(this.L=this.xa())&199;switch(d){case 0:b=R(this,this.H+this.K);this.C=this.D;break;case 1:b=R(this,this.H+this.J);this.C=this.D;break;case 2:b=Pf(this,this.P+this.K);this.C=this.D;break;case 3:b=Pf(this,this.P+this.J);this.C=this.D;break;case 4:b=R(this,this.K);this.C=this.D;break;case 5:b=R(this,this.J);this.C=this.D;break;case 6:b=R(this,T(this));this.C=this.D;break;case 7:b=R(this,this.H);this.C=this.D;break;case 64:b=R(this,this.H+this.K+this.T());this.C=this.D;break; +case 65:b=R(this,this.H+this.J+this.T());this.C=this.D;break;case 66:b=Pf(this,this.P+this.K+this.T());this.C=this.D;break;case 67:b=Pf(this,this.P+this.J+this.T());this.C=this.D;break;case 68:b=R(this,this.K+this.T());this.C=this.D;break;case 69:b=R(this,this.J+this.T());this.C=this.D;break;case 70:b=Pf(this,this.P+this.T());this.C=this.D;break;case 71:b=R(this,this.H+this.T());this.C=this.D;break;case 128:b=R(this,this.H+this.K+T(this));this.C=this.D;break;case 129:b=R(this,this.H+this.J+T(this)); +this.C=this.D;break;case 130:b=Pf(this,this.P+this.K+T(this));this.C=this.D;break;case 131:b=Pf(this,this.P+this.J+T(this));this.C=this.D;break;case 132:b=R(this,this.K+T(this));this.C=this.D;break;case 133:b=R(this,this.J+T(this));this.C=this.D;break;case 134:b=Pf(this,this.P+T(this));this.C=this.D;break;case 135:b=R(this,this.H+T(this));this.C=this.D;break;case 192:b=this.G&65535;break;case 193:b=this.I&65535;break;case 194:b=this.M&65535;break;case 195:b=this.H&65535;break;case 196:b=I(this)&65535; +break;case 197:b=this.P&65535;break;case 198:b=this.K&65535;break;case 199:b=this.J&65535;break;default:b=0}switch(this.L>>3&7){case 0:c=this.G&65535;break;case 1:c=this.I&65535;break;case 2:c=this.M&65535;break;case 3:c=this.H&65535;break;case 4:c=I(this)&65535;break;case 5:c=this.P&65535;break;case 6:c=this.K&65535;break;case 7:c=this.J&65535;break;default:c=0}a=a.call(this,b,c);switch(d){case 0:case 3:Sf(this,a);this.A-=this.B.ed;break;case 1:case 2:Sf(this,a);this.A-=this.B.fd;break;case 4:case 5:case 7:Sf(this, +a);this.A-=this.B.Jc;break;case 6:Sf(this,a);this.A-=this.B.Ld;break;case 64:case 67:case 128:case 131:Sf(this,a);this.A-=this.B.ec;break;case 65:case 66:case 129:case 130:Sf(this,a);this.A-=this.B.fc;break;case 68:case 69:case 70:case 71:case 132:case 133:case 134:case 135:Sf(this,a);this.A-=this.B.ib;break;case 192:this.G=this.G&-65536|a;break;case 193:this.I=this.I&-65536|a;break;case 194:this.M=this.M&-65536|a;break;case 195:this.H=this.H&-65536|a;break;case 196:G(this,I(this)&-65536|a);break; +case 197:this.P=this.P&-65536|a;break;case 198:this.K=this.K&-65536|a;break;case 199:this.J=this.J&-65536|a}} +function Fe(a,b){var c,d=(this.L=this.xa())&199;switch(d){case 0:c=R(this,this.H+this.K);this.C=this.D;break;case 1:c=R(this,this.H+this.J);this.C=this.D;break;case 2:c=Pf(this,this.P+this.K);this.C=this.D;break;case 3:c=Pf(this,this.P+this.J);this.C=this.D;break;case 4:c=R(this,this.K);this.C=this.D;break;case 5:c=R(this,this.J);this.C=this.D;break;case 6:c=R(this,T(this));this.C=this.D;break;case 7:c=R(this,this.H);this.C=this.D;break;case 64:c=R(this,this.H+this.K+this.T());this.C=this.D;break; +case 65:c=R(this,this.H+this.J+this.T());this.C=this.D;break;case 66:c=Pf(this,this.P+this.K+this.T());this.C=this.D;break;case 67:c=Pf(this,this.P+this.J+this.T());this.C=this.D;break;case 68:c=R(this,this.K+this.T());this.C=this.D;break;case 69:c=R(this,this.J+this.T());this.C=this.D;break;case 70:c=Pf(this,this.P+this.T());this.C=this.D;break;case 71:c=R(this,this.H+this.T());this.C=this.D;break;case 128:c=R(this,this.H+this.K+T(this));this.C=this.D;break;case 129:c=R(this,this.H+this.J+T(this)); +this.C=this.D;break;case 130:c=Pf(this,this.P+this.K+T(this));this.C=this.D;break;case 131:c=Pf(this,this.P+this.J+T(this));this.C=this.D;break;case 132:c=R(this,this.K+T(this));this.C=this.D;break;case 133:c=R(this,this.J+T(this));this.C=this.D;break;case 134:c=Pf(this,this.P+T(this));this.C=this.D;break;case 135:c=R(this,this.H+T(this));this.C=this.D;break;case 192:c=this.G&65535;break;case 193:c=this.I&65535;break;case 194:c=this.M&65535;break;case 195:c=this.H&65535;break;case 196:c=I(this)&65535; +break;case 197:c=this.P&65535;break;case 198:c=this.K&65535;break;case 199:c=this.J&65535;break;default:c=0}c=a[this.L>>3&7].call(this,c,b.call(this));switch(d){case 0:case 3:Sf(this,c);this.A-=this.B.ed;break;case 1:case 2:Sf(this,c);this.A-=this.B.fd;break;case 4:case 5:case 7:Sf(this,c);this.A-=this.B.Jc;break;case 6:Sf(this,c);this.A-=this.B.Ld;break;case 64:case 67:case 128:case 131:Sf(this,c);this.A-=this.B.ec;break;case 65:case 66:case 129:case 130:Sf(this,c);this.A-=this.B.fc;break;case 68:case 69:case 70:case 71:case 132:case 133:case 134:case 135:Sf(this, +c);this.A-=this.B.ib;break;case 192:this.G=this.G&-65536|c;break;case 193:this.I=this.I&-65536|c;break;case 194:this.M=this.M&-65536|c;break;case 195:this.H=this.H&-65536|c;break;case 196:G(this,I(this)&-65536|c);break;case 197:this.P=this.P&-65536|c;break;case 198:this.K=this.K&-65536|c;break;case 199:this.J=this.J&-65536|c}} +function Ge(a){var b,c;switch((this.L=this.xa())&199){case 0:c=S(this,this.H+this.K);this.A-=this.B.ed;break;case 1:c=S(this,this.H+this.J);this.A-=this.B.fd;break;case 2:c=Qf(this,this.P+this.K);this.A-=this.B.fd;break;case 3:c=Qf(this,this.P+this.J);this.A-=this.B.ed;break;case 4:c=S(this,this.K);this.A-=this.B.Jc;break;case 5:c=S(this,this.J);this.A-=this.B.Jc;break;case 6:c=S(this,T(this));this.A-=this.B.Ld;break;case 7:c=S(this,this.H);this.A-=this.B.Jc;break;case 64:c=S(this,this.H+this.K+this.T()); +this.A-=this.B.ec;break;case 65:c=S(this,this.H+this.J+this.T());this.A-=this.B.fc;break;case 66:c=Qf(this,this.P+this.K+this.T());this.A-=this.B.fc;break;case 67:c=Qf(this,this.P+this.J+this.T());this.A-=this.B.ec;break;case 68:c=S(this,this.K+this.T());this.A-=this.B.ib;break;case 69:c=S(this,this.J+this.T());this.A-=this.B.ib;break;case 70:c=Qf(this,this.P+this.T());this.A-=this.B.ib;break;case 71:c=S(this,this.H+this.T());this.A-=this.B.ib;break;case 128:c=S(this,this.H+this.K+T(this));this.A-= +this.B.ec;break;case 129:c=S(this,this.H+this.J+T(this));this.A-=this.B.fc;break;case 130:c=Qf(this,this.P+this.K+T(this));this.A-=this.B.fc;break;case 131:c=Qf(this,this.P+this.J+T(this));this.A-=this.B.ec;break;case 132:c=S(this,this.K+T(this));this.A-=this.B.ib;break;case 133:c=S(this,this.J+T(this));this.A-=this.B.ib;break;case 134:c=Qf(this,this.P+T(this));this.A-=this.B.ib;break;case 135:c=S(this,this.H+T(this));this.A-=this.B.ib;break;case 192:c=this.G;break;case 193:c=this.I;break;case 194:c= +this.M;break;case 195:c=this.H;break;case 196:c=I(this);break;case 197:c=this.P;break;case 198:c=this.K;break;case 199:c=this.J;break;default:c=0}var d=this.L>>3&7;switch(d){case 0:b=this.G;break;case 1:b=this.I;break;case 2:b=this.M;break;case 3:b=this.H;break;case 4:b=I(this);break;case 5:b=this.P;break;case 6:b=this.K;break;case 7:b=this.J;break;default:b=0}a=a.call(this,b,c);switch(d){case 0:this.G=a;break;case 1:this.I=a;break;case 2:this.M=a;break;case 3:this.H=a;break;case 4:G(this,a);break; +case 5:this.P=a;break;case 6:this.K=a;break;case 7:this.J=a}} +function He(a){var b,c,d=(this.L=this.xa())&199;switch(d){case 0:b=S(this,this.H+this.K);this.C=this.D;break;case 1:b=S(this,this.H+this.J);this.C=this.D;break;case 2:b=Qf(this,this.P+this.K);this.C=this.D;break;case 3:b=Qf(this,this.P+this.J);this.C=this.D;break;case 4:b=S(this,this.K);this.C=this.D;break;case 5:b=S(this,this.J);this.C=this.D;break;case 6:b=S(this,T(this));this.C=this.D;break;case 7:b=S(this,this.H);this.C=this.D;break;case 64:b=S(this,this.H+this.K+this.T());this.C=this.D;break; +case 65:b=S(this,this.H+this.J+this.T());this.C=this.D;break;case 66:b=Qf(this,this.P+this.K+this.T());this.C=this.D;break;case 67:b=Qf(this,this.P+this.J+this.T());this.C=this.D;break;case 68:b=S(this,this.K+this.T());this.C=this.D;break;case 69:b=S(this,this.J+this.T());this.C=this.D;break;case 70:b=Qf(this,this.P+this.T());this.C=this.D;break;case 71:b=S(this,this.H+this.T());this.C=this.D;break;case 128:b=S(this,this.H+this.K+T(this));this.C=this.D;break;case 129:b=S(this,this.H+this.J+T(this)); +this.C=this.D;break;case 130:b=Qf(this,this.P+this.K+T(this));this.C=this.D;break;case 131:b=Qf(this,this.P+this.J+T(this));this.C=this.D;break;case 132:b=S(this,this.K+T(this));this.C=this.D;break;case 133:b=S(this,this.J+T(this));this.C=this.D;break;case 134:b=Qf(this,this.P+T(this));this.C=this.D;break;case 135:b=S(this,this.H+T(this));this.C=this.D;break;case 192:b=this.G;break;case 193:b=this.I;break;case 194:b=this.M;break;case 195:b=this.H;break;case 196:b=I(this);break;case 197:b=this.P;break; +case 198:b=this.K;break;case 199:b=this.J;break;default:b=0}switch(this.L>>3&7){case 0:c=this.G;break;case 1:c=this.I;break;case 2:c=this.M;break;case 3:c=this.H;break;case 4:c=I(this);break;case 5:c=this.P;break;case 6:c=this.K;break;case 7:c=this.J;break;default:c=0}a=a.call(this,b,c);switch(d){case 0:case 3:Tf(this,a);this.A-=this.B.ed;break;case 1:case 2:Tf(this,a);this.A-=this.B.fd;break;case 4:case 5:case 7:Tf(this,a);this.A-=this.B.Jc;break;case 6:Tf(this,a);this.A-=this.B.Ld;break;case 64:case 67:case 128:case 131:Tf(this, +a);this.A-=this.B.ec;break;case 65:case 66:case 129:case 130:Tf(this,a);this.A-=this.B.fc;break;case 68:case 69:case 70:case 71:case 132:case 133:case 134:case 135:Tf(this,a);this.A-=this.B.ib;break;case 192:this.G=a;break;case 193:this.I=a;break;case 194:this.M=a;break;case 195:this.H=a;break;case 196:G(this,a);break;case 197:this.P=a;break;case 198:this.K=a;break;case 199:this.J=a}} +function Ie(a,b){var c,d=(this.L=this.xa())&199;switch(d){case 0:c=S(this,this.H+this.K);this.C=this.D;break;case 1:c=S(this,this.H+this.J);this.C=this.D;break;case 2:c=Qf(this,this.P+this.K);this.C=this.D;break;case 3:c=Qf(this,this.P+this.J);this.C=this.D;break;case 4:c=S(this,this.K);this.C=this.D;break;case 5:c=S(this,this.J);this.C=this.D;break;case 6:c=S(this,T(this));this.C=this.D;break;case 7:c=S(this,this.H);this.C=this.D;break;case 64:c=S(this,this.H+this.K+this.T());this.C=this.D;break; +case 65:c=S(this,this.H+this.J+this.T());this.C=this.D;break;case 66:c=Qf(this,this.P+this.K+this.T());this.C=this.D;break;case 67:c=Qf(this,this.P+this.J+this.T());this.C=this.D;break;case 68:c=S(this,this.K+this.T());this.C=this.D;break;case 69:c=S(this,this.J+this.T());this.C=this.D;break;case 70:c=Qf(this,this.P+this.T());this.C=this.D;break;case 71:c=S(this,this.H+this.T());this.C=this.D;break;case 128:c=S(this,this.H+this.K+T(this));this.C=this.D;break;case 129:c=S(this,this.H+this.J+T(this)); +this.C=this.D;break;case 130:c=Qf(this,this.P+this.K+T(this));this.C=this.D;break;case 131:c=Qf(this,this.P+this.J+T(this));this.C=this.D;break;case 132:c=S(this,this.K+T(this));this.C=this.D;break;case 133:c=S(this,this.J+T(this));this.C=this.D;break;case 134:c=Qf(this,this.P+T(this));this.C=this.D;break;case 135:c=S(this,this.H+T(this));this.C=this.D;break;case 192:c=this.G;break;case 193:c=this.I;break;case 194:c=this.M;break;case 195:c=this.H;break;case 196:c=I(this);break;case 197:c=this.P;break; +case 198:c=this.K;break;case 199:c=this.J}c=a[this.L>>3&7].call(this,c,b.call(this));switch(d){case 0:case 3:Tf(this,c);this.A-=this.B.ed;break;case 1:case 2:Tf(this,c);this.A-=this.B.fd;break;case 4:case 5:case 7:Tf(this,c);this.A-=this.B.Jc;break;case 6:Tf(this,c);this.A-=this.B.Ld;break;case 64:case 67:case 128:case 131:Tf(this,c);this.A-=this.B.ec;break;case 65:case 66:case 129:case 130:Tf(this,c);this.A-=this.B.fc;break;case 68:case 69:case 70:case 71:case 132:case 133:case 134:case 135:Tf(this, +c);this.A-=this.B.ib;break;case 192:this.G=c;break;case 193:this.I=c;break;case 194:this.M=c;break;case 195:this.H=c;break;case 196:G(this,c);break;case 197:this.P=c;break;case 198:this.K=c;break;case 199:this.J=c}} +function Le(a){var b,c;switch((this.L=this.xa())&199){case 0:c=Q(this,this.G);break;case 1:c=Q(this,this.I);break;case 2:c=Q(this,this.M);break;case 3:c=Q(this,this.H);break;case 4:c=Q(this,Ej.call(this,0));break;case 5:c=Q(this,T(this));break;case 6:c=Q(this,this.K);break;case 7:c=Q(this,this.J);break;case 64:c=Q(this,this.G+this.T());break;case 65:c=Q(this,this.I+this.T());break;case 66:c=Q(this,this.M+this.T());break;case 67:c=Q(this,this.H+this.T());break;case 68:c=Q(this,Ej.call(this,1)+this.T()); +break;case 69:c=Nf(this,this.P+this.T());break;case 70:c=Q(this,this.K+this.T());break;case 71:c=Q(this,this.J+this.T());break;case 128:c=Q(this,this.G+T(this));break;case 129:c=Q(this,this.I+T(this));break;case 130:c=Q(this,this.M+T(this));break;case 131:c=Q(this,this.H+T(this));break;case 132:c=Q(this,Ej.call(this,2)+T(this));break;case 133:c=Nf(this,this.P+T(this));break;case 134:c=Q(this,this.K+T(this));break;case 135:c=Q(this,this.J+T(this));break;case 192:c=this.G&255;break;case 193:c=this.I& +255;break;case 194:c=this.M&255;break;case 195:c=this.H&255;break;case 196:c=this.G>>8&255;break;case 197:c=this.I>>8&255;break;case 198:c=this.M>>8&255;break;case 199:c=this.H>>8&255;break;default:c=0}var d=this.L>>3&7;switch(d){case 0:b=this.G&255;break;case 1:b=this.I&255;break;case 2:b=this.M&255;break;case 3:b=this.H&255;break;case 4:b=this.G>>8&255;break;case 5:b=this.I>>8&255;break;case 6:b=this.M>>8&255;break;case 7:b=this.H>>8&255;break;default:b=0}a=a.call(this,b,c);switch(d){case 0:this.G= +this.G&-256|a;break;case 1:this.I=this.I&-256|a;break;case 2:this.M=this.M&-256|a;break;case 3:this.H=this.H&-256|a;break;case 4:this.G=this.G&-65281|a<<8;break;case 5:this.I=this.I&-65281|a<<8;break;case 6:this.M=this.M&-65281|a<<8;break;case 7:this.H=this.H&-65281|a<<8}} +function Me(a){var b,c,d=(this.L=this.xa())&199;switch(d){case 0:b=Q(this,this.G);this.C=this.D;break;case 1:b=Q(this,this.I);this.C=this.D;break;case 2:b=Q(this,this.M);this.C=this.D;break;case 3:b=Q(this,this.H);this.C=this.D;break;case 4:b=Q(this,Ej.call(this,0));this.C=this.D;break;case 5:b=Q(this,T(this));this.C=this.D;break;case 6:b=Q(this,this.K);this.C=this.D;break;case 7:b=Q(this,this.J);this.C=this.D;break;case 64:b=Q(this,this.G+this.T());this.C=this.D;break;case 65:b=Q(this,this.I+this.T()); +this.C=this.D;break;case 66:b=Q(this,this.M+this.T());this.C=this.D;break;case 67:b=Q(this,this.H+this.T());this.C=this.D;break;case 68:b=Q(this,Ej.call(this,1)+this.T());this.C=this.D;break;case 69:b=Nf(this,this.P+this.T());this.C=this.D;break;case 70:b=Q(this,this.K+this.T());this.C=this.D;break;case 71:b=Q(this,this.J+this.T());this.C=this.D;break;case 128:b=Q(this,this.G+T(this));this.C=this.D;break;case 129:b=Q(this,this.I+T(this));this.C=this.D;break;case 130:b=Q(this,this.M+T(this));this.C= +this.D;break;case 131:b=Q(this,this.H+T(this));this.C=this.D;break;case 132:b=Q(this,Ej.call(this,2)+T(this));this.C=this.D;break;case 133:b=Nf(this,this.P+T(this));this.C=this.D;break;case 134:b=Q(this,this.K+T(this));this.C=this.D;break;case 135:b=Q(this,this.J+T(this));this.C=this.D;break;case 192:b=this.G&255;break;case 193:b=this.I&255;break;case 194:b=this.M&255;break;case 195:b=this.H&255;break;case 196:b=this.G>>8&255;break;case 197:b=this.I>>8&255;break;case 198:b=this.M>>8&255;break;case 199:b= +this.H>>8&255;break;default:b=0}switch(this.L>>3&7){case 0:c=this.G&255;break;case 1:c=this.I&255;break;case 2:c=this.M&255;break;case 3:c=this.H&255;break;case 4:c=this.G>>8&255;break;case 5:c=this.I>>8&255;break;case 6:c=this.M>>8&255;break;case 7:c=this.H>>8&255;break;default:c=0}a=a.call(this,b,c);switch(d){case 192:this.G=this.G&-256|a;break;case 193:this.I=this.I&-256|a;break;case 194:this.M=this.M&-256|a;break;case 195:this.H=this.H&-256|a;break;case 196:this.G=this.G&-65281|a<<8;break;case 197:this.I= +this.I&-65281|a<<8;break;case 198:this.M=this.M&-65281|a<<8;break;case 199:this.H=this.H&-65281|a<<8;break;default:Rf(this,a)}} +function Ne(a,b){var c,d=(this.L=this.xa())&199;switch(d){case 0:c=Q(this,this.G);this.C=this.D;break;case 1:c=Q(this,this.I);this.C=this.D;break;case 2:c=Q(this,this.M);this.C=this.D;break;case 3:c=Q(this,this.H);this.C=this.D;break;case 4:c=Q(this,Ej.call(this,0));this.C=this.D;break;case 5:c=Q(this,T(this));this.C=this.D;break;case 6:c=Q(this,this.K);this.C=this.D;break;case 7:c=Q(this,this.J);this.C=this.D;break;case 64:c=Q(this,this.G+this.T());this.C=this.D;break;case 65:c=Q(this,this.I+this.T()); +this.C=this.D;break;case 66:c=Q(this,this.M+this.T());this.C=this.D;break;case 67:c=Q(this,this.H+this.T());this.C=this.D;break;case 68:c=Q(this,Ej.call(this,1)+this.T());this.C=this.D;break;case 69:c=Nf(this,this.P+this.T());this.C=this.D;break;case 70:c=Q(this,this.K+this.T());this.C=this.D;break;case 71:c=Q(this,this.J+this.T());this.C=this.D;break;case 128:c=Q(this,this.G+T(this));this.C=this.D;break;case 129:c=Q(this,this.I+T(this));this.C=this.D;break;case 130:c=Q(this,this.M+T(this));this.C= +this.D;break;case 131:c=Q(this,this.H+T(this));this.C=this.D;break;case 132:c=Q(this,Ej.call(this,2)+T(this));this.C=this.D;break;case 133:c=Nf(this,this.P+T(this));this.C=this.D;break;case 134:c=Q(this,this.K+T(this));this.C=this.D;break;case 135:c=Q(this,this.J+T(this));this.C=this.D;break;case 192:c=this.G&255;break;case 193:c=this.I&255;break;case 194:c=this.M&255;break;case 195:c=this.H&255;break;case 196:c=this.G>>8&255;break;case 197:c=this.I>>8&255;break;case 198:c=this.M>>8&255;break;case 199:c= +this.H>>8&255;break;default:c=0}c=a[this.L>>3&7].call(this,c,b.call(this));switch(d){case 192:this.G=this.G&-256|c;break;case 193:this.I=this.I&-256|c;break;case 194:this.M=this.M&-256|c;break;case 195:this.H=this.H&-256|c;break;case 196:this.G=this.G&-65281|c<<8;break;case 197:this.I=this.I&-65281|c<<8;break;case 198:this.M=this.M&-65281|c<<8;break;case 199:this.H=this.H&-65281|c<<8;break;default:Rf(this,c)}} +function Oe(a){var b,c;switch((this.L=this.xa())&199){case 0:c=R(this,this.G);break;case 1:c=R(this,this.I);break;case 2:c=R(this,this.M);break;case 3:c=R(this,this.H);break;case 4:c=R(this,Ej.call(this,0));break;case 5:c=R(this,T(this));break;case 6:c=R(this,this.K);break;case 7:c=R(this,this.J);break;case 64:c=R(this,this.G+this.T());break;case 65:c=R(this,this.I+this.T());break;case 66:c=R(this,this.M+this.T());break;case 67:c=R(this,this.H+this.T());break;case 68:c=R(this,Ej.call(this,1)+this.T()); +break;case 69:c=Pf(this,this.P+this.T());break;case 70:c=R(this,this.K+this.T());break;case 71:c=R(this,this.J+this.T());break;case 128:c=R(this,this.G+T(this));break;case 129:c=R(this,this.I+T(this));break;case 130:c=R(this,this.M+T(this));break;case 131:c=R(this,this.H+T(this));break;case 132:c=R(this,Ej.call(this,2)+T(this));break;case 133:c=Pf(this,this.P+T(this));break;case 134:c=R(this,this.K+T(this));break;case 135:c=R(this,this.J+T(this));break;case 192:c=this.G&65535;break;case 193:c=this.I& +65535;break;case 194:c=this.M&65535;break;case 195:c=this.H&65535;break;case 196:c=I(this)&65535;break;case 197:c=this.P&65535;break;case 198:c=this.K&65535;break;case 199:c=this.J&65535;break;default:c=0}var d=this.L>>3&7;switch(d){case 0:b=this.G&65535;break;case 1:b=this.I&65535;break;case 2:b=this.M&65535;break;case 3:b=this.H&65535;break;case 4:b=I(this)&65535;break;case 5:b=this.P&65535;break;case 6:b=this.K&65535;break;case 7:b=this.J&65535;break;default:b=0}a=a.call(this,b,c);switch(d){case 0:this.G= +this.G&-65536|a;break;case 1:this.I=this.I&-65536|a;break;case 2:this.M=this.M&-65536|a;break;case 3:this.H=this.H&-65536|a;break;case 4:G(this,I(this)&-65536|a);break;case 5:this.P=this.P&-65536|a;break;case 6:this.K=this.K&-65536|a;break;case 7:this.J=this.J&-65536|a}} +function Pe(a){var b,c,d=(this.L=this.xa())&199;switch(d){case 0:b=R(this,this.G);this.C=this.D;break;case 1:b=R(this,this.I);this.C=this.D;break;case 2:b=R(this,this.M);this.C=this.D;break;case 3:b=R(this,this.H);this.C=this.D;break;case 4:b=R(this,Ej.call(this,0));this.C=this.D;break;case 5:b=R(this,T(this));this.C=this.D;break;case 6:b=R(this,this.K);this.C=this.D;break;case 7:b=R(this,this.J);this.C=this.D;break;case 64:b=R(this,this.G+this.T());this.C=this.D;break;case 65:b=R(this,this.I+this.T()); +this.C=this.D;break;case 66:b=R(this,this.M+this.T());this.C=this.D;break;case 67:b=R(this,this.H+this.T());this.C=this.D;break;case 68:b=R(this,Ej.call(this,1)+this.T());this.C=this.D;break;case 69:b=Pf(this,this.P+this.T());this.C=this.D;break;case 70:b=R(this,this.K+this.T());this.C=this.D;break;case 71:b=R(this,this.J+this.T());this.C=this.D;break;case 128:b=R(this,this.G+T(this));this.C=this.D;break;case 129:b=R(this,this.I+T(this));this.C=this.D;break;case 130:b=R(this,this.M+T(this));this.C= +this.D;break;case 131:b=R(this,this.H+T(this));this.C=this.D;break;case 132:b=R(this,Ej.call(this,2)+T(this));this.C=this.D;break;case 133:b=Pf(this,this.P+T(this));this.C=this.D;break;case 134:b=R(this,this.K+T(this));this.C=this.D;break;case 135:b=R(this,this.J+T(this));this.C=this.D;break;case 192:b=this.G&65535;break;case 193:b=this.I&65535;break;case 194:b=this.M&65535;break;case 195:b=this.H&65535;break;case 196:b=I(this)&65535;break;case 197:b=this.P&65535;break;case 198:b=this.K&65535;break; +case 199:b=this.J&65535;break;default:b=0}switch(this.L>>3&7){case 0:c=this.G&65535;break;case 1:c=this.I&65535;break;case 2:c=this.M&65535;break;case 3:c=this.H&65535;break;case 4:c=I(this)&65535;break;case 5:c=this.P&65535;break;case 6:c=this.K&65535;break;case 7:c=this.J&65535;break;default:c=0}a=a.call(this,b,c);switch(d){case 192:this.G=this.G&-65536|a;break;case 193:this.I=this.I&-65536|a;break;case 194:this.M=this.M&-65536|a;break;case 195:this.H=this.H&-65536|a;break;case 196:G(this,I(this)& +-65536|a);break;case 197:this.P=this.P&-65536|a;break;case 198:this.K=this.K&-65536|a;break;case 199:this.J=this.J&-65536|a;break;default:Sf(this,a)}} +function Qe(a,b){var c,d=(this.L=this.xa())&199;switch(d){case 0:c=R(this,this.G);this.C=this.D;break;case 1:c=R(this,this.I);this.C=this.D;break;case 2:c=R(this,this.M);this.C=this.D;break;case 3:c=R(this,this.H);this.C=this.D;break;case 4:c=R(this,Ej.call(this,0));this.C=this.D;break;case 5:c=R(this,T(this));this.C=this.D;break;case 6:c=R(this,this.K);this.C=this.D;break;case 7:c=R(this,this.J);this.C=this.D;break;case 64:c=R(this,this.G+this.T());this.C=this.D;break;case 65:c=R(this,this.I+this.T()); +this.C=this.D;break;case 66:c=R(this,this.M+this.T());this.C=this.D;break;case 67:c=R(this,this.H+this.T());this.C=this.D;break;case 68:c=R(this,Ej.call(this,1)+this.T());this.C=this.D;break;case 69:c=Pf(this,this.P+this.T());this.C=this.D;break;case 70:c=R(this,this.K+this.T());this.C=this.D;break;case 71:c=R(this,this.J+this.T());this.C=this.D;break;case 128:c=R(this,this.G+T(this));this.C=this.D;break;case 129:c=R(this,this.I+T(this));this.C=this.D;break;case 130:c=R(this,this.M+T(this));this.C= +this.D;break;case 131:c=R(this,this.H+T(this));this.C=this.D;break;case 132:c=R(this,Ej.call(this,2)+T(this));this.C=this.D;break;case 133:c=Pf(this,this.P+T(this));this.C=this.D;break;case 134:c=R(this,this.K+T(this));this.C=this.D;break;case 135:c=R(this,this.J+T(this));this.C=this.D;break;case 192:c=this.G&65535;break;case 193:c=this.I&65535;break;case 194:c=this.M&65535;break;case 195:c=this.H&65535;break;case 196:c=I(this)&65535;break;case 197:c=this.P&65535;break;case 198:c=this.K&65535;break; +case 199:c=this.J&65535;break;default:c=0}c=a[this.L>>3&7].call(this,c,b.call(this));switch(d){case 192:this.G=this.G&-65536|c;break;case 193:this.I=this.I&-65536|c;break;case 194:this.M=this.M&-65536|c;break;case 195:this.H=this.H&-65536|c;break;case 196:G(this,I(this)&-65536|c);break;case 197:this.P=this.P&-65536|c;break;case 198:this.K=this.K&-65536|c;break;case 199:this.J=this.J&-65536|c;break;default:Sf(this,c)}} +function Re(a){var b,c;switch((this.L=this.xa())&199){case 0:c=S(this,this.G);break;case 1:c=S(this,this.I);break;case 2:c=S(this,this.M);break;case 3:c=S(this,this.H);break;case 4:c=S(this,Ej.call(this,0));break;case 5:c=S(this,T(this));break;case 6:c=S(this,this.K);break;case 7:c=S(this,this.J);break;case 64:c=S(this,this.G+this.T());break;case 65:c=S(this,this.I+this.T());break;case 66:c=S(this,this.M+this.T());break;case 67:c=S(this,this.H+this.T());break;case 68:c=S(this,Ej.call(this,1)+this.T()); +break;case 69:c=Qf(this,this.P+this.T());break;case 70:c=S(this,this.K+this.T());break;case 71:c=S(this,this.J+this.T());break;case 128:c=S(this,this.G+T(this));break;case 129:c=S(this,this.I+T(this));break;case 130:c=S(this,this.M+T(this));break;case 131:c=S(this,this.H+T(this));break;case 132:c=S(this,Ej.call(this,2)+T(this));break;case 133:c=Qf(this,this.P+T(this));break;case 134:c=S(this,this.K+T(this));break;case 135:c=S(this,this.J+T(this));break;case 192:c=this.G;break;case 193:c=this.I;break; +case 194:c=this.M;break;case 195:c=this.H;break;case 196:c=I(this);break;case 197:c=this.P;break;case 198:c=this.K;break;case 199:c=this.J;break;default:c=0}var d=this.L>>3&7;switch(d){case 0:b=this.G;break;case 1:b=this.I;break;case 2:b=this.M;break;case 3:b=this.H;break;case 4:b=I(this);break;case 5:b=this.P;break;case 6:b=this.K;break;case 7:b=this.J;break;default:b=0}a=a.call(this,b,c);switch(d){case 0:this.G=a;break;case 1:this.I=a;break;case 2:this.M=a;break;case 3:this.H=a;break;case 4:G(this, +a);break;case 5:this.P=a;break;case 6:this.K=a;break;case 7:this.J=a}} +function Se(a){var b,c,d=(this.L=this.xa())&199;switch(d){case 0:b=S(this,this.G);this.C=this.D;break;case 1:b=S(this,this.I);this.C=this.D;break;case 2:b=S(this,this.M);this.C=this.D;break;case 3:b=S(this,this.H);this.C=this.D;break;case 4:b=S(this,Ej.call(this,0));this.C=this.D;break;case 5:b=S(this,T(this));this.C=this.D;break;case 6:b=S(this,this.K);this.C=this.D;break;case 7:b=S(this,this.J);this.C=this.D;break;case 64:b=S(this,this.G+this.T());this.C=this.D;break;case 65:b=S(this,this.I+this.T()); +this.C=this.D;break;case 66:b=S(this,this.M+this.T());this.C=this.D;break;case 67:b=S(this,this.H+this.T());this.C=this.D;break;case 68:b=S(this,Ej.call(this,1)+this.T());this.C=this.D;break;case 69:b=Qf(this,this.P+this.T());this.C=this.D;break;case 70:b=S(this,this.K+this.T());this.C=this.D;break;case 71:b=S(this,this.J+this.T());this.C=this.D;break;case 128:b=S(this,this.G+T(this));this.C=this.D;break;case 129:b=S(this,this.I+T(this));this.C=this.D;break;case 130:b=S(this,this.M+T(this));this.C= +this.D;break;case 131:b=S(this,this.H+T(this));this.C=this.D;break;case 132:b=S(this,Ej.call(this,2)+T(this));this.C=this.D;break;case 133:b=Qf(this,this.P+T(this));this.C=this.D;break;case 134:b=S(this,this.K+T(this));this.C=this.D;break;case 135:b=S(this,this.J+T(this));this.C=this.D;break;case 192:b=this.G;break;case 193:b=this.I;break;case 194:b=this.M;break;case 195:b=this.H;break;case 196:b=I(this);break;case 197:b=this.P;break;case 198:b=this.K;break;case 199:b=this.J;break;default:b=0}switch(this.L>> +3&7){case 0:c=this.G;break;case 1:c=this.I;break;case 2:c=this.M;break;case 3:c=this.H;break;case 4:c=I(this);break;case 5:c=this.P;break;case 6:c=this.K;break;case 7:c=this.J;break;default:c=0}a=a.call(this,b,c);switch(d){case 192:this.G=a;break;case 193:this.I=a;break;case 194:this.M=a;break;case 195:this.H=a;break;case 196:G(this,a);break;case 197:this.P=a;break;case 198:this.K=a;break;case 199:this.J=a;break;default:Tf(this,a)}} +function Te(a,b){var c,d=(this.L=this.xa())&199;switch(d){case 0:c=S(this,this.G);this.C=this.D;break;case 1:c=S(this,this.I);this.C=this.D;break;case 2:c=S(this,this.M);this.C=this.D;break;case 3:c=S(this,this.H);this.C=this.D;break;case 4:c=S(this,Ej.call(this,0));this.C=this.D;break;case 5:c=S(this,T(this));this.C=this.D;break;case 6:c=S(this,this.K);this.C=this.D;break;case 7:c=S(this,this.J);this.C=this.D;break;case 64:c=S(this,this.G+this.T());this.C=this.D;break;case 65:c=S(this,this.I+this.T()); +this.C=this.D;break;case 66:c=S(this,this.M+this.T());this.C=this.D;break;case 67:c=S(this,this.H+this.T());this.C=this.D;break;case 68:c=S(this,Ej.call(this,1)+this.T());this.C=this.D;break;case 69:c=Qf(this,this.P+this.T());this.C=this.D;break;case 70:c=S(this,this.K+this.T());this.C=this.D;break;case 71:c=S(this,this.J+this.T());this.C=this.D;break;case 128:c=S(this,this.G+T(this));this.C=this.D;break;case 129:c=S(this,this.I+T(this));this.C=this.D;break;case 130:c=S(this,this.M+T(this));this.C= +this.D;break;case 131:c=S(this,this.H+T(this));this.C=this.D;break;case 132:c=S(this,Ej.call(this,2)+T(this));this.C=this.D;break;case 133:c=Qf(this,this.P+T(this));this.C=this.D;break;case 134:c=S(this,this.K+T(this));this.C=this.D;break;case 135:c=S(this,this.J+T(this));this.C=this.D;break;case 192:c=this.G;break;case 193:c=this.I;break;case 194:c=this.M;break;case 195:c=this.H;break;case 196:c=I(this);break;case 197:c=this.P;break;case 198:c=this.K;break;case 199:c=this.J;break;default:c=0}c=a[this.L>> +3&7].call(this,c,b.call(this));switch(d){case 192:this.G=c;break;case 193:this.I=c;break;case 194:this.M=c;break;case 195:this.H=c;break;case 196:G(this,c);break;case 197:this.P=c;break;case 198:this.K=c;break;case 199:this.J=c;break;default:Tf(this,c)}} +function Ej(a){var b=this.xa(),c=b>>6,d,e;switch(b>>3&7){case 0:d=this.G;break;case 1:d=this.I;break;case 2:d=this.M;break;case 3:d=this.H;break;case 4:d=0;break;case 5:d=this.P;break;case 6:d=this.K;break;case 7:d=this.J}switch(b&7){case 0:e=this.G;break;case 1:e=this.I;break;case 2:e=this.M;break;case 3:e=this.H;break;case 4:e=I(this);this.ka=this.Ka;break;case 5:a?(e=this.P,this.ka=this.Ka):e=T(this);break;case 6:e=this.K;break;case 7:e=this.J}return(d<>8&255;9<(c&15)||uf(this)?(c+=6,80286<=this.ja&&255>8&255;9<(c&15)||uf(this)?(c=c-6&15,d=d-1&255,a=b=1):a=b=0;this.G=this.G&-65536|d<<8|c;a?zf(this):Af(this);b?Hf(this):Ff(this);this.A-=this.B.He},function(){this.G=rj.call(this,this.G)},function(){this.I=rj.call(this,this.I)},function(){this.M=rj.call(this,this.M)},function(){this.H=rj.call(this,this.H)},function(){G(this,rj.call(this, +I(this)))},function(){this.P=rj.call(this,this.P)},function(){this.K=rj.call(this,this.K)},function(){this.J=rj.call(this,this.J)},function(){this.G=pj.call(this,this.G)},function(){this.I=pj.call(this,this.I)},function(){this.M=pj.call(this,this.M)},function(){this.H=pj.call(this,this.H)},function(){G(this,pj.call(this,I(this)))},function(){this.P=pj.call(this,this.P)},function(){this.K=pj.call(this,this.K)},function(){this.J=pj.call(this,this.J)},function(){J(this,this.G&this.R);this.A-=this.B.Sc}, +function(){J(this,this.I&this.R);this.A-=this.B.Sc},function(){J(this,this.M&this.R);this.A-=this.B.Sc},function(){J(this,this.H&this.R);this.A-=this.B.Sc},function(){J(this,I(this)-2&65535);this.A-=this.B.Sc},function(){J(this,this.P&this.R);this.A-=this.B.Sc},function(){J(this,this.K&this.R);this.A-=this.B.Sc},function(){J(this,this.J&this.R);this.A-=this.B.Sc},function(){this.G=this.G&~this.R|D(this);this.A-=this.B.zc},function(){this.I=this.I&~this.R|D(this);this.A-=this.B.zc},function(){this.M= +this.M&~this.R|D(this);this.A-=this.B.zc},function(){this.H=this.H&~this.R|D(this);this.A-=this.B.zc},function(){G(this,I(this)&~this.R|D(this));this.A-=this.B.zc},function(){this.P=this.P&~this.R|D(this);this.A-=this.B.zc},function(){this.K=this.K&~this.R|D(this);this.A-=this.B.zc},function(){this.J=this.J&~this.R|D(this);this.A-=this.B.zc},Fj,Gj,Hj,Ij,Jj,Kj,Lj,Mj,Nj,Oj,Pj,Qj,Rj,Sj,Tj,Uj,Fj,Gj,Hj,Ij,Jj,Kj,Lj,Mj,Nj,Oj,Pj,Qj,Rj,Sj,Tj,Uj,Vj,function(){this.ya.call(this,kk,this.Ma);this.A-=-1===this.C? +1:this.B.Fg},Vj,function(){this.ya.call(this,kk,this.T);this.A-=-1===this.C?1:this.B.Fg},function(){this.$a.call(this,gj)},function(){this.ea.call(this,hj)},function(){this.Oa.call(this,kj)},function(){this.V.call(this,lj)},Xj,Yj,Zj,ak,function(){this.S|=1;this.ea.call(this,ii)},function(){this.S|=1;this.ka=this.Ka=this.rf;this.V.call(this,Zh)},function(){var a;this.V.call(this,hi);switch(this.L>>3&7){case 0:a=this.G;this.G=this.aa;yd(this,a);break;case 1:a=this.I;this.I=this.aa;nf(this,a);break; +case 2:a=this.M;this.M=this.aa;md(this,a);break;case 3:a=this.H;this.H=this.aa;xd(this,a);break;case 4:a=I(this);G(this,this.aa);80386<=this.ja?this.Nb.load(a):yd(this,a);break;case 5:a=this.P;this.P=this.aa;80386<=this.ja?this.Ob.load(a):nf(this,a);break;case 6:a=this.K;this.K=this.aa;md(this,a);break;case 7:a=this.J,this.J=this.aa,xd(this,a)}},function(){this.S|=1;this.U=this.fa;this.aa=D(this);this.ya.call(this,lk,yj);this.U=-1},function(){this.A-=3},function(){var a=this.G;this.G=this.G&~this.R| +this.I&this.R;this.I=this.I&~this.R|a&this.R;this.A-=3},function(){var a=this.G;this.G=this.G&~this.R|this.M&this.R;this.M=this.M&~this.R|a&this.R;this.A-=3},function(){var a=this.G;this.G=this.G&~this.R|this.H&this.R;this.H=this.H&~this.R|a&this.R;this.A-=3},function(){var a=this.G,b=I(this);this.G=this.G&~this.R|b&this.R;G(this,b&~this.R|a&this.R);this.A-=3},function(){var a=this.G;this.G=this.G&~this.R|this.P&this.R;this.P=this.P&~this.R|a&this.R;this.A-=3},function(){var a=this.G;this.G=this.G& +~this.R|this.K&this.R;this.K=this.K&~this.R|a&this.R;this.A-=3},function(){var a=this.G;this.G=this.G&~this.R|this.J&this.R;this.J=this.J&~this.R|a&this.R;this.A-=3},function(){this.G=2==this.ba?this.G&-65536|this.G<<24>>24&65535:this.G<<16>>16;this.A-=2},function(){this.M=2==this.ba?this.M&-65536|(this.G&32768?65535:0):this.G&-2147483648?-1:0;this.A-=this.B.gj},function(){zj.call(this,this.Ma(),Uf(this));this.A-=this.B.jj},function(){this.A-=3},function(){var a=zd(this);a&131072&&3>this.Pa?C.call(this, +13,0):(J(this,a&-196609),this.A-=this.B.Sc)},function(){if(this.ca&131072&&3>this.Pa)C.call(this,13,0);else{var a=D(this),a=a&65535|this.ca&-65536;Ad(this,a);this.A-=this.B.zc}},function(){var a=this.G>>8&255;a&1?zf(this):Af(this);a&4?(this.resultType&=-3,this.ca|=4):(this.resultType&=-3,this.ca&=-5);a&16?Hf(this):Ff(this);a&64?If(this):Gf(this);a&128?(this.resultType&=-17,this.ca|=128):(this.resultType&=-17,this.ca&=-129);this.A-=this.B.gc},function(){this.G=this.G&-65281|(zd(this)&213)<<8;this.A-= +this.B.gc},function(){var a=this.G&-256,b;b=T(this);b=this.Qa(this.ka.mc(b,1));this.G=a|b;this.A-=this.B.Lh},function(){this.G=this.G&~this.R|vd(this,this.ka,T(this));this.A-=this.B.Lh},function(){var a=T(this),b=this.G;this.qc(this.ka.nc(a,1),b);this.A-=this.B.Mh},function(){var a=T(this),b=this.G;this.rc(this.ka.nc(a,this.ba),b);this.A-=this.B.Mh},function(){var a=1,b=0,c=this.Ba,d=this.B.Nh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Ph,this.Ia&256||(this.A-=this.B.Oh));if(a--){var e=this.Qa(this.ka.mc(this.K& +c,1));this.qc(this.Xa.nc(this.J&c,1),e);e=this.ca&1024?-1:1;this.K=this.K&~c|this.K+e&c;this.J=this.J&~c|this.J+e&c;this.A-=d;this.I=this.I&~c|this.I-b&c;a&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.Nh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Ph,this.Ia&256||(this.A-=this.B.Oh));if(a--){var e=vd(this,this.ka,this.K&c);this.rc(this.Xa.nc(this.J&c,this.ba),e);e=this.ca&1024?-this.ba:this.ba;this.K=this.K&~c|this.K+e&c;this.J=this.J&~c|this.J+e&c;this.A-=d;this.I=this.I&~c|this.I- +b&c;a&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.yh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Ah,this.Ia&256||(this.A-=this.B.zh));if(a--){var e=Mf(this,this.ka,this.K),f=Mf(this,this.Xa,this.J);this.C=this.D;Mh.call(this,e,f);e=this.ca&1024?-1:1;this.K=this.K&~c|this.K+e&c;this.J=this.J&~c|this.J+e&c;this.I=this.I&~c|this.I-b&c;this.A-=d-this.B.Vb;a&&vf(this)==(this.Ia&64)&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.yh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Ah, +this.Ia&256||(this.A-=this.B.zh));if(a--){var e=Of(this,this.ka,this.K&c),f=Of(this,this.Xa,this.J&c);this.C=this.D;Nh.call(this,e,f);e=this.ca&1024?-this.ba:this.ba;this.K=this.K&~c|this.K+e&c;this.J=this.J&~c|this.J+e&c;this.I=this.I&~c|this.I-b&c;this.A-=d-this.B.Vb;a&&vf(this)==(this.Ia&64)&&(qf(this),this.S|=256)}},function(){yf(this,this.G&this.xa(),128);this.A-=this.B.He},function(){yf(this,this.G&this.Ma(),this.Ga);this.A-=this.B.He},function(){var a=1,b=0,c=this.Ba,d=this.B.Yh;this.Ia&192&& +(a=this.I&c,b=1,d=this.B.$h,this.Ia&256||(this.A-=this.B.Zh));if(a--){var e=this.G;this.qc(this.Xa.nc(this.J&c,1),e);this.I=this.I&~c|this.I-b&c;80546<=this.Uc&&80564>=this.Uc&&!(this.Ia&2048)!=(103!=this.Qa(this.Ha))&&(c^=-65536);this.J=this.J&~c|this.J+(this.ca&1024?-1:1)&c;this.A-=d;a&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.Yh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.$h,this.Ia&256||(this.A-=this.B.Zh));if(a--){var e=this.G;this.rc(this.Xa.nc(this.J&c,this.ba),e);this.J= +this.J&~c|this.J+(this.ca&1024?-this.ba:this.ba)&c;this.I=this.I&~c|this.I-b&c;this.A-=d;a&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.Fh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Hh,this.Ia&256||(this.A-=this.B.Gh));if(a--){var e=this.Qa(this.ka.mc(this.K&c,1));this.G=this.G&-256|e;this.K=this.K&~c|this.K+(this.ca&1024?-1:1)&c;this.I=this.I&~c|this.I-b&c;this.A-=d;a&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.Fh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Hh, +this.Ia&256||(this.A-=this.B.Gh));if(a--){var e=vd(this,this.ka,this.K&c);this.G=this.G&~this.R|e;this.K=this.K&~c|this.K+(this.ca&1024?-this.ba:this.ba)&c;this.I=this.I&~c|this.I-b&c;this.A-=d;a&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.Sh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Uh,this.Ia&256||(this.A-=this.B.Th));if(a--){var e=this.G&255,f=Mf(this,this.Xa,this.J);this.C=this.D;Mh.call(this,e,f);this.J=this.J&~c|this.J+(this.ca&1024?-1:1)&c;this.I=this.I&~c|this.I-b&c;this.A-= +d-this.B.Vb;a&&vf(this)==(this.Ia&64)&&(qf(this),this.S|=256)}},function(){var a=1,b=0,c=this.Ba,d=this.B.Sh;this.Ia&192&&(a=this.I&c,b=1,d=this.B.Uh,this.Ia&256||(this.A-=this.B.Th));if(a--){var e=this.G&this.R,f=Of(this,this.Xa,this.J&c);this.C=this.D;Nh.call(this,e,f);this.J=this.J&~c|this.J+(this.ca&1024?-this.ba:this.ba)&c;this.I=this.I&~c|this.I-b&c;this.A-=d-this.B.Vb;a&&vf(this)==(this.Ia&64)&&(qf(this),this.S|=256)}},function(){this.G=this.G&-256|this.xa();this.A-=this.B.gc},function(){this.I= +this.I&-256|this.xa();this.A-=this.B.gc},function(){this.M=this.M&-256|this.xa();this.A-=this.B.gc},function(){this.H=this.H&-256|this.xa();this.A-=this.B.gc},function(){this.G=this.G&-65281|this.xa()<<8;this.A-=this.B.gc},function(){this.I=this.I&-65281|this.xa()<<8;this.A-=this.B.gc},function(){this.M=this.M&-65281|this.xa()<<8;this.A-=this.B.gc},function(){this.H=this.H&-65281|this.xa()<<8;this.A-=this.B.gc},function(){this.G=this.G&~this.R|this.Ma();this.A-=this.B.gc},function(){this.I=this.I& +~this.R|this.Ma();this.A-=this.B.gc},function(){this.M=this.M&~this.R|this.Ma();this.A-=this.B.gc},function(){this.H=this.H&~this.R|this.Ma();this.A-=this.B.gc},function(){G(this,I(this)&~this.R|this.Ma());this.A-=this.B.gc},function(){this.P=this.P&~this.R|this.Ma();this.A-=this.B.gc},function(){this.K=this.K&~this.R|this.Ma();this.A-=this.B.gc},function(){this.J=this.J&~this.R|this.Ma();this.A-=this.B.gc},ek,fk,ek,fk,function(){this.V.call(this,$h)},function(){this.V.call(this,Yh)},function(){this.S|= +1;this.Jb.call(this,mk,this.xa)},function(){this.S|=1;this.ya.call(this,mk,this.Ma)},gk,hk,gk,hk,function(){if(this.ca&131072&&3>this.Pa)C.call(this,13,0);else{var a=this.B.Aj;this.rb=-1;Aj.call(this,3,null,a)}},function(){var a=this.xa();if(this.ca&131072&&3>this.Pa)C.call(this,13,0);else{var b;a:{b=this.Jd[a];if(void 0!==b)for(var c=0;cthis.Pa)C.call(this,13,0);else{var a=this.B.Bj;this.rb=-1;Aj.call(this,4,null,a)}else this.A-=this.B.Cj},function(){if(this.ca&131072&&3>this.Pa)C.call(this,13,0);else{this.sb=this.ta.Z;this.U=this.fa;this.A-=this.B.yj;if(this.Za&1&&this.ca&16384){var a=this.na(this.Sa.Aa+0);nd(this.va,a,!1)}else{var a=this.pa,b=D(this),c=D(this),d=D(this);if(this.ca&131072)d=d&131071|this.ca&-131072;else if(d&131072){var e=D(this),f=D(this),g=D(this),h=D(this),k=D(this),l=D(this);od(this,!0,!0);md(this, +f);G(this,e);yd(this,g);xd(this,h);this.Nb.load(k);this.Ob.load(l)}null!=Bd(this,b,c,!1)&&(Ad(this,d,a),this.oe&&hf(this,this.Ha))}this.sb=this.U=-1}},function(){this.Jb.call(this,bk,uj)},function(){this.ya.call(this,2==this.ba?ck:dk,uj)},function(){this.Jb.call(this,bk,vj)},function(){this.ya.call(this,2==this.ba?ck:dk,vj)},function(){var a=this.xa();if(a){var b=this.G&255;this.G=this.G&-65536|b/a<<8|b%a;yf(this,this.G,128);this.A-=this.B.dj}else Dj.call(this)},function(){var a=this.G&255,b=(this.G>> +8&255)*this.xa()|0,c=a+b|0;this.G=this.G&-65536|c&255;rf(this,a,b,c,191);this.A-=this.B.cj},function(){this.G=this.G&-256|(sf(this)?255:0);this.A-=2},function(){this.G=this.G&-256|Mf(this,this.ka,this.H+(this.G&255));this.A-=this.B.bk},function(){ik.call(this,216)},function(){ik.call(this,217)},function(){ik.call(this,218)},function(){ik.call(this,219)},function(){ik.call(this,220)},function(){ik.call(this,221)},function(){ik.call(this,222)},function(){ik.call(this,223)},function(){var a=this.T(), +b=this.I-1&this.Ba;this.I=this.I&~this.Ba|b;b&&!vf(this)?(O(this,K(this)+a),this.A-=this.B.Jj):this.A-=this.B.Ih},function(){var a=this.T(),b=this.I-1&this.Ba;this.I=this.I&~this.Ba|b;b&&vf(this)?(O(this,K(this)+a),this.A-=this.B.Jh):this.A-=this.B.Kh},function(){var a=this.T(),b=this.I-1&this.Ba;this.I=this.I&~this.Ba|b;b?(O(this,K(this)+a),this.A-=this.B.Ij):this.A-=this.B.Ih},function(){var a=this.T();this.I&this.Ba?this.A-=this.B.Kh:(O(this,K(this)+a),this.A-=this.B.Jh)},function(){var a=this.xa(); +Kf(this,a,1,!0)&&(this.G=this.G&-256|mc(this.ga,a,1,this.Ha-2)&255,this.A-=this.B.Dh)},function(){var a=this.xa();Kf(this,a,this.ba,!0)&&(this.G=this.G&~this.R|mc(this.ga,a,this.ba,this.Ha-2)&this.R,this.A-=this.B.Dh)},function(){var a=this.xa();Kf(this,a,1,!1)&&(qc(this.ga,a,1,this.G&255,this.Ha-2),this.A-=this.B.Rh)},function(){var a=this.xa();Kf(this,a,this.ba,!1)&&(qc(this.ga,a,this.ba,this.G&this.R,this.Ha-2),this.A-=this.B.Rh)},function(){var a=this.Ma(),b=K(this),a=b+a;J(this,b);O(this,a); +this.A-=this.B.hj},function(){var a=this.Ma();O(this,K(this)+a);this.A-=this.B.Eh},function(){Bd(this,this.Ma(),Uf(this));this.A-=this.B.Ej},function(){var a=this.T();O(this,K(this)+a);this.A-=this.B.Eh},function(){var a=this.M&65535;Kf(this,a,1,!0)&&(this.G=this.G&-256|mc(this.ga,a,1,this.Ha-1)&255,this.A-=this.B.Ch)},function(){var a=this.M&65535;Kf(this,a,this.ba,!0)&&(this.G=this.G&~this.R|mc(this.ga,a,this.ba,this.Ha-1)&this.R,this.A-=this.B.Ch)},function(){var a=this.M&65535;Kf(this,a,1,!1)&& +(qc(this.ga,a,1,this.G&255,this.Ha-1),this.A-=this.B.Qh)},function(){var a=this.M&65535;Kf(this,a,2,!1)&&(qc(this.ga,a,this.ba,this.G&this.R,this.Ha-1),this.A-=this.B.Qh)},jk,jk,function(){this.S|=132;this.A-=this.B.od},function(){this.S|=68;this.A-=this.B.od},function(){this.ca&131072?C.call(this,13,0):(this.ua|=4,this.A-=2,this.ha&&A(this,-2147483648)?(qf(this),this.ha.Wb()):this.ca&512||(this.ha&&qf(this),this.Wb()))},function(){sf(this)?Af(this):zf(this);this.A-=2},function(){this.cb=!1;this.Jb.call(this, +ok,xj);this.cb&&(this.G=this.G&~this.R|this.ia&this.R)},function(){this.cb=!1;this.ya.call(this,pk,xj);this.cb&&(this.G=this.G&~this.R|this.ia&this.R,this.M=this.M&~this.R|this.wa&this.R)},function(){Af(this);this.A-=2},function(){zf(this);this.A-=2},function(){this.pa>this.Pa?C.call(this,13,0):(this.ca&=-513,this.A-=this.B.fj)},function(){this.pa>this.Pa?C.call(this,13,0):(this.ca|=512,this.S|=4,this.A-=2)},function(){this.ca&=-1025;this.A-=2},function(){this.ca|=1024;this.A-=2},function(){this.Jb.call(this, +Fd,xj)},function(){this.ya.call(this,Gd,xj)}],Wj=[wh,ji,uh,Ci,yh,ej,mj,Mh],kk=[xh,Bi,vh,Di,zh,fj,nj,Nh],lk=[function(a,b){this.A-=-1===this.C?this.B.zc:this.B.Uj;return b},Ph,Ph,Ph,Ph,Ph,Ph,Ph],mk=[function(a,b){this.A-=-1===this.C?this.B.Mj:this.B.Kj;return b},Qh,Qh,Qh,Qh,Qh,Qh,Qh],bk=[function(a,b){var c=a,d=b&this.ra;if(d){var e;(d&=7)?(e=a<>8-d)&255):e=a<<7;Df(this,c,e,128)}return c},function(a,b){var c=a,d=b&this.ra;if(d){var e;(d&=7)?(e=a<<8-d,c=(a>>>d|e)&255):e=a;Df(this,c,e, +128)}return c},function(a,b){var c=a,d=b&this.ra;if(d){var e=Ef(this);(d%=9)?(c=(a<>9-d)&255,e=a<>d|e<<8-d|a<<9-d)&255,e=a<<8-d):e<<=7;Df(this,c,e,128)}return c},function(a,b){var c=a,d=b&this.ra;if(d){var e=0;8>>c-1,a=c>>>1&255,yf(this,a,128,c&1,a&128));return a},Qh, +function(a,b){var c=b&this.ra;c&&(9>24>>c-1,a=c>>1&255,yf(this,a,128,c&1));return a}],ck=[function(a,b){var c=a,d=b&this.ra;if(d){var e;(d&=15)?(e=a<>16-d)&65535):e=a<<15;Df(this,c,e,32768)}return c},function(a,b){var c=a,d=b&this.ra;if(d){var e;(d&=15)?(e=a<<16-d,c=(a>>>d|e)&65535):e=a;Df(this,c,e,32768)}return c},function(a,b){var c=a,d=b&this.ra;if(d){var e=Ef(this);(d%=17)?(c=(a<>17-d)&65535,e=a<>d|e<<16-d|a<<17-d)&65535,e=a<<16-d):e<<=15;Df(this,c,e,32768)}return c},function(a,b){var c=a,d=b&this.ra;if(d){var e=0;16>>c-1,a=c>>>1&65535,yf(this,a,32768,c&1,a&32768));return a},Qh,function(a,b){var c=b&this.ra;c&&(17>16>>c-1,a=c>>1&65535,yf(this,a,32768,c&1));return a}],dk=[function(a,b){var c= +a,d=b&this.ra;d&&(c=a<>>32-d,Df(this,c,a<>>d|e;Df(this,c,e,-2147483648)}return c},function(a,b){var c=a,d=b&this.ra;d&&(c=Ef(this),c=a<>>32-d>>>1,Df(this,c,a<>>d|c<<32-d|a<<32-d<<1,Df(this,c,a<<32-d,-2147483648));return c},function(a,b){var c=a,d=b&this.ra;d&&(d=a<>>c-1,a=c>>>1,yf(this,a,-2147483648,c&1,a&-2147483648));return a},Qh,function(a,b){var c=b&this.ra;c&&(c=a>>c-1,a=c>>1,yf(this,a,-2147483648,c&1));return a}],ok=[function(a,b){b=this.xa();yf(this,a&b,128);this.A-=-1===this.D?this.B.bi:this.B.ai;this.S|=2;return a},Qh,function(a){this.A-=-1===this.D?this.B.Tf:this.B.Sf;return a^255},function(a){var b=-a|0;rf(this,0,a,b,191,!0);this.A-=-1===this.D?this.B.Tf:this.B.Sf;return b&255},function(a){this.ia= +(this.G&255)*a&65535;this.ia&65280?(zf(this),Bf(this)):(Af(this),Cf(this));this.cb=!0;this.A-=-1===this.D?this.B.Qj:this.B.Pj;this.S|=2;return a},function(a){var b=(this.G<<24>>24)*(a<<24>>24)|0;this.ia=b&65535;127b?(zf(this),Bf(this)):(Af(this),Cf(this));this.cb=!0;this.A-=-1===this.D?this.B.vj:this.B.uj;this.S|=2;return a},function(a,b){if(!a)return Dj.call(this),a;var c=(b=this.G&65535)/a;if(255>24,d=(b=this.G<<16>>16)/c|0;if(d!=d<<24>>24||8086==this.ja&&-128==d)return Dj.call(this),a;this.ia=d&255|(b%c&255)<<8;this.cb=!0;this.A-=-1===this.D?this.B.rj:this.B.qj;this.S|=2;return a}],pk=[function(a,b){b=this.Ma();yf(this,a&b,this.Ga);this.A-=-1===this.D?this.B.bi:this.B.ai;this.S|=2;return a},Qh,function(a){this.A-=-1===this.D?this.B.Tf:this.B.Sf;return a^this.R},function(a){var b=-a|0;rf(this,0,a,b,this.Ga| +63,!0);this.A-=-1===this.D?this.B.Tf:this.B.Sf;return b&this.R},function(a,b){if(2==this.ba){b=this.G&65535;var c=b*a|0;this.ia=c&65535;this.wa=c>>16&65535}else Wh.call(this,a,this.G),80563==this.Uc&&68657152==this.G&&129==a&&(this.wa=0);this.wa?(zf(this),Bf(this)):(Af(this),Cf(this));this.cb=!0;this.A-=-1===this.D?this.B.Sj:this.B.Rj;this.S|=2;return a},function(a,b){var c;2==this.ba?(b=this.G&65535,c=(b<<16>>16)*(a<<16>>16)|0,this.ia=c&65535,this.wa=c>>16&65535,c=32767c):(Vh.call(this, +a,this.G),c=this.wa!=this.ia>>31);c?(zf(this),Bf(this)):(Af(this),Cf(this));this.cb=!0;this.A-=-1===this.D?this.B.xj:this.B.wj;this.S|=2;return a},function(a,b){if(2==this.ba){if(!a)return Dj.call(this),a;b=65536*(this.M&65535)+(this.G&65535);var c=b/a;if(65536<=c)return Dj.call(this),a;this.ia=c&65535;this.wa=b%a&65535}else{if(!qj.call(this,this.G,this.M,a))return Dj.call(this),a;this.ia|=0;this.wa|=0}this.cb=!0;this.A-=-1===this.D?this.B.pj:this.B.oj;this.S|=2;return a},function(a,b){if(2==this.ba){if(!a)return Dj.call(this), +a;var c=a<<16>>16,d=(b=this.M<<16|this.G&65535)/c|0;if(d!=d<<16>>16||8086==this.ja&&-32768==d)return Dj.call(this),a;this.ia=d&65535;this.wa=b%c&65535}else{var c=this.G,d=this.M,e=a,f=0,g=0;0>e&&(e=-e|0,f=1-f);0>d&&(c=-c|0,d=~d+(c?0:1)|0,g=1,f=1-f);!qj.call(this,c,d,e)||this.ia>2147483647+f||this.wa>2147483647+g?c=!1:(f&&(this.ia=-this.ia),g&&(this.wa=-this.wa),c=!0);if(!c)return Dj.call(this),a;this.ia|=0;this.wa|=0}this.cb=!0;this.A-=-1===this.D?this.B.tj:this.B.sj;this.S|=2;return a}],Fd=[function(a){var b= +a+1|0;rf(this,a,1,b,190);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&255},function(a){var b=a-1|0;rf(this,a,1,b,190,!0);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&255},Qh,Qh,Qh,Qh,Qh,Qh],Gd=[function(a){var b=a+1|0;rf(this,a,1,b,this.Ga|62);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&this.R},function(a){var b=a-1|0;rf(this,a,1,b,this.Ga|62,!0);this.A-=-1===this.D?this.B.Rf:this.B.Qf;return b&this.R},function(a){J(this,K(this));O(this,a);this.A-=-1===this.D?this.B.lj:this.B.kj;this.S|= +2;return a},function(a){if(-1===this.D)return Qh.call(this,a);this.U=this.fa;zj.call(this,a,this.na(this.D+this.ba));this.A-=this.B.ij;this.S|=2;this.U=-1;return a},function(a){O(this,a);this.A-=-1===this.D?this.B.Gj:this.B.Fj;this.S|=2;return a},function(a){if(-1===this.D)return Qh.call(this,a);Bd(this,a,this.na(this.D+this.ba));this.A-=this.B.Dj;this.S|=2;return a},function(a){var b=a;this.S&512&&(a=a-2&65535,80286>this.ja&&(b=a));J(this,b);this.A-=-1===this.D?this.B.Sc:this.B.Wj;this.S|=2;return a}, +Qh];function qe(){this.V.call(this,jj);this.A-=-1===this.D?6:13}function re(){this.ea.call(this,ij);this.A-=-1===this.D?12:19}var ie=Array(256);ie[0]=function(){16>(this.Qa(this.Ha)&56)&&(this.S|=1);this.ya.call(this,this.jg,xj)};ie[1]=function(){this.Qa(this.Ha)&16||(this.S|=1);this.ya.call(this,qk,xj)};ie[2]=function(){!(this.Za&1)||this.ca&131072?C.call(this,6):this.V.call(this,Xh)};ie[3]=function(){!(this.Za&1)||this.ca&131072?C.call(this,6):this.V.call(this,ci)}; +ie[5]=function(){this.pa?C.call(this,13,0,0,!0):(Jf(this,this.na(2054)),this.J=this.na(2086),this.K=this.na(2088),this.P=this.na(2090),this.H=this.na(2094),this.M=this.na(2096),this.I=this.na(2098),this.G=this.na(2100),ld(this.Xa,2102,this.na(2084)),ld(this.va,2108,this.na(2082)),ld(this.ta,2114,this.na(2080)),ld(this.vb,2120,this.na(2078)),Ad(this,this.na(2072)),O(this,this.na(2074)),G(this,this.na(2092)),this.Ec=this.na(2126)|this.Qa(2128)<<16,this.Bd=this.Ec+this.na(2130),this.Mc=this.na(2138)| +this.Qa(2140)<<16,this.Ud=this.Mc+this.na(2142),ld(this.Bc,2132,this.na(2076)),ld(this.Sa,2144,this.na(2070)),this.A-=195)};ie[6]=function(){this.pa?C.call(this,13,0):(this.Za&=-9,this.A-=2)};ie[11]=Id;ie[166]=Id;ie[255]=Id;var M=[];M[5]=Id; +M[7]=function(){if(this.pa)C.call(this,13,0,0,!0);else{var a=this.Xa.mc(this.J&this.Ba,204);if(-1!==a){sj.call(this,this.oa(a));var b=this.oa(a+168),c=(b&24576)>>13;Ad(this,this.oa(a+4),c);this.Ec=this.oa(a+112);this.Bd=this.Ec+this.oa(a+116);this.Mc=this.oa(a+100);this.Ud=this.Mc+this.oa(a+104);kd(this.Bc,this.oa(a+56),this.oa(a+120),this.oa(a+124),this.oa(a+128));kd(this.Sa,this.oa(a+52),this.oa(a+84),this.oa(a+88),this.oa(a+92));this.J=this.oa(a+12);this.K=this.oa(a+16);this.P=this.oa(a+20);this.H= +this.oa(a+28);this.M=this.oa(a+32);this.I=this.oa(a+36);this.G=this.oa(a+40);kd(this.Ob,this.oa(a+60),this.oa(a+132),this.oa(a+136),this.oa(a+140));kd(this.Nb,this.oa(a+64),this.oa(a+144),this.oa(a+148),this.oa(a+152));kd(this.vb,this.oa(a+68),this.oa(a+156),this.oa(a+160),this.oa(a+164));kd(this.ta,this.oa(a+72),b,this.oa(a+172),this.oa(a+176));kd(this.va,this.oa(a+76),this.oa(a+180),this.oa(a+184),this.oa(a+188));kd(this.Xa,this.oa(a+80),this.oa(a+192),this.oa(a+196),this.oa(a+200));O(this,this.oa(a+ +8));G(this,this.oa(a+24))}this.A-=122<<(a&3?1:0)}};M[16]=Xj;M[17]=Yj;M[18]=Zj;M[19]=ak;M[32]=function(){if(this.pa)C.call(this,13,0);else{var a,b=this.xa();switch((b&56)>>3){case 0:a=this.Za;break;case 2:a=this.ue;break;case 3:a=this.Qd;break;default:je.call(this);return}ye(this,b&7,a);this.A-=6}};M[33]=function(){if(this.pa)C.call(this,13,0);else{var a=this.xa(),b=(a&56)>>3;4==b||5==b?je.call(this):(ye(this,a&7,this.Ja[b]),this.A-=22)}}; +M[34]=function(){if(this.pa)C.call(this,13,0);else{var a=this.xa(),b=xe(this,a&7);switch((a&56)>>3){case 0:sj.call(this,b);this.A-=10;break;case 2:this.ue=b;this.A-=4;break;case 3:Cd.call(this,b);this.A-=5;break;default:je.call(this)}}};M[35]=function(){if(this.pa)C.call(this,13,0);else{var a=this.xa(),b=(a&56)>>3;4==b||5==b?je.call(this):(a=xe(this,a&7),a!=this.Ja[b]&&(jf(this,!1),this.Ja[b]=a,jf(this,!0)),this.A-=4>b?22:14)}}; +M[36]=function(){if(this.pa)C.call(this,13,0);else{var a=this.xa(),b=(a&56)>>3;6>b?je.call(this):(ye(this,a&7,this.Ce[b]),this.A-=12)}};M[38]=function(){if(this.pa)C.call(this,13,0);else{var a=this.xa(),b=(a&56)>>3;6>b?je.call(this):(this.Ce[b]=xe(this,a&7),this.A-=12)}};M[128]=function(){var a=this.Ma();xf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[129]=function(){var a=this.Ma();xf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)}; +M[130]=function(){var a=this.Ma();sf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[131]=function(){var a=this.Ma();sf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)};M[132]=function(){var a=this.Ma();vf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[133]=function(){var a=this.Ma();vf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)};M[134]=function(){var a=this.Ma();sf(this)||vf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb}; +M[135]=function(){var a=this.Ma();sf(this)||vf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)};M[136]=function(){var a=this.Ma();wf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[137]=function(){var a=this.Ma();wf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)};M[138]=function(){var a=this.Ma();tf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[139]=function(){var a=this.Ma();tf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)}; +M[140]=function(){var a=this.Ma();!wf(this)!=!xf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[141]=function(){var a=this.Ma();!wf(this)==!xf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[142]=function(){var a=this.Ma();vf(this)||!wf(this)!=!xf(this)?(O(this,K(this)+a),this.A-=this.B.ab):this.A-=this.B.bb};M[143]=function(){var a=this.Ma();vf(this)||!wf(this)!=!xf(this)?this.A-=this.B.bb:(O(this,K(this)+a),this.A-=this.B.ab)};M[144]=function(){tj.call(this,Ei)}; +M[145]=function(){tj.call(this,Ei)};M[146]=function(){tj.call(this,Fi)};M[147]=function(){tj.call(this,Gi)};M[148]=function(){tj.call(this,Hi)};M[149]=function(){tj.call(this,Ii)};M[150]=function(){tj.call(this,Ji)};M[151]=function(){tj.call(this,Ki)};M[152]=function(){tj.call(this,Li)};M[153]=function(){tj.call(this,Mi)};M[154]=function(){tj.call(this,Ni)};M[155]=function(){tj.call(this,Oi)};M[156]=function(){tj.call(this,Pi)};M[157]=function(){tj.call(this,Qi)};M[158]=function(){tj.call(this,Ri)}; +M[159]=function(){tj.call(this,Si)};M[160]=function(){wd(this,this.Nb.Z,this.ba,2);this.A-=this.B.Ie};M[161]=function(){this.U=this.fa;var a=D(this);this.Nb.load(a);this.A-=this.B.zc;this.U=-1};M[163]=function(){this.ea.call(this,Ih);-1!==this.D&&(this.A-=6)};M[164]=function(){this.ea.call(this,2==this.ba?Ti:Vi);this.A-=-1===this.D?3:7};M[165]=function(){this.ea.call(this,2==this.ba?Xi:Yi);this.A-=-1===this.D?3:7};M[168]=function(){wd(this,this.Ob.Z,this.ba,2);this.A-=this.B.Ie}; +M[169]=function(){this.U=this.fa;var a=D(this);this.Ob.load(a);this.A-=this.B.zc;this.U=-1};M[171]=function(){this.ea.call(this,Lh);-1!==this.D&&(this.A-=5)};M[172]=function(){this.ea.call(this,2==this.ba?Zi:aj);this.A-=-1===this.D?3:7};M[173]=function(){this.ea.call(this,2==this.ba?cj:dj);this.A-=-1===this.D?3:7};M[175]=function(){this.V.call(this,2==this.ba?Sh:Uh)};M[178]=function(){this.V.call(this,di)};M[179]=function(){this.ea.call(this,Kh);-1!==this.D&&(this.A-=5)}; +M[180]=function(){this.V.call(this,ai)};M[181]=function(){this.V.call(this,bi)}; +M[182]=function(){this.Oa.call(this,fi);switch(this.L>>3&7){case 0:this.G=this.G&~this.R|this.G&255;break;case 1:this.I=this.I&~this.R|this.I&255;break;case 2:this.M=this.M&~this.R|this.M&255;break;case 3:this.H=this.H&~this.R|this.H&255;break;case 4:this.gb=this.gb&~this.R|this.G>>8&255;this.G=this.aa;break;case 5:this.P=this.P&~this.R|this.I>>8&255;this.I=this.aa;break;case 6:this.K=this.K&~this.R|this.M>>8&255;this.M=this.aa;break;case 7:this.J=this.J&~this.R|this.H>>8&255,this.H=this.aa}this.A-= +-1===this.D?3:6};M[183]=function(){ud(this,2);this.V.call(this,gi);switch(this.L>>3&7){case 0:this.G=this.G&65535;break;case 1:this.I=this.I&65535;break;case 2:this.M=this.M&65535;break;case 3:this.H=this.H&65535;break;case 4:this.gb=this.gb&65535;break;case 5:this.P=this.P&65535;break;case 6:this.K=this.K&65535;break;case 7:this.J=this.J&65535}this.A-=-1===this.D?3:6};M[186]=function(){this.ya.call(this,rk,this.xa)};M[187]=function(){this.ea.call(this,Jh);-1!==this.D&&(this.A-=5)}; +M[188]=function(){this.V.call(this,Ch)};M[189]=function(){this.V.call(this,Dh)}; +M[190]=function(){this.Oa.call(this,fi);switch(this.L>>3&7){case 0:this.G=this.G&~this.R|(this.G&255)<<24>>24&this.R;break;case 1:this.I=this.I&~this.R|(this.I&255)<<24>>24&this.R;break;case 2:this.M=this.M&~this.R|(this.M&255)<<24>>24&this.R;break;case 3:this.H=this.H&~this.R|(this.H&255)<<24>>24&this.R;break;case 4:this.gb=this.gb&~this.R|this.G<<16>>24&this.R;this.G=this.aa;break;case 5:this.P=this.P&~this.R|this.I<<16>>24&this.R;this.I=this.aa;break;case 6:this.K=this.K&~this.R|this.M<<16>>24& +this.R;this.M=this.aa;break;case 7:this.J=this.J&~this.R|this.H<<16>>24&this.R,this.H=this.aa}this.A-=-1===this.D?3:6};M[191]=function(){ud(this,2);this.V.call(this,gi);switch(this.L>>3&7){case 0:this.G=this.G<<16>>16;break;case 1:this.I=this.I<<16>>16;break;case 2:this.M=this.M<<16>>16;break;case 3:this.H=this.H<<16>>16;break;case 4:this.gb=this.gb<<16>>16;break;case 5:this.P=this.P<<16>>16;break;case 6:this.K=this.K<<16>>16;break;case 7:this.J=this.J<<16>>16}this.A-=-1===this.D?3:6}; +var kf=[function(){this.A-=2+(-1===this.D?0:1);return this.Bc.Z},function(){this.A-=2+(-1===this.D?0:1);return this.Sa.Z},function(a){this.S|=2;this.Bc.load(a);this.A-=17+(-1===this.D?0:2);return a},function(a){this.S|=2;-1!==this.Sa.load(a)&&(this.jb(this.Sa.Xb+4,this.Sa.wb|=512),this.Sa.type|=512);this.A-=17+(-1===this.D?0:2);return a},function(a){this.S|=2;this.A-=14+(-1===this.D?0:2);if(-1!==this.Da.load(a)&&2048!=(this.Da.wb&2560)&&(this.Da.Gc>=this.pa&&this.Da.Gc>=(a&3)||7168==(this.Da.wb&7168)))return If(this), +a;Gf(this);return a},function(a){this.S|=2;this.A-=14+(-1===this.D?0:2);if(-1!==this.Da.load(a)&&512==(this.Da.wb&2560)&&this.Da.Gc>=this.pa&&this.Da.Gc>=(a&3))return If(this),a;Gf(this);return a},Qh,Qh],Hd=[ge,ge,ge,ge,ge,ge,Qh,Qh],qk=[function(a){if(-1===this.D)C.call(this,6);else{a=this.Bd-this.Ec;var b=this.Ec;80286==this.ja?b|=-16777216:80386<=this.ja&&2!=this.ba&&(a|=b<<16);this.nb(this.D+2,b);this.A-=11}return a},function(a){if(-1===this.D)C.call(this,6);else{a=this.Ud-this.Mc;var b=this.Mc; +80286==this.ja?b|=-16777216:80386<=this.ja&&2!=this.ba&&(a|=b<<16);this.nb(this.D+2,b);this.A-=12}return a},function(a){-1===this.D||this.ca&131072?C.call(this,6):(this.Ec=this.oa(this.D+2)&(this.R|this.R<<8),a&=65535,this.Bd=this.Ec+a,this.S|=2,this.A-=11);return a},function(a){-1===this.D||this.ca&131072?C.call(this,6):(this.Mc=this.oa(this.D+2)&(this.R|this.R<<8),a&=65535,this.Ud=this.Mc+a,this.S|=2,this.A-=12);return a},function(){this.A-=2+(-1===this.D?0:1);return this.Za},Qh,function(a){this.ca& +131072?C.call(this,6):(Jf(this,a),this.A-=-1===this.D?3:6,this.S|=2);return a},Qh],rk=[Qh,Qh,Qh,Qh,Eh,Hh,Gh,Fh]; +function sk(a){Wa.call(this,"ChipSet",a,sk,32768);var b=a.model;b&&!tk[b]&&w("Unrecognized ChipSet model: "+b);this.ja=tk[b]||uk;this.C=[];b=vk(a[wk]);this.C[0]=[b,b];null==b&&(this.ia=[360,360],(b=a.floppies)&&b.length&&(this.ia=b),xk(this,yk,this.ia.length),xk(this,zk,a.monitor||(this.ja=fg&&(this.cb=this.Da=2);this.ka=a.scaleTimers||!1;this.Ub=a.rtcDate;this.Db=!1;a.sound&&(this.sb=this.Fa=null,window&&(this.sb=window.AudioContext|| +window.webkitAudioContext),this.sb&&(this.Fa=new this.sb));this.reset(!0);ub(this)}fb(sk);var uk=5150.9,fg=5170,tk={5150:5150,5160:5160,5170:fg,att6300:5160.101,mpc1600:5150.101,z150:5160.15,compaq:5150.102,other:uk,deskpro386:5180},wk="sw1",Ak="sw2",Bk={Ek:1,ONE:0,ho:64,eo:128,In:192,Lc:192,Sg:6},Ck={fo:16,Bn:32,Qn:48,Lc:48,Sg:4},yk=1,zk=4,Dk={5150:[{},{}]};Dk[5150][0][yk]={Lc:192,hd:{1:0,2:64,3:128,4:192},Rd:"Number of Floppy Drives"};Dk[5150][0][3]={Lc:2,hd:{0:0,1:2},Rd:"Coprocessor"}; +Dk[5150][0][zk]={Lc:48,hd:{0:0,1:16,2:32,3:48,none:0,tv:16,color:32,cga:32,mda:48,mono:48,ega:0,vga:0},Rd:"Monitor Type"};Dk[5150][0][5]={Lc:12,hd:{16:0,32:4,48:8,64:12},Rd:"Base Memory (16Kb Increments)"};Dk[5150][1][6]={Lc:31,hd:{0:0,32:1,64:2,96:3,128:4,160:5,192:6,224:7,256:8,288:9,320:10,352:11,384:12,416:13,448:14,480:15,512:16,544:17,576:18},Rd:"Expansion Memory (32Kb Increments)"};Dk[5160]=[{},{}];Dk[5160][0][yk]=Dk[5150][0][yk];Dk[5160][0][3]=Dk[5150][0][3];Dk[5160][0][zk]=Dk[5150][0][zk]; +Dk[5160][0][5]={Lc:12,hd:{64:0,128:4,192:8,256:12},Rd:"Base Memory (64Kb Increments)"};Dk[5160][1][6]=Dk[5150][1][6];Dk[5160.101]=[{},{}];Dk[5160.101][0][5]={Lc:143,hd:{128:1,256:130,512:8,640:141},Rd:"Base Memory (128Kb Increments)"};Dk[5160.101][0][3]={Lc:16,hd:{0:0,1:16},Rd:"Coprocessor"};Dk[5160.101][1][2]={Lc:1,hd:{0:0,1:1},Rd:"Floppy Type"};Dk[5160.101][1][yk]=Dk[5150][0][yk];Dk[5160.101][1][zk]=Dk[5150][0][zk];m=sk.prototype; +m.Pb=function(a,b,c){switch(b){case wk:return this.qa[b]=c,Ek(this,0,b),!0;case Ak:if(5150==(this.ja|0)||5160.101==this.ja)return this.qa[b]=c,Ek(this,1,b),!0;break;case "swdesc":return this.qa[b]=c,!0}return!1}; +m.Ic=function(a,b,c,d){this.ga=b;this.F=c;this.ha=d;this.X=a;this.Tb=Hb(a,"FPU");xk(this,3,this.Tb?1:0,!0);this.B=Hb(a,"Keyboard");this.gb=c.Y.Kd/1193181;lc(b,this,Fk);pc(b,this,Gk);this.jab;b++){var c=13>=b?Rk(e,b):e.A[b];a&&(a+="\n");a+="CMOS["+t(b)+"]: "+t(c)}e.ha.O(a)})}ff(c,26,this.dm.bind(this))}; +m.ic=function(a,b){if(!b)if(!a)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0}; +m.reset=function(a){var b;Sk(this);this.L=Array(this.cb);for(b=0;b=fg){this.N=16;this.ea=0;this.aa=16;this.Ja=0;this.fa=160;512<=Wk(this)&&(this.fa|=16);3==+Xk(this,zk,void 0)&&(this.fa|=64);5180==(this.ja|0)&&(this.fa|=12);this.Ka= +3;this.ra=Array(8);this.pa=0;a&&(this.A=Array(64));Yk(this,this.Ub);for(a=21;24>=a;a++)this.A[a]=0;for(a=14;46>a;a++)void 0===this.A[a]&&(this.A[a]=0);a=0|+Xk(this,zk,void 0)<b){var d=!1;4!=b&&5!=b||a.A[11]&2||(12>c?c=c?c:12:c=(c-=12)?c+128:140,d=!0);a.A[11]&4||(d&&128c;c++)b+=a.A[c];a.A[47]=b&255;a.A[46]=b>>8} +m.save=function(){var a=new lf(this);N(a,0,[this.C]);for(var b=[],c=0;c=fg&&(N(a,5,[this.N,this.ea,this.aa,this.Ja,this.fa,this.Ka]),N(a,6,[this.ra[7],this.ra,this.pa,this.A,this.Ga,this.ua]));return a.data()}; +m.restore=function(a){var b,c;b=a[0];Array.isArray(b[0])?this.C=b[0]:(this.C[0][0]=b[0],this.C[1][0]=b[1]&15,this.C[0][1]=b[2],this.C[1][1]=b[3]&15);Sk(this);b=a[1];for(c=0;c=f;f++){var g="pcjs-bitCell";f||(g+=" pcjs-bitCellLeft");d+='
    '+f+"
    \n"}e.innerHTML=d;il(a,b,c,!0)}function jl(a,b,c){if(b=(a=Dk[a.ja|0])&&a[b])for(var d in b)if(a=b[d],a.Lc&1<g.Ab[0]&&(g.Ab[0]=255,g.Ab[1]--,0>g.Ab[1]&&(g.Ab[1]=255)));return h}function pl(a,b,c,d,e,f){var g=a.L[b];A(a,768)&&x(a,d,e,f,"DMA"+b+".CHANNEL"+c+".COUNT["+g.Kb+"]",null,!0);a=g.Dc[c];a.Ab[g.Kb]=a.Fc[g.Kb]=e;g.Kb^=1}function ql(a,b,c,d){var e=a.L[b],f=e.Yb|1;e.Yb&=-16;A(a,768)&&x(a,c,null,d,"DMA"+b+".STATUS",f,!0);return f} +function rl(a,b,c,d,e){var f=a.L[b];A(a,768)&&x(a,c,d,e,"DMA"+b+".REQ",null,!0);a=d&3;f.Yb=f.Yb&~(16<>2].Dc[b&3],c,d,e)}function tl(a,b,c){b=a.L[b>>2].Dc[b&3];b.sg&&b.hh&&b.Hg?(c&&(b.done=c),b.Ee||Cl(a,b,!0)):c&&c(!0)} +function Cl(a,b,c){c&&(b.count=b.Ab[1]<<8|b.Ab[0],b.type=b.mode&12,b.Ri=b.ud=!1);for(var d=!1;0<=b.count&&(c=b.ng<<16|b.Eb[1]<<8|b.Eb[0],4==b.type?(d=!0,function(c){b.hh.call(b.sg,b.Hg,-1,function(f,g){0>f&&(b.Ri||(b.Ri=!0),f=255);b.Ee||a.ga.qc(c,f);(d=g)&&setTimeout(function(){Dl(b)||Cl(a,b)},0)})}(c)):8==b.type?(c=a.ga.Qa(c),0>b.hh.call(b.sg,b.Hg,c)&&(b.ud=!0)):0!=b.type&&(b.ud=!0)),!d&&!Dl(b););} +function Dl(a){if(!a.ud&&0<=--a.count&&(a.mode&32?(a.Eb[0]--,0>a.Eb[0]&&(a.Eb[0]=255,a.Eb[1]--,0>a.Eb[1]&&(a.Eb[1]=255))):(a.Eb[0]++,255>3];b=1<<(b&7);d.lc&b||(d.lc|=b,d.of=c||0,Gl(a))}function gg(a,b){var c=a.vc[b>>3],d=1<<(b&7);c.lc&d&&(c.lc&=~d,Gl(a))}function Gl(a,b){var c,d=-1;1>=1),ad(a.F,e))),0==b&&2==c&&bl(a))}function Nl(a,b,c,d){x(a,c,null,d,"PIT"+b+".CTRL",null,2048);return b?a.Pa:a.Oa} +function Ol(a,b,c,d,e){x(a,c,d,e,"PIT"+b+".CTRL",null,2048);e=0;c=d&192;b?(e=3,a.Pa=d):a.Oa=d;if(192==c){if(!(d&16))for(c=0;2>=c;c++)if(d&2<=c;c++)d&2<>=6;var f=d&1,g=d&14;d&=48;if(0==d)Pl(a,e+c);else{e=e+c;var h=a.V[e];h.gg=d;h.mode=g;h.ah=f;h.Fc=[0,0];h.Ab=[0,0];h.ze=[0,0];h.vd=!1;h.$e=!1;h.Be=!1;h.ef=!1;Kl(a,e);0==b&&0==c&&gg(a,0);0==b&&2==c&&255==a.vc[0].Cd&& +77==a.W&&(b=a.V[0],b.$c[0]=b.Fc[0],b.$c[1]=b.Fc[1],b.xd=Zc(a.F,a.ka))}}}function Ml(a,b){var c=a.V[b],d=c.Fc[1]<<8|c.Fc[0];d||(d=1==c.nd?256:65536);return d}function ed(a,b){var c=a.V[b],d=c.$c[1]<<8|c.$c[0];d||(d=1==c.nd?256:65536);return d}function Pl(a,b){Qk(a,b);var c=a.V[b];c.ze[0]=c.Ab[0];c.ze[1]=c.Ab[1];c.$e=!0;Kl(a,b)}function Kl(a,b){var c=a.V[b];c.Gd=32==c.gg?1:0;c.nd=48==c.gg?2:1} +function Qk(a,b,c){var d=a.V[b];if(d.Be&&(2!=b||a.W&1)){var e=Zc(a.F,a.ka),f=(e-d.xd)/a.gb|0;0>f&&(d.xd=e,f=0);var g=Ml(a,b),h=ed(a,b)-f;0==d.mode?(0>=h&&(h=0),h||(d.vd=!0,d.Be=!1,b||hg(a,0))):4==d.mode?(d.vd=1!=h,0>=h&&(h=g+h,0>=h&&(h=g),d.$c[0]=h&255,d.$c[1]=h>>8&255,d.xd=e,!b&&d.vd&&hg(a,0))):6==d.mode&&(h-=f,0>=h&&(d.vd=!d.vd,h=g+h,0>=h&&(h=g),d.$c[0]=h&255,d.$c[1]=h>>8&255,d.xd=e,!b&&d.vd&&hg(a,0)));d.Ab[0]=h&255;d.Ab[1]=h>>8&255;c&&(a.xd=0)}return d} +function dd(a,b){for(var c=0;c=fg){var c=a.F.Y.Kd,d=Zc(a.F,a.ka);null==a.fb&&(a.Ga=Zc(a.F,a.ka),a.Jb=1024,a.fb=Math.floor(a.F.Y.Kd/a.Jb),al(a));d>=a.ua&&(a.A[12]|=64,a.A[11]&64&&(a.A[12]|=128,hg(a,8)),a.ua=d+a.fb);a.A[0]==a.A[1]&&a.A[2]==a.A[3]&&a.A[4]==a.A[5]&&(a.A[12]|=32,a.A[11]&32&&(a.A[12]|=128,hg(a,8)));var e=d-a.Ga,f=Math.floor(e/c);if(f&&!(a.A[11]&128)){for(;f--;)if(60<=++a.A[0]&&(a.A[0]=0,60<=++a.A[2]&&(a.A[2]=0,24<=++a.A[4]))){a.A[4]=0;a.A[6]=a.A[6]%7+1; +var g;g=a.A[9];var h=sa[a.A[8]-1];28==h&&0===g%4&&(g%100||0===g%400)&&h++;g=h;++a.A[7]>g&&(a.A[7]=1,12<++a.A[8]&&(a.A[8]=1,a.A[9]=(a.A[9]+1)%100))}a.A[12]|=16;a.A[11]&16&&(a.A[12]|=128,hg(a,8))}a.Ga=d-e%c}}m=sk.prototype;m.Nl=function(a,b){var c=this.$a;this.Ca&16&&(this.W&128?c=this.C[0][1]:this.B&&(c=Ql(this.B)));x(this,a,null,b,"PPI_A",c);return c};m.gn=function(a,b,c){x(this,a,b,c,"PPI_A");this.$a=b};m.Ol=function(a,b){var c=this.W;x(this,a,null,b,"PPI_B",c);return c}; +m.hn=function(a,b,c){x(this,a,b,c,"PPI_B");Rl(this,b)};function Rl(a,b){var c=!!(b&2),d=!!(a.W&2);a.W=b;a.B&&Sl(a.B,!(b&128),!!(b&64));c!=d&&bl(a,c)}m.Pl=function(a,b){var c=0,c=5150==(this.ja|0)?this.W&4?c|this.C[1][1]&15:c|this.C[1][1]>>4&1:this.W&8?c|this.C[0][1]>>4:c|this.C[0][1]&15;this.W&1&&Qk(this,2).vd&&(c=this.W&2?c|32:c|16);x(this,a,null,b,"PPI_C",c,32896);return c};m.jn=function(a,b,c){x(this,a,b,c,"PPI_C");this.rb=b};m.Ql=function(a,b){var c=this.Ca;x(this,a,null,b,"PPI_CTRL",c);return c}; +m.kn=function(a,b,c){x(this,a,b,c,"PPI_CTRL");this.Ca=b};m.Zk=function(a,b){var c=this.B?Ql(this.B):0;x(this,a,null,b,"8041_KBD",c);this.wa&=-2;return c};m.sm=function(a,b,c){x(this,a,b,c,"8041_KBD")};m.Yk=function(a,b){var c=this.W;x(this,a,null,b,"8041_CTRL",c);return c};m.rm=function(a,b,c){x(this,a,b,c,"8041_CTRL");Rl(this,b)};m.$k=function(a,b){var c=this.wa;x(this,a,null,b,"8041_STATUS",c);return c}; +m.al=function(a,b){var c=this.Ja;x(this,a,null,b,"8042_OUTBUFF",c,16384);this.N&=-258;this.B&&Tl(this.B);return c}; +m.um=function(a,b,c){x(this,a,b,c,"8042_INBUF.DATA",null,16384);if(this.N&8)switch(this.ea){case 96:Ul(this,b);break;case 209:Vl(this,b);break;default:if(Ul(this,this.aa&-17),this.B){a=this.B;c=b;var d=-1;A(a)&&y(a,"sendCmd("+t(c)+")");switch(a.V||c){case 255:d=250;Wl(a);break;case 243:a.V&&(c=0);Xl(a,250);a.V=c;break;case 237:a.V&&(c=0);Xl(a,250);a.V=c;break;default:y(a,"sendCmd(): unrecognized command")}Yl(this,d)}}this.ea=b;this.N&=-9}; +m.bl=function(a,b){var c=this.W&-209|(Zc(this.F)&64?16:0);x(this,a,null,b,"8042_RWREG",c,16384);return c};m.vm=function(a,b,c){x(this,a,b,c,"8042_RWREG",null,16384);Rl(this,b)};m.cl=function(a,b){x(this,a,null,b,"8042_STATUS",this.N,16384);var c=this.N&255;this.N&256&&(this.N|=1,this.N&=-257);return c}; +m.tm=function(a,b,c){x(this,a,b,c,"8042_INBUFF.CMD",null,16384);this.ea=b;this.N|=8;a=0;240<=this.ea&&(a=this.ea^15,this.ea=240);switch(this.ea){case 32:Yl(this,this.aa);break;case 173:Ul(this,this.aa|16);break;case 174:Ul(this,this.aa&-17);this.B&&Tl(this.B);break;case 170:this.B&&(a=this.B,a.A=[],A(a)&&y(a,"scan codes flushed"));Ul(this,this.aa|16);Yl(this,85);Vl(this,3);break;case 171:Yl(this,0);break;case 192:Yl(this,this.fa);break;case 208:Yl(this,this.Ka);break;case 224:Yl(this,this.aa&16?0: +1);break;case 240:a&1&&se(this.F)}};function Ul(a,b){a.aa=b;a.N=a.N&-5|b&4;a.B&&Sl(a.B,!!(b&8),!(b&16))}function Yl(a,b,c){0<=b&&(a.Ja=b,c?a.N|=1:(a.N&=-2,a.N|=256))}function Vl(a,b){a.Ka=b;Ub(a.ga,!!(b&2));b&1||se(a.F)}function Zl(a,b){a.ja=c?Rk(this,c):this.A[c];A(this,4352)&&x(this,a,null,b,"CMOS.DATA["+t(c)+"]",d,!0);null!=b&&12==c&&(this.A[c]&=15,d&128&&gg(this,8),d&64&&this.A[11]&64&&al(this));return d}; +m.Km=function(a,b,c){var d=this.pa&63;A(this,4352)&&x(this,a,b,c,"CMOS.DATA["+t(d)+"]",null,!0);a=b^this.A[d];if(13>=d){if(c=b,10>d){var e=!1;this.A[11]&4||(c=10*(c>>4)+(c&15),e=!0);if(4==d||5==d)e&&23=c?c=12==c?0:c:(c-=116,c=24==c?12:c))}}else c=b;this.A[d]=c;11==d&&a&64&&b&64&&al(this)};m.ik=function(a,b,c){x(this,a,b,c,"NMI");this.ya=b};m.Um=function(a,b,c){x(this,a,b,c,"FPU.CLEAR")};m.Vm=function(a,b,c){x(this,a,b,c,"FPU.RESET");this.Tb&&ag(this.Tb)}; +m.dm=function(a){if(A(this,16)&&nk(this.ha,26,a)){var b=this.F.G>>8;gf(this.F,a,function(a,d){return function(e){d=Zc(a.F)-d;var f,g=a.F.M&255,h=a.F.M>>8,k=a.F.M&255,l=a.F.M>>8;if(2==b||3==b)f=" CH(hour)="+u(h)+" CL(min)="+t(g)+" DH(sec)="+t(l);else if(4==b||5==b)f=" CX(year)="+u(a.F.I)+" DH(month)="+t(l)+" DL(day)="+t(k);g=a.ha;h=d;g.message("INT "+t(26)+": C="+(sf(g.F)?1:0)+(f||"")+" (cycles="+h+(e?",level="+(e+1):"")+")")}}(this,Zc(this.F)))}return!0}; +function bl(a,b){if(a.Fa)try{void 0!==b?a.Db=b:b=a.Db&&a.F&&a.F.la.Fb;var c=Math.round(1193181/Ml(a,2));if(20>c||2E4>>4,0,this.X,this.C,this.Sd),delete this.Sd);return!0};bm.prototype.hc=function(){return!0}; +function cm(a,b,c,d){if(d)a.Na("Unable to load system ROM (error "+d+": "+b+")");else{hb(a.fe,b,c);if("["==c.charAt(0)||"{"==c.charAt(0))try{var e=eval("("+c+")"),f=e.bytes,g=e.data;if(f)a.A=f;else if(g)for(a.A=Array(4*g.length),d=c=0;c>8&255,a.A[d++]=g[c]>>16&255,a.A[d++]=g[c]>>24&255;else a.A=e;a.Sd=e.symbols;if(!a.A.length){w("Empty ROM: "+b);return}if(1==a.A.length){w(a.A[0]);return}}catch(h){a.Na("ROM data error: "+h.message);return}else for(b=c.replace(/\n/gm, +" ").replace(/ +$/,"").split(" "),a.A=Array(b.length),e=0;e>>d.La].xf(e&d.A,a.A[c]&255,e)}b=!0}else b=!1;if(b){b=[];"number"==typeof a.N?b.push(a.N):null!=a.N&&a.N.length&&(b=a.N);for(c=0;cthis.B?21:23,c=a.A[b]|a.A[b+1]<<8,c=c+(this.A>>10);a.A[b]=c&255;a.A[b+1]=c>>8;$k(a)}}else w("No RAM allocated")}; +m.save=function(){var a=new lf(this);this.controller&&N(a,0,this.controller.save());return a.data()};m.restore=function(a){return this.controller?this.controller.restore(a[0]):!0};function im(a){this.N=a;this.C=km;this.ha=lm;this.B=mm;this.A=null}var jm=-2134900736,km=65535,lm=2575,mm=2,nm=[null,0],om=[function(a){return this.controller.Qa(a)},null,null,function(a,b){this.controller.qc(a,b)},null,null];m=im.prototype;m.save=function(){return[this.C,this.B]}; +m.restore=function(a){this.qc(0,a[0]&255);this.qc(2,a[1]&255);return!0};m.Qa=function(a){var b=255;2>a?b=a&1?this.ha>>8:this.ha&255:4>a&&(b=a&1?this.B>>8:this.B&255);return b};m.qc=function(a,b){if(a)2==a&&(this.B=this.B&-256|b);else if(b!=(this.C&255)){var c=this.N.ga;if(b&1)this.A&&($b(c,917504,131072,this.A),this.A=null);else{this.A||(this.A=ac(c,917504,131072));var d=ac(c,16646144,131072);$b(c,917504,131072,d,b&2?1:dc)}this.C=this.C&-256|b}};m.Ti=function(){return nm};m.ih=function(){return om}; +Sa(function(){for(var a=pb(document,"pcx86","ram"),b=0;b":62,"?":63,"@":64,yn:65,zn:66,An:67,Fn:68,E:69,Gn:70,Jn:71,Kn:72,Ln:73,Mn:74,Nn:75,On:76,Pn:77,Rn:78,Sn:79,Tn:80,Q:81,Un:82,Yn:83,co:84,io:85,jo:86,ko:87,mo:88,no:89,oo:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,po:97,qo:98,so:99,d:100,e:101,to:102,uo:103,vo:104, +wo:105,xo:106,k:107,yo:108,zo:109,n:110,Bo:111,p:112,q:113,r:114,Co:115,t:116,Eo:117,Fo:118,Go:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126},sm={};sm[186]=X[";"];sm[187]=X["="];sm[188]=X[","];sm[189]=X["-"];sm[190]=X["."];sm[191]=X["/"];sm[192]=X["`"];sm[219]=X["["];sm[220]=X["\\"];sm[221]=X["]"];sm[222]=X["'"];sm[173]=X["-"];var tm={};tm[X["1"]]=X["!"];tm[X["2"]]=X["@"];tm[X["3"]]=X["#"];tm[X["4"]]=X.$;tm[X["5"]]=X["%"];tm[X["6"]]=X["^"];tm[X["7"]]=X["&"];tm[X["8"]]=X["*"];tm[X["9"]]=X["("]; +tm[X["0"]]=X[")"];tm[186]=X[":"];tm[187]=X["+"];tm[188]=X["<"];tm[189]=X._;tm[190]=X[">"];tm[191]=X["?"];tm[192]=X["~"];tm[219]=X["{"];tm[220]=X["|"];tm[221]=X["}"];tm[222]=X['"'];tm[173]=X._;tm[61]=X["+"];tm[59]=X[":"]; +var um={3016:1,1016:2,1017:8,1018:32,1091:128,1093:64,1224:128,1020:512,1144:1024,1145:2048},vm={TAB:1009,ESC:1027,F1:1112,F2:1113,F3:1114,F4:1115,F5:1116,F6:1117,F7:1118,F8:1119,F9:1120,F10:1121,LEFT:1037,UP:1038,RIGHT:1039,DOWN:1040,SYSREQ:4027,CTRL_C:4003,CTRL_BREAK:4008,CTRL_ALT_DEL:4046,CTRL_ALT_INS:4045,CTRL_ALT_ENTER:4013},wm={esc:1027,1:X["1"],2:X["2"],3:X["3"],4:X["4"],5:X["5"],6:X["6"],7:X["7"],8:X["8"],9:X["9"],0:X["0"],"-":X["-"],"=":X["="],bs:1008,tab:1009,q:81,w:87,e:69,r:82,t:84,y:89, +u:85,i:73,o:79,p:80,"[":X["["],"]":X["]"],enter:13,ctrl:1017,a:65,s:83,d:68,f:70,g:71,h:72,j:74,k:75,l:76,";":X[";"],quote:X["'"],"`":X["`"],shift:1016,"\\":X["\\"],z:90,x:88,c:67,v:86,b:66,n:78,m:77,",":X[","],".":X["."],"/":X["/"],"right-shift":3016,prtsc:1044,alt:1018,space:1032,"caps-lock":1020,f1:1112,f2:1113,f3:1114,f4:1115,f5:1116,f6:1117,f7:1118,f8:1119,f9:1120,f10:1121,"num-lock":1144,"scroll-lock":1145,"num-home":1036,"num-up":1038,"num-pgup":1033,"num-sub":1109,"num-left":1037,"num-center":1101, +"num-right":1039,"num-add":1107,"num-end":1035,"num-down":1040,"num-pgdn":1034,"num-ins":1045,"num-del":1046,sysreq:84},xm={"caps-lock":512,"num-lock":1024,"scroll-lock":2048},Y={1027:1};Y[X["1"]]=2;Y[X["!"]]=10754;Y[X["2"]]=3;Y[X["@"]]=10755;Y[X["3"]]=4;Y[X["#"]]=10756;Y[X["4"]]=5;Y[X.$]=10757;Y[X["5"]]=6;Y[X["%"]]=10758;Y[X["6"]]=7;Y[X["^"]]=10759;Y[X["7"]]=8;Y[X["&"]]=10760;Y[X["8"]]=9;Y[X["*"]]=10761;Y[X["9"]]=10;Y[X["("]]=10762;Y[X["0"]]=11;Y[X[")"]]=10763;Y[X["-"]]=12;Y[X._]=10764; +Y[X["="]]=13;Y[X["+"]]=10765;Y[1008]=14;Y[1009]=15;Y[113]=16;Y[81]=10768;Y[119]=17;Y[87]=10769;Y[101]=18;Y[69]=10770;Y[114]=19;Y[82]=10771;Y[116]=20;Y[84]=10772;Y[121]=21;Y[89]=10773;Y[117]=22;Y[85]=10774;Y[105]=23;Y[73]=10775;Y[111]=24;Y[79]=10776;Y[112]=25;Y[80]=10777;Y[X["["]]=26;Y[X["{"]]=10778;Y[X["]"]]=27;Y[X["}"]]=10779;Y[13]=28;Y[1017]=29;Y[97]=30;Y[65]=10782;Y[115]=31;Y[83]=10783;Y[100]=32;Y[68]=10784;Y[102]=33;Y[70]=10785;Y[103]=34;Y[71]=10786;Y[104]=35;Y[72]=10787;Y[106]=36;Y[74]=10788; +Y[107]=37;Y[75]=10789;Y[108]=38;Y[76]=10790;Y[X[";"]]=39;Y[X[":"]]=10791;Y[X["'"]]=40;Y[X['"']]=10792;Y[X["`"]]=41;Y[X["~"]]=10793;Y[1016]=42;Y[X["\\"]]=43;Y[X["|"]]=10795;Y[122]=44;Y[90]=10796;Y[120]=45;Y[88]=10797;Y[99]=46;Y[67]=10798;Y[118]=47;Y[86]=10799;Y[98]=48;Y[66]=10800;Y[110]=49;Y[78]=10801;Y[109]=50;Y[77]=10802;Y[X[","]]=51;Y[X["<"]]=10803;Y[X["."]]=52;Y[X[">"]]=10804;Y[X["/"]]=53;Y[X["?"]]=10805;Y[3016]=54;Y[1044]=55;Y[1018]=56;Y[1032]=57;Y[1020]=58;Y[1112]=59;Y[1113]=60;Y[1114]=61; +Y[1115]=62;Y[1116]=63;Y[1117]=64;Y[1118]=65;Y[1119]=66;Y[1120]=67;Y[1121]=68;Y[1144]=69;Y[1145]=70;Y[1036]=71;Y[1038]=72;Y[1033]=73;Y[1109]=74;Y[1037]=75;Y[1101]=76;Y[1039]=77;Y[1107]=78;Y[1035]=79;Y[1040]=80;Y[1034]=81;Y[1045]=82;Y[1046]=83;Y[4027]=84;Y[1122]=87;Y[1123]=88;Y[1091]=91;Y[1093]=93;Y[1224]=91;Y[4003]=7470;Y[4008]=7494;Y[4046]=3677523;Y[4045]=3677522;Y[4013]=3677468;m=pm.prototype; +m.Pb=function(a,b,c,d){var e=this,f=a+"-"+b;if(void 0===this.qa[f])switch(b){case "kbd":return c.onkeydown=function(a){return ym(e,a,!0)},c.onkeypress=function(a){a=a||window.event;a=a.which||a.keyCode;e.L="";var b=!Y[a]||!!(e.xc&128);b||zm(e,a,!0);return b},c.onkeyup=function(a){return ym(e,a,!1)},!0;case "caps-lock":return this.qa[f]=c,c.onclick=function(){e.X&&e.X.yd();zm(e,1020,!0)},!0;case "num-lock":return this.qa[f]=c,c.onclick=function(){e.X&&e.X.yd();zm(e,1144,!0)},!0;case "scroll-lock":return this.qa[f]= +c,c.onclick=function(){e.X&&e.X.yd();zm(e,1145,!0)},!0;default:var g=b.toUpperCase().replace(/-/g,"_");if(void 0!==vm[g]&&"button"==a)return this.qa[f]=c,c.onclick=function(a,b,c){return function(){a.X&&a.X.yd();Am(a,c,!0);zm(a,c,!0)}}(this,g,vm[g]),!0;if(void 0!==wm[b])return this.fa++,this.qa[f]=c,a=function(a,b,c){return function(){zm(a,c)}}(this,b,wm[b]),b=function(a,b,c){return function(){Bm(a,c)}}(this,b,wm[b]),"ontouchstart"in window?(c.ontouchstart=a,c.ontouchend=b):(c.onmousedown=a,c.onmouseup= +c.onmouseout=b),!0;if(d)return this.qa[f]=c,c.onclick=function(){e.X&&e.X.yd();d&&!e.L&&(e.L=d,Cm(e,300))},!0}return!1};function Dm(a,b,c){if(a.fa){for(var d in tm)if(b==tm[d]){b=+d;(d=sm[d])&&(b=d);break}for(var e in wm)if((d=wm[e]==b)||(d=b,97<=d&&122>=d&&(d-=32),d=wm[e]==d),d){(a=a.qa["key-"+e])&&void 0!==c&&(a.style.color=c?"#ffffff":"#000000",a.style.backgroundColor=c?"#000000":"#ffffff");break}}}m.Ic=function(a,b,c,d){this.X=a;this.ga=b;this.F=c;this.ha=d;this.N=Hb(a,"ChipSet")}; +function qm(a,b){var c=0;a.ja=null;"string"==typeof b&&(a.ja=b.toUpperCase(),c=rm.indexOf(a.ja),0>c&&(c=0));if(b=rm[c])a.ra=parseInt(b.substr(2),10)}function Wl(a){y(a,"keyboard reset",65792);a.A=[];Xl(a,170)}function Sl(a,b,c){a.aa!==c&&(a.aa=a.ea=c)&&(a.U=!0);a.W!==b&&(a.W=b)&&!a.ea&&$l(a,!0);a.W&&a.ea&&(Wl(a),a.ea=!1)}function Xl(a,b){a.N&&(a.A.unshift(b),a.U=!0,Zl(a.N,b))} +function Tl(a){var b=0;a.A.length&&a.U&&(b=a.A[0],a.N&&Zl(a.N,b));A(a)&&y(a,b?"scan code "+t(b)+" available":"no scan codes available")}function Ql(a){var b=0;a.A.length&&(b=a.A[0]);A(a)&&y(a,"scan code "+t(b)+" delivered");return b}function $l(a,b){0>=1);if(b&3584){if(!1===d)return!0;d=null}null==d?d=!((c?a.C:a.xc)&b):d||b&255&&(b=255);if(c){a.C&=~b;d&&(a.C|=b);c=b;var f,g;for(g in xm)d="led-"+g,e=xm[g],c&&c!=e||!(f=a.qa[d])||(f.style.backgroundColor=a.C&e?"#00ff00":"#000000")}else a.xc&=~b,d&&(a.xc|=b);return!0}}return!1} +function zm(a,b,c){if(Y[b]&&a.F&&a.F.la.Fb){um[b]&&a.B.length&&0e||(e==a.B.length&&(d={},d.Ne=b,d.xc=a.xc,Dm(a,b,!0),e++),0b.Md){if(!b.Ff){Bm(a,b.Ne);return}b.Ff=!1;c=a.ua}else c=1==b.Md++?500:100;b.uk=setTimeout(function(a){return function(){Fm(a,b)}}(a),c)}} +function Hm(a,b,c){var d=b;if(65<=b&&90>=b)!(a.xc&515)==c&&(d=b+32);else if(97<=b&&122>=b)!!(a.xc&515)==c&&(d=b-32);else if(!!(a.xc&3)==c){if(a=tm[b])d=a}else if(a=sm[b])d=a;return d}m.Ig=function(a){a||(this.xc&=-256)}; +function ym(a,b,c){var d=!0,e=!1,f=!1,g=b.keyCode,h=Hm(a,g,!0);a.eh&&h==X["`"]&&(g=h=27);if(Y[g+1E3])if(h+=1E3,2==b.location&&(h+=2E3),Am(a,h,!1,c)){if(20==g||144==g||145==g)a.pa||(c=e=!0);if(!(c||91!=g&&93!=g))for(var k=0;k=b||97<=b&&122>=b;e>>>=8;){var g=0,h=e&255;224==f||225==f?d.push(f|(c?0:128)):(42==h?a.C&3||a.C&512&&b||(g=h):29==h?a.C&12||(g=h):56==h?a.C&48||(g=h):d.push(f|(c?0:128)),g&&(c?d.unshift(g):d.push(g|128)))}for(c=0;ce.A.length?(A(e)&&y(e,"scan code "+t(f)+" buffered"),e.A.push(f),1== +e.A.length&&e.N&&Zl(e.N,f)):(20==e.A.length&&e.A.push(255),y(e,"scan code buffer overflow")));d=!0}return d}Sa(function(){for(var a=pb(document,"pcx86","keyboard"),b=0;bc.length)c=[!1,0,null,null,0,Array(5>b?Zm:$m)];this.ha=a.ha;this.type=e[0];this.port=e[1];this.Ua=b;this.ob=e[2];this.ac=e[3];this.Fd=d||e[4];65536<=this.Fd&&720896<=this.ob&&(this.ac=Math.min(this.Fd>>2,32768));this.Hc=c[0];this.gd=c[1];this.tf=c[2];this.ma=c[3];this.Ac=c[4]&255;this.Lg=c[4]>>8&255;this.mb=c[5];this.ph=Zm;this.mg=an;if(5<=b){this.ph=$m;this.mg=bn;b=c[6];void 0===b&&(b=[!1,0,Array(20), +0,3==f?0:1,0,0,Array(5),0,0,0,Array(9),0,[this.ob,this.ac,this.Fd],Array(this.Fd>>2),-2147478512,0,-1,0,-1,0,-1,0,0,0,0,1,255,0,0,0,Array(256)]);this.Ye=b[0];this.Pd=b[1];this.Tc=b[2];this.Vg=cn;this.Og=b[3];this.vf=b[4];this.fg=b[5];this.de=b[6];this.Ke=b[7];this.Xg=dn;this.kk=b[8];this.lk=b[9];this.ce=b[10];this.be=b[11];this.Wg=en;this.Gb=b[12];d=b[13];"number"==typeof d&&(d=[this.ob,this.ac,d]);this.ob=d[0];this.ac=d[1];d=this.Fd>>2;if((this.sd=b[14])&&this.sd.length>this.controller.fi&255};gn[17408]=function(a){return(this.controller.Gb=this.da[(a&-4)+this.C])>>((a&3)<<3)&255};gn[5120]=function(a){a+=this.C;var b=this.controller.Gb=this.da[a&-2];return(a&1?b>>8:b)&255};gn[1280]=function(a){a+=this.C;a=this.controller.Gb=this.da[a];for(var b=this.controller.rh,c=this.controller.qh&b,d=0,e=128;e;)(a&b)==c&&(d|=e),c>>>=1,b>>>=1,e>>=1;return d}; +gn[0]=function(a,b){var c=a+this.C,d;d=(b|b<<8|b<<16|b<<24)&this.controller.ae|this.controller.re;d=d&this.controller.Mb|this.controller.Gb&~this.controller.Mb;d=d&this.controller.qb|this.da[c]&~this.controller.qb;this.da[c]!=d&&(this.da[c]=d,this.Wa=!0)}; +gn[32]=function(a,b){var c=a+this.C;b=b>>this.controller.dd|b<<8-this.controller.dd&255;var d;d=(b|b<<8|b<<16|b<<24)&this.controller.ae|this.controller.re;d=d&this.controller.Mb|this.controller.Gb&~this.controller.Mb;d=d&this.controller.qb|this.da[c]&~this.controller.qb;this.da[c]!=d&&(this.da[c]=d,this.Wa=!0)}; +gn[96]=function(a,b){var c=a+this.C;b=b>>this.controller.dd|b<<8-this.controller.dd&255;var d;d=(b|b<<8|b<<16|b<<24)&this.controller.ae|this.controller.re;d&=this.controller.Gb;d=d&this.controller.Mb|this.controller.Gb&~this.controller.Mb;d=d&this.controller.qb|this.da[c]&~this.controller.qb;this.da[c]!=d&&(this.da[c]=d,this.Wa=!0)}; +gn[160]=function(a,b){var c=a+this.C;b=b>>this.controller.dd|b<<8-this.controller.dd&255;var d;d=(b|b<<8|b<<16|b<<24)&this.controller.ae|this.controller.re;d|=this.controller.Gb;d=d&this.controller.Mb|this.controller.Gb&~this.controller.Mb;d=d&this.controller.qb|this.da[c]&~this.controller.qb;this.da[c]!=d&&(this.da[c]=d,this.Wa=!0)}; +gn[224]=function(a,b){var c=a+this.C;b=b>>this.controller.dd|b<<8-this.controller.dd&255;var d;d=(b|b<<8|b<<16|b<<24)&this.controller.ae|this.controller.re;d^=this.controller.Gb;d=d&this.controller.Mb|this.controller.Gb&~this.controller.Mb;d=d&this.controller.qb|this.da[c]&~this.controller.qb;this.da[c]!=d&&(this.da[c]=d,this.Wa=!0)};gn[4]=function(a,b){var c=(a&-4)+this.C,d=(a&3)<<3,d=b<>this.controller.dd|b<<8-this.controller.dd&255;var d;d=(b|b<<8|b<<16|b<<24)&this.controller.Mb;d=this.controller.Vf&d|this.controller.Gb&~d;d=d&this.controller.qb|this.da[c]&~this.controller.qb;this.da[c]!=d&&(this.da[c]=d,this.Wa=!0)}; +function hn(a){var b=[];if(void 0!==a.Ua){b[0]=a.Hc;b[1]=a.gd;b[2]=a.tf;b[3]=a.ma;b[4]=a.Ac|a.Lg<<8;b[5]=a.mb;if(5<=a.Ua){var c=[];c[0]=a.Ye;c[1]=a.Pd;c[2]=a.Tc;c[3]=a.Og;c[4]=a.vf;c[5]=a.fg;c[6]=a.de;c[7]=a.Ke;c[8]=a.kk;c[9]=a.lk;c[10]=a.ce;c[11]=a.be;c[12]=a.Gb;c[13]=[a.ob,a.ac,a.Fd];var d;a:if(d=a.sd){var e=0,f=[];if(void 0!==d[0])for(var g=0;2>g;g++)for(var h=g;h>1;f[e++]=k;h=l}if(f.length>3;for(c=0;c=d&&(z=d,q=!0);break;case "p":0<= +d&&3>=d&&(F=d);break;case "w":d=b.ob&&(f-=b.ob);a="";for(c=0;cF?r(H):da(H>>(F<<3),8));q&&(f+=v-z);a&&(a+="\n");a+=E}a&&b.ha.O(a);b.B=f}else b.ha.O("no buffer")}else e.ha.O("BIOSMODE: "+t(e.Ga)),b=e.C,jn(b,"CRTC",b.Ac,b.mb,b.mg),5<=b.Ua&&(jn(b," GRC",b.ce,b.be,b.Wg),jn(b," SEQ",b.de,b.Ke,b.Xg),jn(b," ATC",b.Pd,b.Tc,b.Vg),jn(b," ATCINDX", +b.Pd),b.ha.O(" ATCDATA: "+b.Ye),jn(b," FEAT",b.fg),jn(b," MISC",b.vf),jn(b," STATUS0",b.Og)),jn(b," STATUS1",b.ma),1!=b.Ua&&3!=b.Ua||jn(b," MODEREG",b.gd),3==b.Ua&&jn(b," COLOR",b.tf),5<=b.Ua&&(b.ha.O(" LATCHES: "+r(b.Gb)),b.ha.O(" ACCESS: "+r(b.yg,4)),b.ha.O("Use 'dump video [addr]' to dump video memory"));else e.ha.O("no active video card")})}if((this.B=Hb(a,"Keyboard"))&&this.ka){for(var f in this.qa)0c&&(a=Math.round(c/b*100)+"%")}this.rf?(this.ka.style.width=a,this.ka.style.width=a,this.ka.style.display="block",this.ka.style.margin="auto"):(this.ia.style.width=a,this.ia.style.height="auto");this.ia.style.backgroundColor="black";this.ia.Xe();a=!0}this.X&&this.X.focus()}return a}; +function Lm(a,b){!b&&a.ia&&(a.rf?a.ka.style.width=a.ka.style.height="":a.ia.style.width=a.ia.style.height="");y(a,"notifyFullScreen("+b+")",!0);a.B&&(a.B.eh=b)}m.De=function(a){var b=!1;this.X&&(a?this.X.De&&(this.X.De(),this.V&&this.V.Wf(!0),b=!0):this.X.vk&&(this.X.vk(),this.V&&this.V.Wf(!1),b=!0),this.X&&this.X.focus());return b};m.Wf=function(a){this.V&&(this.V.Wf(a),this.B&&(this.B.eh=a));var b=this.qa.lockPointer;b&&(b.textContent=a?"Press Esc to Unlock Pointer":this.xk)}; +function tn(a,b){var c=a.X;c&&!a.ne&&(c.addEventListener("touchstart",function(b){vn(a,b,!0)},!1),c.addEventListener("touchmove",function(b){vn(a,b)},!0),c.addEventListener("touchend",function(b){vn(a,b,!1)},!1),a.ne=b,a.uc=a.Cc=a.jg=-1,a.Jd=!1,a.Xc=null,a.Id=!1,a.xn=function(){a.Id=!0;a.V.ke(wn,!0)})}m.Ig=function(a){this.B&&this.B.Ig(a)}; +function vn(a,b,c){var d,e,f=0,g=0;e=a.ka;do isNaN(e.offsetLeft)||(f+=e.offsetLeft,g+=e.offsetTop);while(e=e.offsetParent);var h=a.ra/a.ka.offsetWidth,k=a.Da/a.ka.offsetHeight;b.targetTouches&&b.targetTouches.length?(d=b.targetTouches[0].pageX,e=b.targetTouches[0].pageY):(d=b.pageX,e=b.pageY);d=(d-f)*h;e=(e-g)*k;if(1==a.ne)d=d/(a.ra/3)|0,e=e/(a.Da/3)|0,1!=e?e?zm(a.B,1040,!0):zm(a.B,1038,!0):1!=d&&(d?zm(a.B,1039,!0):zm(a.B,1037,!0));else if(a.V){g=a.Jd;f=b.timeStamp-a.jg;!0===c?(a.Jd=500f){a.V.ke(wn,!0);a.V.ke(wn,!1);return}}if(c||0>a.uc||0>a.Cc)a.uc=d,a.Cc=e;c=Math.round(d-a.uc);b=Math.round(e-a.Cc);a.uc=d;a.Cc=e;a.V.If(c,b,a.uc,a.Cc)}}m.ic=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0}; +m.reset=function(){var a=!0,b=0;this.N&&(b=+Xk(this.N,zk,void 0));this.ja||(this.Ua=3==b?1:3);this.wa=3;switch(this.Ua){case gm:b=7;break;case 5:var c=Om[this.Vc];c&&(b=c[0]);b||(b=4);break;case 1:b=3;this.wa=7;break;default:b=2}this.ya!==b&&(this.ya=b,a=!0);this.C=null;this.pa=this.rd=new Xm(this,1);this.aa=this.Wc=new Xm(this,3);5>this.Ua?this.A=new Xm:(this.A=new Xm(this,this.Ua,null,this.Fd),xn(this));yn(this);this.Ga=null;this.cb=this.ua=-1;this.Pa=0;zn(this,this.wa);if(this.C.ob&&a){a=this.C.ob+ +this.Ub;for(b=this.C.ob;b>1&255,d=d>>8&-129,d>>4==(d&15)&&(d^=15)):(c=d&255,d=(d&256?7:112)|8&d>>8);jc(this.ga,b,c|d<<8)}un(this,!0)}};function xn(a){a.A.vf&1?(a.pa=a.rd,a.aa=a.A):(a.pa=a.A,a.aa=a.Wc)}m.save=function(){var a=new lf(this);N(a,0,hn(this.rd));N(a,1,hn(this.Wc));N(a,2,[this.ya,this.wa,this.Ga]);N(a,3,hn(this.A));return a.data()}; +m.restore=function(a){var b=a[2];this.ya=b[0];this.wa=b[1];this.Ga=b[2];this.C=null;this.pa=this.rd=new Xm(this,1,a[0]);this.aa=this.Wc=new Xm(this,3,a[1]);this.A=new Xm(this,this.Ua,a[3],this.Fd);this.A.Hc&&xn(this);yn(this);if(!An(this))return!1;Bn(this);return!0}; +function Mm(a,b,c,d){if(d)a.Na("Unable to load font ROM (error "+d+": "+b+")");else{hb(a.fe,b,c);try{var e=eval("("+c+")"),f=e.bytes||e;if(!f.length){w("Empty font ROM: "+b);return}if(1==f.length){w(f[0]);return}if(8192==f.length)fm(a,f,[6144,0]);else if(2048==f.length)fm(a,f,[0]);else{a.Na("Unrecognized font data length ("+f.length+")");return}}catch(g){a.Na("Font ROM data error: "+g.message);return}(a.ea||a.ha)&&ub(a)}} +function Cn(a,b){if(1==b)return a.Ca[0]=Rm[0],a.Ca[1]=Rm[7],a.Ca;if(2==b){var c=a.C.tf;if(a.C===a.A){var d=a.A.Tc[0],c=d&7;d&16&&(c|=8);18!=a.A.Tc[1]&&(c|=32)}a.Ca[0]=Rm[c&15];c=c&32?Tm:Sm;for(d=0;df;f++)g=d[f]||0,h=g<<2&252,k=g>>4&252,g=g>>10&252,a.Ca[f]=[h,k,g,255];else{var l=d&&d[255];e=null!=c.Tc[15]?c.Tc:Um;for(f=0;16>f;f++)g=e[f]&63,l?(g|= +(c.Tc[20]&12)<<4,c.Tc[16]&128&&(g&=-49,g|=(c.Tc[20]&3)<<4),g=d[g],h=g<<2&252,k=g>>4&252,g=g>>10&252):(h=(g&4?170:0)|(g&32?85:0),k=(g&2?170:0)|(g&16?85:0),g=(g&1?170:0)|(g&8?85:0)),a.Ca[f]=[h,k,g,255]}a.rb=!0}return a.Ca}function fm(a,b,c,d){a.Uc=b;a.Jb=c;a.Tb=d} +function yn(a,b){var c=!1;if(window&&a.Uc&&(!b||a.U)){var d=0,e=a.Tb?a.Tb:8,f=Cn(a);null!=a.Jb[0]&&$n(a,3,a.Jb[0],d,e,8,a.Uc,f)&&(c=!0);d=a.Tb?0:2048;e=a.Tb?a.Tb:9;null!=a.Jb[1]&&($n(a,1,a.Jb[1],d,e,14,a.Uc,Pm,Qm)&&(c=!0),a.Tb&&$n(a,a.Ua,a.Jb[1],0,a.Tb,14,a.Uc,f)&&(c=!0))}return c}function $n(a,b,c,d,e,f,g,h,k){var l=!1;null!=c&&(ao(a,b,c,d,e,f,g,h,k)&&(l=!0),a.wn&&ao(a,b<<1,c,d,e,f,g,h,k)&&(l=!0));return l} +function ao(a,b,c,d,e,f,g,h,k){var l=!1,n=b&1?0:1,q=a.Oa[b],p=16>h.length?h.length:16;q||(q={Qc:e<W||!H?W:8,wa=ja.createImageData(l.Qc,l.Rc),Ha=0;256>Ha;Ha++){for(Ba= +0;Ba=W-2,Sc=P[Ba>(8<=Xa&&192<=Ha&&223>=Ha?7:Xa)?z:bb;bo(wa,Je,Xd,Ke);v&&bo(wa,Je+1,Xd,Ke)}ja.putImageData(wa,(Ha&15)*l.Qc,(Ha>>4)*l.Rc)}l.Pe[F]="#"+r(z[0],2)+r(z[1],2)+r(z[2],2);l.ui[F]=z;l.Ug[F]=ia;l=!0}}a.Oa[b]=q;return l}function co(a){0a.cb&&(a.cb=0):a.cb=-1} +function Bn(a){if(a.U){for(var b=10;15>=b;b++)if(null==a.C.mb[b])return;var c=a.C.mb[10],b=c&31,d=a.C.mb[11]&31,e=a.C.mb[9]&31,f=!1;a.C===a.A&&(f=!0,7!=e||4!=b||d||(d=7));if(c&32||b>d&&!f||b>e)eo(a);else{c=a.C.mb[15]+((a.C.mb[14]&63)<<8);a.ua!=c&&(eo(a),a.ua=c);d=d-b+1;if(a.kg!=b||a.Ce!=d)a.kg=b,a.Ce=d;a.$a=e+1;co(a)}}} +function eo(a){if(0<=a.ua){if(void 0!==a.fa){var b=a.fa[a.ua];if(b&131072){var b=b&-131073,c=a.ua%a.L,d=a.ua/a.L|0;a.U&&a.Oa[a.U]&&(a.gb&&fo(a,c,d,b,a.gb),fo(a,c,d,b));a.fa[a.ua]=b}}a.ua=-1}} +function go(a){var b,c=a.C;a.hf=!1;var d=c.be[5];if(null!=d){b=1024;var e=0,f=c.be[3]&31;switch(d&3){case 0:if(f){e=32;switch(f&24){case 8:e=96;break;case 16:e=160;break;case 24:e=224}c.dd=f&7}break;case 1:e=1;break;case 2:switch(f&24){default:e=2;break;case 8:e=98;break;case 16:e=162;break;case 24:e=226}break;case 3:a.Ua==gm&&(e=3,c.dd=f&7)}d&8&&(b=1280);c=c.Ke[4];null!=c&&(c&4||(b|=4096,e|=16),d&64&&(c&8&&(b|=16384,e|=4),a.hf=!0));b|=e}return b} +function ho(a,b){var c=a.C;return c&&null!=b&&b!=c.yg?(c.Qg(b),a.ga.Qg(c.ob,c.ac,c.ih(),!0),!0):!1} +function An(a,b){var c,d=a.Ga,e=a.C;if(e)if(1==e.Ua)d=7;else if(5<=e.Ua){var d=null,f=e.Fd>>2,g=32768=e.mb[18]?19:20:21:g&128||350>f?d= +l?13:14:480<=f&&(d=3==a.ya?17:18):d=l?7-d:6:d-=l?2:0);c=go(a)}}else e.gd&8&&(e.gd&2?(d=e.gd&16?6:5,e.gd&4||--d):(d=e.gd&1?3:1,e.gd&4&&--d));else a.Ga=null,null==d&&(d=a.wa);if(!zn(a,d,b))return!1;ho(a,c);return!0} +function zn(a,b,c){if(null!=b&&(b!=a.Ga||c)){a.Rg=0;a.Ga=b;a.rb=!1;b=a.C||(7==b?a.pa:a.aa);if(b!=a.C||b.ob!=a.ob||b.ac!=a.ac){eo(a);if(a.ob){if(!cc(a.ga,a.ob,a.ac))return!1;a.C&&(a.C.Hc=!1)}a.C=b;b.Hc=!0;a.ob=b.ob;a.ac=b.ac;if(!Vb(a.ga,b.ob,b.ac,3,b===a.A?b:null))return!1}a:{a.U=0;a.L=a.kd;a.W=a.me;a.Db=a.L;a.jd=Jm[7][2];b=0;if(c=Jm[a.Ga])a.L=c[0],a.W=c[1],a.jd=c[2],b=c[3],a.U=c[4],4!=a.ya&&7!=a.ya||a.C!==a.A||3!=a.U||(7==(a.A.mb[9]&31)?a.W=350>kn(a.A,18)?43:50:a.U=a.Ua);a.bg=a.L*a.W|0;a.Zf=a.bg/ +a.jd|0;a.Ub=a.Zf;a.td=0;void 0!==b&&(a.Ub=(a.Ub<<1)+b|0,a.td=a.Ub+b>>1);if(a.Oa.length){a.Ja=a.ra/a.L|0;a.Ka=a.Da/a.W|0;if(a.U){b=a.Oa[a.U];if(!b)break a;c=a.Oa[a.U<<1];a.Xf&&80==a.L?c&&a.Ja>=3*c.Qc>>2&&(a.U<<=1,b=c):(c&&a.Ja>=c.Qc&&(a.U<<=1,b=c),a.Xf||(a.Ja=b.Qc,a.Ka=b.Rc));a.bc=a.tc=0;b&&(a.bc=a.L*b.Qc,a.tc=a.W*b.Rc)}else a.Ja=a.Ka=1,a.bc=a.L,a.tc=a.W;a.sb=a.ea.createImageData(a.bc,a.tc);a.fb=document.createElement("canvas");a.fb.width=a.bc;a.fb.height=a.tc;a.gb=a.fb.getContext("2d");a.oe=a.pe= +0;a.Ed=a.ra;a.Hd=a.Da;b=a.ra-a.L*a.Ja;c=a.Da-a.W*a.Ka;0>1,a.Ed-=b);0>1,a.Hd-=c);if(b||c)a.ea.fillStyle=a.ka.style.backgroundColor,a.ea.fillRect(0,0,a.ra,a.Da)}}io(a,!0);un(a)}return!0}function bo(a,b,c,d){b=(b+c*a.width)*d.length;a.data[b]=d[0];a.data[b+1]=d[1];a.data[b+2]=d[2];a.data[b+3]=d[3]}function jo(a){a.Pa=-1;a.Fa=!1;var b=a.Zf;if(void 0===a.fa||a.fa.length!=b)a.fa=Array(b)}function io(a,b){b||(a.rb=!1);jo(a)} +function fo(a,b,c,d,e){var f=d&255,g=d>>8;d=g&15;var h=a.Oa[a.U];h.Af&&(d=h.Af[d]);var k=g>>4&15;h.Af&&(k=h.Af[k]);e?(b*=h.Qc,c*=h.Rc,e.fillStyle=h.Pe[k],e.fillRect(b,c,h.Qc,h.Rc)):(b=b*a.Ja+a.oe,c=c*a.Ka+a.pe,a.ea.fillStyle=h.Pe[k],a.ea.fillRect(b,c,a.Ja,a.Ka));g&256&&(k=(f&15)*h.Qc,f=(f>>4)*h.Rc,e?e.drawImage(h.Ug[d],k,f,h.Qc,h.Rc,b,c,h.Qc,h.Rc):a.ea.drawImage(h.Ug[d],k,f,h.Qc,h.Rc,b,c,a.Ja,a.Ka));g&512&&(f=a.kg,g=a.Ce,e?(a.$a&&a.$a!==h.Rc&&(f=f*h.Rc/a.$a|0,g=g*h.Rc/a.$a|0),e.fillStyle=h.Pe[d], +e.fillRect(b,c+f,h.Qc,g)):(a.$a&&a.$a!==a.Ka&&(f=f*a.Ka/a.$a|0,g=g*a.Ka/a.$a|0),a.ea.fillStyle=h.Pe[d],a.ea.fillRect(b,c+f,a.Ja,g)))} +function un(a,b){if(a.la.cc){var c=!1,d=a.C;d&&(d!==a.A?d.gd&8&&(c=!0):d.Pd&32&&(c=!0));if(c||b){if(b)jo(a);else if(void 0===a.fa)return;var e=!1;!(b||++a.Rg&15)&&0<=a.cb&&(a.cb++,e=!0);var f=0,g=a.bg,h=a.ob,c=h,k=c+a.ac;19<=a.Ga&&(h=c=655360,k=c+65536);if(ko(a,d)&8||d.qf&&d.qf=a.Ga&& +(n<<=1));c+n>k&&(n=k-c,0>n&&(n=0));k=c+n;if(l=!b&&a.Fa){for(var l=a.ga,q=!0,p=c>>>l.La;0f)return;g=f+1}}if(a.U){if(a.Oa[a.U]){d=f;f=0;e=a.Pa=0;h=1048575;n=a.C.gd&32;5<=a.Ua&&(n=a.C.Tc[16]&8);l=a.ua-a.C.Nd;n&&(e=32768,h&=~e,a.cb&2||(h&=-65537));for(c+=d<<1;c>8|(z&255)<<8;var H=e,L=16;n>=h))>>(L-=h);bo(a.sb,n++,q,l[P])}n>F&&(F=n);q=E&&(E=q+1)}k+=2;d++;if(n>=a.L){n=0;q+=2;if(q>a.W)break;q==a.W&&(q=1,k=c+a.td)}}a.Fa=!0; +pa.L?a.Db-a.L-z>>3:0;c>=8;l>p&&(p=l);n=v&&(v=n+1)}c+=E;if(l>=a.L){l=0;if(++n>a.W)break;c+=H}}z||(a.Fa=!0);qa.L?a.Db-a.L-v>>3:0;cH&&(L=H)):(z<<=v,L-=v,a.Fa=!1):(a.Fa&&z===a.fa[d]?(h+=L,L=0):a.fa[d]=z,d++);if(L){hq&&(q=h);l=F&&(F=l+1)}if(h>=a.L){h=0;if(++l>a.W)break;c+=E}}v||(a.Fa=!0);nd&&(b.xh=d,d=-d|0);d%b.sh>b.mm&&(c|=1);d%b.vh>b.om&&(c|=9);b.gi=d/b.vh|0;return c}m.Jl=function(a,b){return lo(this,this.pa,a,b)};m.dn=function(a,b,c){var d=this.pa;d.Lg=d.Ac;d.Ac=b&31;x(this,a,b,c,"CRTC.INDX")};m.Il=function(a,b){return mo(this,this.pa,a,b)};m.cn=function(a,b,c){no(this,this.pa,a,b,c)};m.Kl=function(a,b){return oo(this,this.pa,b)};m.en=function(a,b,c){a=this.pa;x(this,a.port+4,b,c,"MODE");a.gd=b;An(this,!1)}; +m.Ll=function(a,b){return po(this,this.pa,b)};m.hk=function(a,b,c){this.A.fg=this.A.fg&-4|b&3;x(this,a,b,c,"FEAT")};m.hl=function(a,b){var c=this.A.Pd;b&&!A(this)||x(this,960,null,b,"ATC.INDX",c);return c};m.Fk=function(a,b){var c=this.A.Tc[this.A.Pd&31];b&&!A(this)||x(this,960,null,b,"ATC."+this.A.Vg[this.A.Pd&31],c);return c}; +m.gk=function(a,b,c){var d=this.A,e=d.Pd&32;if(d.Ye){d.Ye=!1;var f=d.Pd&31;if(16<=f||!e)c&&!A(this)||x(this,a,b,c,"ATC."+d.Vg[f]),d.Tc[f]=b,io(this,!1)}else d.Pd=b,x(this,a,b,c,"ATC.INDX"),d.Ye=!0,b&32&&!e&&yn(this,!0)&&un(this,!0),a=(d.mb[12]<<8)+d.mb[13]|0,d.Nd!=a&&(d.Nd=a,io(this)),d.qf=0}; +m.Vl=function(a,b){var c=0;if(5==this.Ua)c=3-((this.A.vf&12)>>2),c=(this.Vc&1<>this.A.Kc&63;b&&!A(this)||x(this,969,null,b,"DAC.DATA["+t(this.A.pd)+"]["+t(this.A.Kc)+"]",c);this.A.Kc+=6;12Missing <canvas> support. Please try a newer web browser.";break}e.setAttribute("class","pcjs-canvas");e.setAttribute("width",d.screenWidth);e.setAttribute("height",d.screenHeight);e.style.backgroundColor=d.screenColor;e.style.height="auto";0<=za().indexOf("MSIE")&&(c.onresize=function(a,b,c,d){return function(){b.style.height= +(a.clientWidth*d/c|0)+"px"}}(c,e,d.screenWidth,d.screenHeight),c.onresize());var f=+(d.aspect||$a.aspect);f&&.3<=f&&3.33>=f&&(Ra("onresize",function(a,b,c){return function(){b.style.height=(a.clientWidth/c|0)+"px"}}(c,e,f)),window.onresize());c.appendChild(e);f=document.createElement("textarea");Ia("iOS")&&(f.setAttribute("autocapitalize","off"),f.setAttribute("autocorrect","off"));c.appendChild(f);var g=e.getContext("2d"),d=new Z(d,e,g,f,c);ob(d,c)}}); +function qo(a){this.V=a.adapter;switch(this.V){case 1:this.X=956;this.C=7;break;case 2:this.X=888;this.C=7;break;case 3:this.X=632;this.C=5;break;default:w("Unrecognized parallel adapter #"+this.V);return}this.A=this.B=null;Wa.call(this,"ParallelPort",a,qo,4194304);a=a.binding;"console"==a?this.B="":nb(this,a,ro)}fb(qo);var ro="buffer";m=qo.prototype;m.Pb=function(a,b,c){switch(b){case ro:return this.qa[b]=this.A=c,!0}return!1}; +m.Ic=function(a,b,c,d){this.ga=b;this.F=c;this.ha=d;this.N=Hb(a,"ChipSet");lc(b,this,so,this.X);pc(b,this,to,this.X);ub(this)};m.ic=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){uo(this)};m.save=function(){var a=new lf(this),b=0,c=[];c[b++]=this.L;c[b++]=this.Yb;c[b]=this.Cf;N(a,0,c);return a.data()};m.restore=function(a){return uo(this,a[0])}; +function uo(a,b){var c=0;void 0===b&&(b=[0,0,0]);a.L=b[c++];a.Yb=b[c++];a.Cf=b[c];return!0}m.wl=function(a,b){var c=this.L;x(this,a,null,b,"DATA",c);return c};m.Ul=function(a,b){var c=this.Yb;x(this,a,null,b,"STAT",c);return c};m.sl=function(a,b){var c=this.Cf;x(this,a,null,b,"CTRL",c);return c}; +m.Qm=function(a,b,c){x(this,a,b,c,"DATA");this.L=b;this.Yb|=64;a=!1;y(this,"transmitByte("+t(b)+")");this.A&&(8==b?this.A.value=this.A.value.slice(0,-1):(this.A.value+=String.fromCharCode(b),this.A.scrollTop=this.A.scrollHeight),a=!0);if(null!=this.B){if(10==b||1024<=this.B.length)this.O(this.B),this.B="";10!=b&&(this.B+=String.fromCharCode(b));a=!0}a&&(this.Yb&=-65);vo(this)};m.Lm=function(a,b,c){x(this,a,b,c,"CTRL");this.Cf=b;vo(this)}; +function vo(a){a.N&&a.C&&(a.Cf&16&&!(a.Yb&64)?hg(a.N,a.C):gg(a.N,a.C))}var so={0:qo.prototype.wl,1:qo.prototype.Ul,2:qo.prototype.sl},to={0:qo.prototype.Qm,2:qo.prototype.Lm};Sa(function(){for(var a=pb(document,"pcx86","parallel"),b=0;b=b)a.preventDefault&&a.preventDefault(),64");if(2==b.length){var c=na(b[0]);if(c!=this.zd)return;b=na(b[1]);if(this.ia=jb(b)){var d=this.ia.exports;if(d){var e=d.connect;e&&e.call(this.ia);if(this.ra=d.receiveData){this.status(this.fe+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}}; +m.ic=function(a,b){if(!b)if(this.Wi(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};m.hc=function(a){return a?this.save():!0};m.reset=function(){Ao(this)};m.save=function(){var a=new lf(this),b=0,c=[];c[b++]=this.wa;c[b++]=this.Da;c[b++]=this.fa;c[b++]=this.pa;c[b++]=this.U;c[b++]=this.B;c[b++]=this.C;c[b++]=this.A;c[b++]=this.Ca;c[b]=this.aa;N(a,0,c);return a.data()};m.restore=function(a){return Ao(this,a[0])}; +function Ao(a,b){var c=0;void 0===b&&(b=[0,0,384,0,1,0,0,96,48,[]]);a.wa=b[c++];a.Da=b[c++];a.fa=b[c++];a.pa=b[c++];a.U=b[c++];a.B=b[c++];a.C=b[c++];a.A=b[c++];a.Ca=b[c++];a.aa=b[c];return!0}m.eg=function(a){if("number"==typeof a)this.aa.push(a);else if("string"==typeof a)for(var b=0;b>8:this.pa;x(this,a,null,b,this.B&128?"DLM":"IER",c);return c};m.El=function(a,b){var c=this.U;x(this,a,null,b,"IIR",c);return c}; +m.Fl=function(a,b){var c=this.B;x(this,a,null,b,"LCR",c);return c};m.Hl=function(a,b){var c=this.C;x(this,a,null,b,"MCR",c);return c};m.Gl=function(a,b){var c=this.A;x(this,a,null,b,"LSR",c);return c};m.Ml=function(a,b){var c=this.Ca;x(this,a,null,b,"MSR",c);return c}; +m.on=function(a,b,c){x(this,a,b,c,this.B&128?"DLL":"THR");if(this.B&128)this.fa=this.fa&-256|b;else{this.Da=b;this.A&=-97;a=!1;y(this,"transmitByte("+t(b)+")");this.ra&&this.ra.call(this.ia,b)&&(a=!0);if(this.L)13==b?this.ea=0:8==b?(this.L.value=this.L.value.slice(0,-1),0":String.fromCharCode(b),c=a.length,32>b&&1==c&&(c=0),9==b&&(b=this.Ga||8,c=b-this.ea%b,this.Ga&&(a=ma("",c))),this.Fa&&!this.ea&&c&&(a=String.fromCharCode(this.Fa)+a),this.L.value+=a,this.L.scrollTop= +this.L.scrollHeight,this.ea+=c),a=!0;else if(null!=this.W){if(10==b||1024<=this.W.length)this.O(this.W),this.W="";10!=b&&(this.W+=String.fromCharCode(b));a=!0}a&&(this.A|=96)}};m.$m=function(a,b,c){x(this,a,b,c,this.B&128?"DLM":"IER");this.B&128?this.fa=this.fa&255|b<<8:this.pa=b};m.an=function(a,b,c){x(this,a,b,c,"LCR");this.B=b}; +m.bn=function(a,b,c){var d=this.C;x(this,a,b,c,"MCR");this.C=b;this.V&&(d^b)&3&&(a=this.V,b=this.C,(c=3==(b&3))?a.Hc||(d=!1,a.C&2||(a.reset(),y(a,"serial mouse reset"),d=!0),a.C&1||(y(a,"serial mouse ID requested"),d=!0),d&&(a.N.eg([77,77]),y(a,"serial mouse ID sent")),Co(a),a.Hc=c):a.Hc&&(y(a,"serial mouse inactive"),Do(a),a.Hc=c),a.C=b)}; +var yo={0:wo.prototype.Rl,1:wo.prototype.Dl,2:wo.prototype.El,3:wo.prototype.Fl,4:wo.prototype.Hl,5:wo.prototype.Gl,6:wo.prototype.Ml},zo={0:wo.prototype.on,1:wo.prototype.$m,3:wo.prototype.an,4:wo.prototype.bn};Sa(function(){for(var a=pb(document,"pcx86","serial"),b=0;ba.L||0>a.V)a.L=b.clientX,a.V=b.clientY;a.fa?(c=b.movementX||b.mozMovementX||b.webkitMovementX||0,d=b.movementY||b.mozMovementY||b.webkitMovementY||0):(c=b.clientX-a.L,d=b.clientY-a.V);a.L=b.clientX;a.V=b.clientY;a.If(c,d,a.L,a.V)}} +m.ke=function(a,b){if(this.Hc&&this.F&&this.F.la.Fb){var c="mouse button"+a+" "+(b?"dn":"up");switch(a){case wn:if(this.aa!=b){this.aa=b;Io(this,c);return}break;case 2:if(this.ea!=b){this.ea=b;Io(this,c);return}}y(this,c+": ignored")}};m.If=function(a,b,c,d){this.Hc&&this.F&&this.F.la.Fb&&(a||b)&&(this.U=a,this.W=b,Io(this,null,c,d))}; +function Io(a,b,c,d){var e=64|(a.aa?32:0)|(a.ea?16:0)|(a.W&192)>>4|(a.U&192)>>6,f=a.U&63,g=a.W&63;A(a,8388608)&&y(a,(b?b+": ":"")+(void 0!==d?"mouse ("+c+","+d+"): ":"")+"serial packet ["+t(e)+","+t(f)+","+t(g)+"]",0,!0);a.N.eg([e,f,g]);a.U=a.W=0}Sa(function(){for(var a=pb(document,"pcx86","mouse"),b=0;b>9]);if(f){if(e+c<=f.length)return ap(a.za,f,e,c);for(e=d=0;c--;)d|=Zo(a,b++,1)<=e.hi&&a<=e.dk){d=a-=e.hi;var f,g;for(g in e.we){var h=e.we[g],k=a-h[0];if(!k){c=this.hg+"!"+h[1];break}b&&0>2;var e=d=0,a=new DataView(a,0,c);g.A=Array(g.Bb);for(c=0;cb.indexOf("/api/v1/dump")&&(a=ga(b),"json"==a||"gz"==a?f=encodeURI(b):"demandrw"==this.mode||"demandro"==this.mode?(f=fp(this,b),this.tg=!0):(c="path",d="&mbhd=10",!b.indexOf("http:")||!b.indexOf("ftp:")||0<="dsk ima img 360 720 12 144".split(" ").indexOf(a)?(c="disk",d="&mbhd=0"):ha(b,"/")&& +(c="dir"),f=ya()+"/api/v1/dump?"+c+"="+encodeURIComponent(b)+(this.cf?"":d)+"&format=json"));return!!xa(f,null,!0,function(a,b,c){gp(g,a,b,c)})}; +function gp(a,b,c,d){var e=null;a.ff=!1;var f=0>d&&a.X&&!a.X.la.cc;if(a.tg)d?a.controller.Na('Unable to connect to disk "'+a.V+'" (error '+d+": "+c+")",f):(a.N=!0,hp(a),e=a);else if(d)a.controller.Na('Unable to load disk "'+a.ga+'" (error '+d+": "+b+")",f);else{hb(a.controller.fe,b,c);try{if(0g&&0c.indexOf("0x")&&'["'!=c.substr(0,2)?JSON.parse(c.replace(/([a-z]+):/gm,'"$1":').replace(/\/\/[^\n]*/gm,"")):eval("("+c+")");if(h.length)if(1==h.length)w(h[0]);else{a.Bb=h.length;a.ub=h[0].length;a.lb=h[0][0].length;var k=h[0][0][0];a.Va=k&&k.length||512;for(d=c=0;d>2,n=k.pattern;void 0===n&&(n=k.pattern=0);var q=k.data;if(void 0===q){var p=k.bytes;if(void 0!==p&&p.length){for(var z= +l<<2,F=p.length;Fb;b++){if(128==ap(a,e,c+0,1)){d.$f=ap(a,e,c+8,4);(e=$o(a,d.$f))&&(f=!0);break}c+=16}if(!f)return}d.Hf||(d.Hf=ap(a,e,19,2)||ap(a,e,32,4),d.Gf=ap(a,e,14,2),d.mh=d.Gf+ap(a,e,22,2)*ap(a,e,16,1),d.wh=ap(a,e,17,2),d.Ag=ap(a,e,13,1));d.kh=d.mh+((32*d.wh+(d.Va-1))/d.Va|0);d.lm=(d.Hf-d.kh)/d.Ag|0;d.Cg=4084>=d.lm?12:16;d.Vk=12==d.Cg?4086:65526;b=[];for(e=d.mh;e>8;f+=2;if(k)for(;l--;)Zo(d,f,1),254>=k?(n=k,q=Zo(d,f+1),f+=3):(n=Zo(d,f+3,1),q=Zo(d,f+4),f+=6),d.Ad[n]&&(d.Ad[n].we[h]=[q]),d.A[h]=[n,q],h++;else h+=l}(g=bp(e,Wo,c))&&cp(e,g+c);g=bp(e,Xo,c);h=bp(e,Uo,c);g&&h&&cp(e,g,g+h)}}}} +function kp(a,b,c,d,e){var f,g=a.C.length,h=b.Va/32|0;b.Do=d+"\\";for(var k=0;kF)break;for(var v=p.kh+(F-2)*p.Ag,E=0;E>3,1),d?e=16==b.Cg?e<<8:c&7?e<<4:(e&15)<<8:c&7&&(e>>=4));return e} +function $o(a,b){var c=a.ub*a.lb,d=b/c|0;return dg)break;e|=g<=f)break;e+=String.fromCharCode(f)}return e}function ep(a,b,c,d,e,f){a||(a={sector:d,length:e,data:[],pattern:f});a.Wk=b;a.Xk=c;a.wd=a.Zc=0;a.Wa=!1;return a} +function fp(a,b){var c;c="action=open&volume="+b+("&mode="+a.mode);c+="&chs="+a.Bb+":"+a.ub+":"+a.lb+":"+a.Va;c+="&machine="+a.controller.gf();c+="&user="+a.controller.le();return ya()+"/api/v1/disk?"+c} +function mp(a,b,c,d,e,f,g){if(a.N){var h;h="action=read&volume="+a.V;h+="&chs="+a.Bb+":"+a.ub+":"+a.lb+":"+a.Va;h=h+("&addr="+b+":"+c+":"+d+":"+e)+("&machine="+a.controller.gf());h+="&user="+a.controller.le();xa(ya()+"/api/v1/disk?"+h,null,f,function(h,l,n){h=[b,c,d,e,f,g];var q=!1,p=h[0],z=h[1],F=h[2],v=h[3];if(!n){l=JSON.parse(l);for(q=0;v--;){var E=a.seek(p,z,F,!0);if(!E)break;ip(E,l,q);q+=E.length;F++}q=h[4]}(h=h[5])&&h(n,q)})}else g&&g(-1,!1)} +function np(a,b,c,d,e,f,g){if(a.N){var h={};a.fa=!0;h.action="write";h.volume=a.V;h.chs=a.Bb+":"+a.ub+":"+a.lb+":"+a.Va;h.addr=b+":"+c+":"+d+":"+e;h.machine=a.controller.gf();h.user=a.controller.le();h.data=JSON.stringify(f);xa(ya()+"/api/v1/disk",h,g,function(f,h,n){var q=[b,c,d,e,g];f=q[0];h=q[1];var p=q[2],z=q[3],q=q[4];a.fa=!1;if(0<=f&&fb&&(b=0);2E3>2,e=Array(d),f=0;f>2,e=a.data;a=a.pattern;for(var f=0;f>8&255;c[d++]=g>>16&255;c[d++]=g>>24&255}return c}m.read=function(a,b){var c=-1;if(a&&b>2,c=(d>((b&3)<<3)&255;return c}; +m.write=function(a,b,c){if(this.ff)return!1;if(b>2;b=(b&3)<<3;for(var g=d.length;g<=f;g++)d[g]=e;a.Zc?f=a.wd+a.Zc&&(a.Zc+=f-(a.wd+a.Zc)+1):(a.wd=f,a.Zc=1);d[f]=d[f]&~(255<=this.A.length||k>=this.A[h].length||l>=this.A[h][k].length){c="sector (CHS="+h+":"+k+":"+l+") out of range ("+ +b+" changes applied)";b=-1;break}if(this.ff){c="unable to modify write-protected disk";b=-1;break}e=g[f++];f=g[f++];g=e+f.length;if(h=this.A[h][k][l]){for(k=h.data.length;kb?-2!=b&&this.controller.Na("Unable to restore disk '"+this.ga+": "+c):hp(this);return b}; +m.toJSON=function(){var a;a=0;for(var b;b=$o(this,a++);)sp(b);a=JSON.stringify(this.A,function(a,b){return"file"==a?void 0:b});a=a.replace(/,"length":512/gm,"").replace(/,"pattern":0/gm,"");a=a.replace(/"(sector|length|data|pattern)":/gm,"$1:");a=a.replace(/,"[^"]*":([0-9]+|true|false)/gm,"");a=a.replace(/(sector|length|data|pattern):/gm,'"$1":');return a=a.replace(/([\]}]),/gm,"$1,\n")}; +function sp(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function tp(a){Wa.call(this,"FDC",a,tp,524288);this.dmaRead=this.zk;this.dmaWrite=this.Ak;this.dmaFormat=this.Ok;this.U=a.autoMount||null;this.fa=a.sortBy||"name";"none"==this.fa&&(this.fa=null);this.B=[];this.ia=!Ia("Mobi")&&window&&"FileReader"in window}fb(tp);aa={}; +var up={3:{Wd:3,je:0,name:aa.bo},4:{Wd:2,je:1,name:aa.$n},5:{Wd:9,je:7,name:aa.lo},6:{Wd:9,je:7,name:aa.Vn},7:{Wd:2,je:0,name:aa.Xn},8:{Wd:1,je:2,name:aa.ao},10:{Wd:2,je:7,name:aa.Wn},13:{Wd:6,je:7,name:aa.Hn},15:{Wd:3,je:0,name:aa.Zn}};m=tp.prototype; +m.Pb=function(a,b,c){var d=this;switch(b){case "listDisks":this.qa[b]=c;if(this.fa){b=[];for(a=0;a'+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.qa[b]=c,c.onchange=function(){var a=ca(c.value,10);null!=a&&vp(d,a)},!0;case "loadDrive":return this.qa[b]=c,c.onclick=function(){var a=d.qa.listDisks;a&&wp(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.ia){c.parentNode.removeChild(c);break}this.qa[b]=c;c.onclick=function(){var a=d.qa.listDrives;a&&a.options&&d.A&&(a=ca(a.value,10),(a= +d.A[a])?(a=a.za)?(a=Ja(rp(a),"octet-stream",!0,a.Pg.replace(".json",".img")),w(a)):d.Na("No diskette loaded in drive."):d.Na("No diskette drive selected."))};return!0;case "mountDrive":if(!this.ia){c.parentNode.removeChild(c);break}this.qa[b]=c;c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length});c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;wp(d,fa(b,!0),b,a)}return!1};return!0}return!1}; +m.Ic=function(a,b,c,d){this.ga=b;this.F=c;this.ha=d;this.X=a;this.N=Hb(a,"ChipSet");if((this.U=Qc(this.X,"autoMount")||this.U)&&"string"==typeof this.U)try{this.U=eval("("+this.U+")")}catch(e){w("FDC auto-mount error: "+e.message+" ("+this.U+")"),this.U=null}xp(this);lc(b,this,yp);pc(b,this,zp);Ap(this,"None","",!0);this.ia&&Ap(this,"Local Disk","?");Ap(this,"Remote Disk","??");Bp(this)||ub(this)}; +m.ic=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.X.fh){this.B=[];for(var c=0;cg.za.restore(p)&&(h=!1);h&&g.za&&void 0!==g.eb&&(g.pb=g.za.seek(g.Qb,g.kb,g.xb));h||(e=!1)}a.W=b[c++]||0;a.jc=b[c]||0;return e}m.Ii=function(a){var b;a=this.A[a];if(void 0!==a){b={};for(var c in a)b[c]=a[c]}return b}; +m.pk=function(a,b,c){if(a.za){var d=a.za.info(),e=d[2],f=d[1]*e;if(b+c<=d[0]*f)return a.Qb=Math.floor(b/f),b%=f,a.kb=Math.floor(b/e),a.xb=b%e+1,a.Ib=c*d[3],a.Cb=0,!0}return!1}; +function Bp(a,b){b||(a.ea=0);if(a.U)for(var c in a.U){var d=a.U[c],e=d.path,f;if(!(f=d.name))a:{if((f=a.qa.listDisks)&&f.options)for(var g=0;gEp(a,e,b,c,!1,d)&&window.confirm("Click OK to reload the original disk.\n(WARNING: All disk changes will be discarded)");){for(var f=a,g=c,h=void 0,h=0;ha.Bb||f[1]>a.ub)&&(this.Na('Diskette "'+c+'" too large for drive '+String.fromCharCode(65+a.hb)),b=null);b?(a.za=b,a.nk=c,a.Me=d,Fp(this,c,d,b),f=b.info(),this.W|=128,this.Na('Mounted diskette "'+c+'" in drive '+String.fromCharCode(65+a.hb),a.Ae||e),a.Bg=f[0],a.Of=f[1],a.Pf=f[2],this.X&&this.X.yd()):a.af=!1;a.Ae&&(a.Ae=!1,--this.ea||ub(this));vp(this,a.hb)}; +function Ap(a,b,c,d){if((a=a.qa.listDisks)&&a.options){for(var e=0;e=this.C&&(this.ma&=-81,this.L=this.C=0);return c}; +m.Sm=function(a,b,c){A(this)&&x(this,a,b,c,"DATA["+this.C+"]");this.C=up[a].Wd){b=!1;this.L=0;a=Gp(this);var d,e,f,g,h=a&31;switch(h){case 3:Gp(this);Gp(this);Hp(this);break;case 4:c=Gp(this);this.hb=c&3;d=this.A[this.hb];Hp(this);Ip(this,(d.Cb&-16777216)>>>24);break;case 5:case 6:c=Gp(this);b=c>>2&1;this.hb=c&3;d=this.A[this.hb];d.kb=b;c=d.Qb=Gp(this);e=Gp(this);f=d.xb=Gp(this);g=Gp(this);d.Ib=128<>2&1;this.hb=c&3;d= +this.A[this.hb];c=d.Qb;e=d.kb=b;f=d.xb=1;g=0;d.Cb=0;d.za&&(d.pb=d.za.seek(d.Qb,d.kb,d.xb))?g=d.pb.length>>8:d.Cb=72;Jp(this,d,a,b,c,e,f,g);b=!0;break;case 13:c=Gp(this);b=c>>2&1;this.hb=c&3;d=this.A[this.hb];c=d.Qb;e=d.kb=b;f=1;g=Gp(this);d.Ib=128<>2&1,c=Gp(this),d.Qb+=c-d.he,0>d.Qb&&(d.Qb=0),d.Qb>=d.Bb&&(d.Qb=d.Bb-1),d.he=c,d.Cb=32,d.Qb||(d.Cb|=268435456),Hp(this),b=!0}0>>8);Ip(a,(b.Cb&16711680)>>>16);var k=0;if(e!=b.Qb||f!=b.kb)k=g=1;c&128&&(f^=k,d||(k=0));Ip(a,e+k);Ip(a,f);Ip(a,g);Ip(a,h)}function Gp(a){var b=a.V[a.L];a.L++;return b}function Hp(a){a.L=a.C=0}function Ip(a,b){a.V[a.C++]=b}m.zk=function(a,b,c){void 0===b||0>b?this.Je(a,c):c(-1,!1)};m.Ak=function(a,b){return void 0!==b&&0<=b?Kp(a,b):-1}; +m.Ok=function(a,b){var c;if(void 0!==b&&0<=b)a:if(c=b,a.Cb)c=-1;else{a.md[a.We++]=c;if(a.We==a.md.length){a.Qb=a.md[0];a.kb=a.md[1];a.xb=a.md[2];a.Ib=128<Kp(a,a.zi)){c=-1;break a}a.pg++}a.pg>=a.ie&&(c=-1)}else c=-1;return c};m.Je=function(a,b){var c=-1,d=null,e=0;if(!a.Cb&&a.za){do{if(a.pb&&(e=a.eb,0<=(c=a.za.read(a.pb,a.eb++)))){d=a.pb;break}a.pb=a.za.seek(a.Qb,a.kb,a.xb);if(!a.pb){a.Cb=1088;break}a.eb=0;Lp(a)}while(1)}b(c,!1,d,e)}; +function Kp(a,b){if(a.Cb||!a.za)return-1;do{if(a.pb&&a.za.write(a.pb,a.eb++,b))break;a.pb=a.za.seek(a.Qb,a.kb,a.xb);if(!a.pb){a.Cb=8256;b=-1;break}a.eb=0;Lp(a)}while(1);return b}function Lp(a){a.xb++;a.xb>=a.Pf+1&&(a.xb=1,a.kb++,a.kb>=a.Of&&(a.kb=0,a.Qb++))}var yp={1009:tp.prototype.yl,1012:tp.prototype.Al,1013:tp.prototype.xl,1015:tp.prototype.zl},zp={1010:tp.prototype.Tm,1013:tp.prototype.Sm,1015:tp.prototype.Rm}; +Sa(function(){for(var a=pb(document,"pcx86","fdc"),b=0;bk.za.restore(g)&&(z=!1),z&&void 0!==k.eb&&(k.pb=k.za.seek(k.ee,k.kb,k.xb+ +k.og)));z||(e=!1);null!=a.pa&&1>=d&&(a.pa|=(f.type&3)<<(1-d<<1))}0<=a.hb&&(a.B=a.A[a.hb]);return e}m.Ii=function(a){var b;a=this.A[a];if(void 0!==a){b={};for(var c in a)b[c]=a[c]}return b}; +function Vp(a,b,c){if(b){var d=0,e=0;null==c&&((d=b.Re[2])?e=b.Re[0]<<8|b.Re[1]:c=b.type);null==c||d||(d=Op[a.U][c][1],e=Op[a.U][c][0]);d&&((c=Op[a.U][b.type])&&e!=c[0]&&d!=c[1]&&a.Na("Warning: drive parameters ("+e+","+d+") do not match drive type "+b.type+" ("+c[0]+","+c[1]+")"),b.Bb=e,b.ub=d,null==b.za&&(b.za=new Jo(a,b,b.mode)))}} +m.pk=function(a,b,c){if(a.za){var d=a.za.info(),e=d[0];if(e){var f=d[2],g=d[1]*f;if(b+c<=e*g)return a.ee=Math.floor(b/g),b%=g,a.kb=Math.floor(b/f),a.xb=b%f,a.Ib=c*d[3],a.errorCode=0,!0}}return!1}; +function Tp(a,b){b||(a.ea=0);for(var c=0;c=this.C&&(this.L=this.C=0,this.ma&=-15);return c};m.qn=function(a,b,c){x(this,a,b,c,"DATA["+this.C+"]");this.C=a&&(this.ma|=2,this.ma&=-2,Wp(this))};m.am=function(a,b){var c=this.ma;x(this,a,null,b,"STATUS",c);this.L=a.B.Va?(a.ma=128,a.Je(a.B,function(b){0<=b?(Yp(a),a.N&&5180==a.N.ja&&(a.ma=0),a.ma|=88):(a.ma=1,a.W=16)},!1)):a.ma=80));return d}m.Dk=function(a,b){return Xp(this,a,b)|Xp(this,a,b)<<8}; +function Zp(a,b,c,d){if(a.B&&a.B.Ib>=a.B.Va)if(0>$p(a.B,c))a.ma=1,a.W=16;else if(1==a.B.eb||a.B.eb==a.B.Va)A(a,1048832)&&x(a,b,c,d,"DATA["+a.B.eb+"]"),1=a.B.Va&&(a.ma|=8))}m.zm=function(a,b,c){Zp(this,a,b&255,c);Zp(this,a,b>>8&255,c)};m.gl=function(a,b){var c=this.W;x(this,a,null,b,"ERROR",c);return c};m.Em=function(a,b,c){x(this,a,b,c,"WPREC");this.Pa=b};m.il=function(a,b){var c=this.aa;x(this,a,null,b,"SECCNT",c);return c}; +m.Cm=function(a,b,c){x(this,a,b,c,"SECCNT");this.aa=b};m.jl=function(a,b){var c=this.Ca;x(this,a,null,b,"SECNUM",c);return c};m.Dm=function(a,b,c){x(this,a,b,c,"SECNUM");this.Ca=b};m.el=function(a,b){var c=this.ya;x(this,a,null,b,"CYLLO",c);return c};m.ym=function(a,b,c){x(this,a,b,c,"CYLLO");this.ya=b};m.dl=function(a,b){var c=this.wa;x(this,a,null,b,"CYLHI",c);return c};m.xm=function(a,b,c){x(this,a,b,c,"CYLHI");this.wa=b};m.fl=function(a,b){var c=this.ra;x(this,a,null,b,"DRVHD",c);return c}; +m.Am=function(a,b,c){x(this,a,b,c,"DRVHD");this.ra=b;this.ma=this.A[this.ra&16?1:0]?this.ma|80:this.ma&-65};m.kl=function(a,b){var c=this.ma;x(this,a,null,b,"STATUS",c);this.ma&64&&(this.ma&=-129);return c};m.wm=function(a,b,c){x(this,a,b,c,"COMMAND");this.Da=b;this.N&&gg(this.N,14);aq(this)};m.Bm=function(a,b,c){x(this,a,b,c,"FDR");this.fa&4&&!(b&4)&&(this.W=1);this.fa=b}; +function aq(a){var b=!1,c=a.Da,d=a.ra&16?1:0,e=a.ra&15,f=a.ya|(a.wa&3)<<8,g=a.Ca,h=a.aa||256;a.hb=-1;a.B=null;a.W=0;a.ma=80;var k=a.A[d];k?(k.ee=f,k.kb=e,k.xb=g,k.Ib=h*k.Va,c=144<=c?c:c&240,k.pb=null,k.eb=0,k.errorCode=0,a.hb=d,a.B=k):c=-1;switch(c&240){case 16:b=!0;break;case 32:a.ma=128;a.Je(k,function(b){0<=b&&a.N?(Yp(a),a.ma=88):(a.ma=1,a.W=16)},!1);break;case 48:a.ma=8;break;case 64:b=!0;break;case 112:b=!0;break;case 144:a.W=1;b=!0;break;case 145:k.ub=e+1,k.lb=h,b=!0}b&&Yp(a)} +function Yp(a){!a.N||a.fa&2||hg(a.N,14,120)} +function Wp(a){a.L=0;var b=bq(a),c=bq(a),d=c&32,e=d>>5,f=c&31,g=bq(a),h=bq(a),k=g<<2&768|h,l=g&63,n=bq(a),q=bq(a),p=a.A[e];p&&(p.ee=k,p.kb=f,p.xb=l,p.Ib=n*p.Va);switch(b){case 3:cq(a,p?p.errorCode:4);dq(a,c);dq(a,g);dq(a,h);dq(a,0|d);b=-1;break;case 12:for(c=0;0<=(b=bq(a));)p&&cb?this.Je(a,c):c(-1,!1)};m.Ck=function(a,b){return void 0!==b&&0<=b?$p(a,b):-1}; +m.Pk=function(a,b){var c;void 0!==b&&0<=b?(c=b,a.eb$p(a,a.zi)){c=-1;break a}a.pg++}a.pg>=a.ie&&(c=-1)}else c=-1;return c}; +function eq(a,b,c){b.errorCode=4;if(b.za&&(b.pb=null,a.N)){b.errorCode=0;Bl(a.N,3,a,"dmaRead",b);tl(a.N,3,function(a){a||0!=b.errorCode||(b.errorCode=4);c(b.errorCode?2:0)});return}c(b.errorCode?2:0)}function fq(a,b,c){b.errorCode=4;if(b.za&&(b.pb=null,a.N)){b.errorCode=0;Bl(a.N,3,a,"dmaWrite",b);tl(a.N,3,function(a){a||(0==b.errorCode&&(b.errorCode=4),20==b.errorCode&&(b.errorCode=0));c(b.errorCode?2:0)});return}c(b.errorCode?2:0)} +function gq(a,b,c){b.errorCode=4;b.Se&&b.Se.length==b.Ib||(b.Se=Array(b.Ib));b.eb=0;a.N?(b.errorCode=0,Bl(a.N,3,a,"dmaWriteBuffer",b),tl(a.N,3,function(a){a||0!=b.errorCode||(b.errorCode=4);c(b.errorCode?2:0)})):c(b.errorCode?2:0)} +m.Je=function(a,b,c){var d=-1,e=null,f=0;if(a.errorCode)return b&&b(d,!1,e,f),d;var g=!1!==c?1:0;if(a.pb&&(f=a.eb,d=a.za.read(a.pb,a.eb),a.eb+=g,0<=d))return e=a.pb,b&&b(d,!1,e,f),d;if(b){if(a.za)return a.za.seek(a.ee,a.kb,a.xb+a.og,!1,function(c,k){(a.pb=c)?(e=c,f=a.eb=0,hq(a),d=a.za.read(a.pb,a.eb),a.eb+=g):a.errorCode=20;b(d,k,e,f)}),d;a.errorCode=20;b(d,!1,e,f)}return d}; +function $p(a,b){if(a.errorCode)return-1;do{if(a.pb&&a.za.write(a.pb,a.eb++,b))break;a.za&&a.za.seek(a.ee,a.kb,a.xb+a.og,!0,function(b){a.pb=b});if(!a.pb){a.errorCode=20;b=-1;break}a.eb=0;hq(a)}while(1);return b}function hq(a){a.xb++;var b=1-a.og;a.xb>=a.lb+b&&(a.xb=b,a.kb++,a.kb>=a.ub&&(a.kb=0,a.ee++))}m.bm=function(){var a=this.F.M&255;!(this.F.G>>8)&&128>8||!this.N)||(a=!(this.N.vc[0].Cd&64));return a?!0:!1}; +var Qp={800:Mp.prototype.$l,801:Mp.prototype.am,802:Mp.prototype.Zl},Pp={496:Mp.prototype.Dk,497:Mp.prototype.gl,498:Mp.prototype.il,499:Mp.prototype.jl,500:Mp.prototype.el,501:Mp.prototype.dl,502:Mp.prototype.fl,503:Mp.prototype.kl},Sp={800:Mp.prototype.qn,801:Mp.prototype.tn,802:Mp.prototype.sn,803:Mp.prototype.rn,807:Mp.prototype.ii,811:Mp.prototype.ii,815:Mp.prototype.ii},Rp={496:Mp.prototype.zm,497:Mp.prototype.Em,498:Mp.prototype.Cm,499:Mp.prototype.Dm,500:Mp.prototype.ym,501:Mp.prototype.xm, +502:Mp.prototype.Am,503:Mp.prototype.wm,1014:Mp.prototype.Bm};Sa(function(){for(var a=pb(document,"pcx86","hdc"),b=0;b>2;this.Ba=b.zg;this.bc=new gd(this.F,7,"DBG");this.Ga=zq;80186<=this.F.ja&&(this.Ga=zq.slice(),this.Ga[15]=xq,80286<=this.F.ja&&(this.Ga[15]=yq,80386<=this.F.ja&&(this.Ja=8)));Pk(this,64,function(a){Dq(d,d.F.ld,a[0])});Pk(this,4,function(a){if(a=a[0]){var b=Eq(d,a);if(void 0===b)d.O("invalid selector: "+a);else if(a=Fq(d, +b,2),d.O("dumpSel("+u(a?a.Z:b)+"): %"+r(a?a.Xb:null,d.Ca)),a){var c,b=!1;if(a.type&4096)a.type&2048?(c="code"+(a.type&512?",readable":",execonly"),a.type&1024&&(c+=",conforming")):(c="data"+(a.type&512?",writable":",readonly"),a.type&1024&&(c+=",expdown")),a.type&256&&(c+=",accessed");else{var h=Gq[a.type];h&&(c=h[0],b=h[1])}!c||a.wb&32768||(c+=",not present");d.O((b?"seg="+u(a.Aa&65535)+" off="+u(a.Ta):"base="+r(a.Aa,d.Ca)+" limit="+Hq(a.Ta))+" type="+t(a.type>>8)+" ("+c+") ext="+u(a.ext&-65296)+ +" dpl="+t(a.Gc))}}else d.O("no selector")});Pk(this,134217728,function(a){var b;(a=a[0])&&(b=Eq(d,a));if(void 0===b)d.O("invalid MCB");else for(d.O("dumpMCB("+u(b)+")");b;){a=jq(d,0,b);var c=d.Qa(a,1),h=d.na(a,2),k=d.na(a,5);if(77!=c&&90!=c)break;d.O(Iq(0,b)+": '"+String.fromCharCode(c)+"' PID="+u(h)+" LEN="+u(k)+' "'+Jq(d,a,8)+'"');b+=1+k}});Pk(this,128,function(a){Dq(d,d.F.sa,a[0],d.F.sa!==d.F.ld)});Pk(this,8,function(a){a:{if(a=a[0]){var b=Eq(d,a);if(void 0===b){d.O("invalid task selector: "+a); +break a}a=Fq(d,b,2)}else a=d.F.Sa;d.O("dumpTSS("+u(a?a.Z:b)+"): %"+r(a?a.Aa:null,d.Ca));if(a){var b="",c=a.type&-513,h=256==c?4:8,k=256==c?Kq:Lq,l,n,q,p;for(p in k)l=k[p],n=a.Aa+l,q=Lf(d.F,n,2),2304==c&&(q|=Lf(d.F,n+2,2)<<16),b&&(b+="\n"),b+=u(l)+" "+ma(p+":",11)+r(q,h);if(2304==c)for(p=0,l=q>>>16;lp;)n=a.Aa+l,q=Lf(d.F,n,2),b+="\n"+u(l)+" ports "+u(p)+"-"+u(p+15)+": "+ea(q,2),p+=16,l+=2;d.O(b)}}});this.C=null;this.rb=0;this.cb=!1;ff(this.F,48,this.em.bind(this));ff(this.F,65,this.fm.bind(this)); +this.ka=null;ff(this.F,104,this.gm.bind(this));ub(this)};function Mq(a,b,c,d,e,f){b=Jq(a,b);var g=Fq(a,d),g=g?g.Ta+1:0,h=(e?"_CODE":"_DATA")+r(c,2);f&&A(a,128)&&a.message(b+" "+(e?"code":"data")+"("+r(c,4)+")=#"+r(d,4)+" len "+r(g));e=Nq(a,b,c);e[b+h]=0;em(a,b,c,d,0,null,g,e)} +function Oq(a,b,c,d){var e=a.na(b,2),f=a.na(b,2),g=a.oa(b,4),h=a.oa(b,4),k=jq(a,a.oa(b,4),a.na(b,2));b=jq(a,a.oa(b,4),a.na(b,2));b=Jq(a,b).toUpperCase();var k=Jq(a,k).toUpperCase(),l=(c?"_CODE":"_DATA")+r(e,2);d&&A(a,128)&&a.message((b==k?"":b+"!")+k+" "+(c?"code":"data")+"("+r(e,4)+")="+r(f,4)+":"+r(g)+" len "+r(h));c=Nq(a,k,e);c[k+l]=g;em(a,k,e,f,g,null,h,c)}function Pq(a,b,c){c=Jq(a,c).toUpperCase();Qq(a,c,b)} +m.em=function(){var a=this.F;if(null!=this.C&&2752554==a.G){var b=a.M&65535,c=a.K&65535,d=jq(this,I(a)+12,a.ta.Z);switch(this.oa(d)){case 336:Oq(this,jq(this,a.H,b),!c,!!this.C)}}return!0}; +m.fm=function(a){var b=this.F,c=b.G&65535,d=b.H&65535,e=b.I&65535,f=b.M&65535,g=b.K&65535,h=b.J&65535,k=b.Xa.Z;if(null==this.C)return 79==c&&gf(b,a,function(a){return function(){62342!=(b.G&65535)?(b.G=b.G&-65536|62342,y(a,"INT 0x41 handling enabled",128),a.C=!0):(y(a,"INT 0x41 monitoring enabled",128),a.C=!1)}}(this)),!0;switch(c){case 79:this.C&&(b.G=b.G&-65536|62342,y(this,"INT 0x41 handling enabled",128));break;case 80:Mq(this,jq(this,h,k),d+1,e,!(g&1),!!this.C);break;case 82:Qq(this,null,d); +break;case 127:this.C&&(b.G=b.G&-65536|(this.cb?0:1));break;case 131:this.C&&(a=jq(this,b.M,e),this.rb++?(this.O("TRAPFAULT failed"),Rq(this,this.A,a,!0,!0),this.rb=0,this.Wb()):(this.O("INT 0x41 TRAPFAULT: fault="+u(d)+" error="+("0x"+r(b.K))+" addr="+Sq(a)),this.Td(this.A,a,!0),lq(this,!0)));break;case 141:this.C&&(b.G=b.G&-65536|1);break;case 336:Oq(this,jq(this,b.H,f),!g,!!this.C);break;case 338:Pq(this,d,jq(this,b.J,f))}this.cb=!1;return!this.C}; +m.gm=function(a){var b=this.F,c=b.G&255,d=b.G>>8&255,e=b.H&65535,f=b.I&65535,g=b.M&65535,h=b.J&65535,k=b.Xa.Z;if(null==this.ka){if(67==d){if(609437257==b.oa((b.va.Z<<4)+10)||1111835735==b.oa((b.va.Z<<4)+95))return!0;gf(b,a,function(a){return function(){62342!=(b.G&65535)?(b.G=b.G&-65536|62342,y(a,"INT 0x68 handling enabled",128),a.C=a.ka=!0):(y(a,"INT 0x68 monitoring enabled",128),a.ka=!1)}}(this))}return!0}switch(d){case 67:this.ka&&(b.G=b.G&-65536|62342);break;case 68:this.ka&&(a=id(b.va,this.Kk.bind(this)))&& +(b.J=a[0],yd(b,a[1]));break;case 72:Qq(this,null,e);break;case 80:32==c?Mq(this,jq(this,h,k),0,f,!0,!!this.ka):128>c?Mq(this,jq(this,h,k),e+1,c&64?g:f,!(c&1),!!this.ka):Oq(this,jq(this,h,k),!(c&1),!!this.ka),this.ka&&(b.G=b.G&-256|1)}return!this.ka};m.Kk=function(){var a=this.F;5==(a.G&255)&&(a.I=a.K=0,a.G=a.G&-256|1);return!1}; +m.Pb=function(a,b,c){var d=this;switch(b){case "debugInput":return this.Ka=this.qa[b]=c,c.onkeydown=function(a){var b;if(13==a.keyCode)b=c.value,c.value="",nq(d,b,!0);else if(27==a.keyCode)c.value=b="";else if(38==a.keyCode?d.U>>0)+1;a.wb=f;a.type=g;a.ext=k;a.Xb=d;hd(a,!0,!0,!1)}}return a}m.dc=function(a,b,c){var d=a&&a.Ea;if(null==d&&(d=-1,a)){var e=Fq(this,a.Z,a.type);e&&(b=a.Ra||0,c=c||1,d=e=-1===e.Xb||e.cd&&(b>>>0)+c>e.Zb||!e.cd&&(b>>>0)+c<=e.Zb?e.Aa+b|0:-1,a.Ea=d)}return d};m.Qa=function(a,b){var c=255,d=this.dc(a,!1,1);-1!==d&&(c=Lf(this.F,d,1,5==a.type)|0,b&&Uq(this,a,b));return c}; +m.tb=function(a,b){return a.Rb?this.oa(a,b?4:0):this.na(a,b?2:0)};m.na=function(a,b){var c=65535,d=this.dc(a,!1,2);-1!==d&&(c=Lf(this.F,d,2,5==a.type),b&&Uq(this,a,b));return c};m.oa=function(a,b){var c=-1,d=this.dc(a,!1,4);-1!==d&&(c=Lf(this.F,d,4,5==a.type),b&&Uq(this,a,b));return c};m.qc=function(a,b,c,d){var e=this.dc(a,!0,1);if(-1!==e){if(5!=a.type)this.F.qc(e,b);else{var f=this.ga;f.sa[(e&f.Hb)>>>f.La].xf(e&f.A,b&255,e)}c&&Uq(this,a,c);d||Wc(this.F,!0)}}; +m.jb=function(a,b,c){var d=this.dc(a,!0,2);-1!==d&&(5!=a.type?this.F.jb(d,b):jc(this.ga,d,b),c&&Uq(this,a,c),Wc(this.F,!0))};function jq(a,b,c,d,e,f,g){return Vq(a,{},b,c,d,e,f,g)}function Vq(a,b,c,d,e,f,g,h){b.Ra=c||0;b.Z=d;b.Ea=e;b.type=f||(Tq(a)?2:1);b.Rb=null!=g?g:a.F&&4==a.F.va.ba;b.oc=null!=h?h:a.F&&4==a.F.va.Oc;b.Yd=!1;return b}function Wq(a){return[a.Ra,a.Z,a.Ea,a.Yd,a.Rb,a.oc,a.Te,a.Xd]}function Xq(a){return{Ra:a[0],Z:a[1],Ea:a[2],Yd:a[3],Rb:a[4],oc:a[5],Te:a[6],Xd:a[7]}} +function Yq(a,b,c){if(null!=b.Z&&(a=Fq(a,b.Z,b.type))){var d=b.Ra&a.Ba;if(!a.cd){if(d>>>0>=a.Zb)return!1}else if(d>>>0f?null!=h?(g=ar(a,b,void 0),f=null):(f=ar(a,b,void 0),null==f&&(g=null)):(h=ar(a,b.substring(0,f),void 0),g=ar(a,b.substring(f+1),void 0),f=null)}null!=g&&(e=jq(a,g,h,f,c),d||Yq(a,e,!0)||(a.O("invalid offset: "+Sq(e)),e=null));return e}function br(a,b,c){c&&(c=c.match(/(['"])(.*?)\1/))&&(b.Gk=cr(a,b.mk=c[2]))}function Uq(a,b,c){c=c||1;null!=b.Ea&&(b.Ea+=c);null!=b.Z&&(b.Ra+=c,Yq(a,b)||(b.Ra=0,b.Ea=null))}function Iq(a,b,c){return null!=b?r(b,4)+":"+r(a,a&-65536||c?8:4):r(a)} +function Sq(a){var b;switch(a.type){case 1:case 3:b="&";break;case 2:b="#";break;case 4:b="%";break;case 5:b="%%";break;default:b=a.Z?"":"%"}return 4<=a.type||null==a.Z?b+r(a.Ea):b+Iq(a.Ra,a.Z,a.oc)}function Jq(a,b,c){var d="";for(c=c||256;d.length>>a.F.La;g=1}a.O("blockid "+(d?"linear ":"physical")+" blockaddr used size type");a.O("-------- --------- ---------- ------ ------ ----");c=-1;for(var h=0;g--;)(d=b[f])&&5==d.type&&(d=Ic(a.F,e,!1,!0)),d.type==c?h++||a.O("..."):(c=d.type,h=Zb[c],6==c&&(d=d.Dd,h+=" -> "+Zb[d.type]),d&&a.O(r(d.id)+" %"+r(f<c&&(c=va(vq,a.substr(b,2))));return c} +function fr(a,b){var c=0,d=gr(a,b);if(void 0!==d)switch(b){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:c=2;break;case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 22:case 16:case 17:case 18:case 19:case 20:case 21:c=4;break;case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 56:c=8;break;case 23:c=a.Ja}return c?r(d,c):"??"} +function gr(a,b){var c;if(0<=b){var d=a.F;switch(b){case 0:c=d.G&255;break;case 1:c=d.I&255;break;case 2:c=d.M&255;break;case 3:c=d.H&255;break;case 4:c=d.G>>8&255;break;case 5:c=d.I>>8&255;break;case 6:c=d.M>>8&255;break;case 7:c=d.H>>8&255;break;case 8:c=d.G&65535;break;case 9:c=d.I&65535;break;case 10:c=d.M&65535;break;case 11:c=d.H&65535;break;case 12:c=I(d)&65535;break;case 13:c=d.P&65535;break;case 14:c=d.K&65535;break;case 15:c=d.J&65535;break;case 22:c=K(d)&65535;break;case 23:c=zd(d);break; +case 16:c=d.Xa.Z;break;case 17:c=d.va.Z;break;case 18:c=d.ta.Z;break;case 19:c=d.vb.Z;break;default:if(80286==a.F.ja)32==b&&(c=d.Za);else if(80386<=a.F.ja)switch(b){case 24:c=d.G;break;case 25:c=d.I;break;case 26:c=d.M;break;case 27:c=d.H;break;case 28:c=I(d);break;case 29:c=d.P;break;case 30:c=d.K;break;case 31:c=d.J;break;case 32:c=d.Za;break;case 33:c=d.li;break;case 34:c=d.ue;break;case 35:c=d.Qd;break;case 20:c=d.Nb.Z;break;case 21:c=d.Ob.Z;break;case 56:c=K(d)}}}return c} +function hr(a,b){b=$q(a,b);for(var c=0,d,e;0<=(c=b.indexOf("@",c));)e=er(b,c+1),0<=e&&(b=b.substr(0,c)+fr(a,e)+b.substr(c+1+vq[e].length)),c++;for(c=0;0<=(c=b.indexOf("#",c));)e=b.substr(c+1,2),d=ca(e,16),null!=d&&32<=d&&128>d?(d=e+" '"+String.fromCharCode(d)+"'",b=b.replace("#"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("$",c));)e=b.substr(c+1,9),(d=Zq(a,e))?(d=e+' "'+Jq(a,d)+'"',b=b.replace("$"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("^",c));)e=b.substr(c+1,9),(d=Zq(a,e))?(Uq(a,d),d=e+ +' "'+Jq(a,d,11)+'"',b=b.replace("^"+e,d),c+=d.length):c++;return b}m=iq.prototype;m.message=function(a,b){b&&(a+=" at "+Sq(jq(this,K(this.F),this.F.va.Z))+" (%"+r(this.F.Ha)+")");if(!this.Pa||a!=this.Pa)if(this.Pa=a,this.wc&-2147483648&&(this.Wb(),a+=" (cpu halted)"),this.O(a),this.F){var c=this.F;c.Y.nf=0;c.fb-=c.A;c.A=0;Wc(c)}}; +function nk(a,b,c,d){var e,f;if(!d&&(d=A(a,1)&&0>pq.indexOf(b),!d)){var g=oq[b];g&&(d=A(a,g)?!0:524288==g&&A(a,g=1048576))}d&&(e=a.F.G>>8&255,f=a.F.M&255,33==b&&11==e||524288==g&&128<=f||1048576==g&&128>f)&&(d=!1);d&&((g=(g=Ab[b])&&g[e]||"")&&(g=" "+hr(a,g)),a.message("INT "+t(b)+": AH="+t(e)+" at "+Iq(c-2-a.F.va.Aa,a.F.va.Z)+g));return d} +function qb(a,b,c,d,e,f,g,h){h|=256;if(null==e||(a.wc&h)==h)h=null,null!=e&&(h=a.F.va.Z,e-=a.F.va.Aa),a.message(b.zd+"."+(null!=d?"outPort":"inPort")+"("+u(c)+","+(f?f:"unknown")+(null!=d?","+t(d):"")+")"+(null!=g?": "+t(g):"")+(null!=e?" at "+Iq(e,h):""))}m.jh=function(){this.O("Type ? for help with PCx86 Debugger commands");this.qd();if(this.gb){var a=this.gb;this.gb=null;nq(this,a)}}; +function lq(a,b){var c;if(Wf(a)){if(!a.ia||!a.ia.length){a.ia=Array(1E3);for(c=0;c>>f.La].Td(e&f.Fa,a==this.fa);g&&Yb(f)}}d&&(a.push(b),c?(null!=b.Ea&&(b.Z=null),b.Yd=!0):(nr(this,a,a.length-1,"set"),lq(this)));return d}; +function Rq(a,b,c,d,e){for(var f=!1,g=or(a,a.dc(c)),h=1;h>3&7,z=(3>(g>>6&3)?0:48)+p;(217==f||219==f)&&52<=z&&(z=p<<4|g&7);(p=Bq[f])&&(q=p[z]);q&&(n=sq,k=q,l=k[0])}l>=n.length&&(g=a.Qa(b,1),k=Cq[l-n.length][g>>3&7],l=k[0]);n=n[l];p=k.length-1;q="";b.Rb&&(18==l? +n="CWDE":28==l?n="CDQ":104<=l&&107>=l&&(n+="D"));if(164<=f&&167>=f||170<=f&&175>=f)p=0,b.Rb&&"W"==n.slice(-1)&&(n=n.slice(0,-1)+"D");for(var f=null,z=!0,F=1;F<=p;F++){var v,E;v="";E=k[F];if(void 0!==E){null==f&&(f=E>>14);80==l&&(2==f?q="[%800]":3==f&&(q="ES:["+(b.oc?"E":"")+"DI]"));var H=E&15;if(0!=H)if(8==H)z=!1;else{var L=E&240;if(128<=L)if(0>g&&(g=a.Qa(b,1)),160>L){v=a;var W=p,H=b,P="",bb=g>>6,ia=g&7;if(3>bb){var ja=void 0,L=0==n.indexOf("FI");if(!bb&&(!H.oc&&6==ia||H.oc&&5==ia))bb=2;else{if(H.oc)if(4!= +ia)ia+=8;else{var P=v,ja=bb,Ha=H,Xa=P.Qa(Ha,1),Ba=Xa>>6,Wb=Xa>>3&7,Xa=Xa&7,wa="";if(ja||5!=Xa)wa=wq[Xa+8];4!=Wb&&(wa&&(wa+="+"),wa+=wq[Wb+8],Ba&&(wa+="*"+(1<>24,P+="-"+r(-ja,2)):P+="+"+r(ja,2)):2==bb&&(P&&(P+="+"),H.oc?(ja=v.oa(H,4),P+=r(ja)):(ja=v.na(H,2),P+=r(ja,4)));P="["+P+"]";if(1==W){v="";E&=15;4==E&&(E=H.Rb?5:3);switch(E){case 7:v="FAR";break;case 1:v="BYTE";break;case 3:if(L){v="INT16"; +break}v="WORD";break;case 5:v="DWORD";break;case 11:if(L){v="INT32";break}case 11:v="REAL32";break;case 12:if(L){v="INT64";break}case 12:v="REAL64";break;case 13:v="REAL80";break;case 14:v="BCD80"}v&&(P=v+" "+P)}}else P=sr(v,ia,E,H);v=P}else v=160==L?sr(a,g&7,E,b):sr(a,g>>3&7,E,b);else if(16==L)v="1";else if(0==L){v=a;H=E;L=b;E=" ";switch(H&15){case 1:H&12288&&(E=r(v.Qa(L,1),2));break;case 2:E=r(v.Qa(L,1)<<24>>24,L.Rb?8:4);break;case 4:if(L.Rb){E=r(v.oa(L,4));break}case 3:E=r(v.na(L,2),4);break;case 7:L= +jq(v,v.tb(L,!0),v.na(L,2),null,L.type,L.Rb,L.oc);E=Sq(L);v=tr(v,L);v[0]&&(E+=" ("+v[0]+")");break;default:E="imm("+u(H)+")"}v=E}else 32==L?(b.oc?(v=8,E=a.oa(b,4)):(v=4,E=a.na(b,2)),v="["+r(E,v)+"]"):48==L?(v=1==H?a.Qa(b,1)<<24>>24:a.tb(b,!0),E=b.Ra+v&(b.Rb?-1:65535),v=r(E,b.Rb?8:4),E=tr(a,jq(a,E,b.Z)),E[0]&&(v+=" ("+E[0]+")")):96==L?v=9==H?"ST":10==H?"ST("+(g&7)+")":sr(a,(E&3840)>>8,E,b):112==L?v=sr(a,(E&3840)>>8,192,b):64==L?v="DS:[SI]":80==L&&(v="ES:[DI]");if(!v||!v.length){q="INVALID";break}0< +q.length&&(q+=",");q+=v||"???"}}}g="";k=Sq(e)+" ";if(-1!==e.Ea&&-1!==b.Ea){do if(g+=r(a.Qa(e,1),2),null==e.Ea)break;while(e.Ea!=b.Ea)}k+=ma(g,e.oc?24:16);k+=ma(n,8);q&&(k+=" "+q);a.F.jaa.F.ja)return"??";b+=16}else if(208==e)b+=32;else if(224==e)b+=40;else if(240==e)b+=48;else if(a=c&15,3<=a&&(8>b&&(b+=8),5==a||4==a&&d.Rb))b+=16;return vq[b]} +function vr(a,b){var c;switch(b){case "V":c=xf(a.F);break;case "D":c=a.F.ca&1024;break;case "I":c=a.F.ca&512;break;case "T":c=a.F.ca&256;break;case "S":c=wf(a.F);break;case "Z":c=vf(a.F);break;case "A":c=uf(a.F);break;case "P":c=tf(a.F);break;case "C":c=sf(a.F);break;default:c=0}return b+(c?"1":"0")+" "}function Hq(a){return r(a,a&-65536?8:4)}function wr(a,b){8<=b&&15>=b&&4a.F.ja&&(d="\n"+d,c+=e,e="");c+="\n"+xr(a,a.F.va,b)+" ";80386<=a.F.ja&&(e+="\n",c+=xr(a,a.F.Nb,b)+" "+xr(a,a.F.Ob,b)+"\n");c+=yr(a,"LD",a.F.Bc.Z,a.F.Bc.Aa,a.F.Bc.Aa+a.F.Bc.Ta)+" "+yr(a,"GD",null,a.F.Ec,a.F.Bd)+" "+yr(a,"ID", +null,a.F.Mc,a.F.Ud)+" ";c=c+(d+" "+e)+wr(a,32);80386<=a.F.ja&&(c+=wr(a,34)+wr(a,35))}else 80386<=a.F.ja&&(c+=xr(a,a.F.Nb,b)+" "+xr(a,a.F.Ob,b)+" ");return c+=wr(a,23)+vr(a,"V")+vr(a,"D")+vr(a,"I")+vr(a,"T")+vr(a,"S")+vr(a,"Z")+vr(a,"A")+vr(a,"P")+vr(a,"C")}var Ar={"||":0,"&&":1,"|":2,"^":3,"&":4,"!=":5,"==":5,">=":6,">":6,"<=":6,"<":6,">>>":7,">>":7,"<<":7,"-":8,"+":8,"%":9,"/":9,"*":9}; +function Br(a,b,c){for(c=c||-1;c--&&b.length;){var d=b.pop();if(2>a.length)return!1;var e=a.pop(),f=a.pop();switch(d){case "*":d=f*e;break;case "/":if(!e)return!1;d=f/e;break;case "%":if(!e)return!1;d=f%e;break;case "+":d=f+e;break;case "-":d=f-e;break;case "<<":d=f<>":d=f>>e;break;case ">>>":d=f>>>e;break;case "<":d=f":d=f>e?1:0;break;case ">=":d=f>=e?1:0;break;case "==":d=f==e?1:0;break;case "!=":d=f!=e?1:0;break;case "&":d=f&e;break; +case "^":d=f^e;break;case "|":d=f|e;break;case "&&":d=f&&e?1:0;break;case "||":d=f||e?1:0;break;default:return!1}a.push(d|0)}return!0} +function ar(a,b,c){var d;if(b){b=$q(a,b);for(var e=0,f=!1,g=b,h=[],k=[],l=b.split(/(\|\||&&|\||^|&|!=|==|>=|>>>|>>|>|<=|<<|<|-|\+|%|\/|\*)/);eb[0]?1:a[0]>>0,n],v=pa(z,p,a.sb);0>v&&z.splice(-(v+1),0,p)}F&&(q.a=F.replace(/''/g,'"'))}a.B.push({hg:b,pm:c,Z:d,Ra:e,Ea:f,hm:g,Sd:h,ti:l})} +function Qq(a,b,c){for(var d=0;d>>0,f=a.dc(b)>>>0,g=0;g>>0,n=h.Ea;null!=n&&(n>>>=0);var q=h.hm;48==k&&(k=40);if(k==b.Z&&e>=l&&e=n&&fc?(a.O("out of data at address "+Sq(b)),n=!0):(a.qc(b,c,1,!0),l++)})})(a,g);Wc(a.F, +!0);a.O(l+" bytes read at "+c)}else a.O("sector "+e+" request out of range");else a.O("drive "+d+" not loaded");else a.O("invalid drive: "+d)}else a.O("disk controller not present")}}else a.O("load commands:"),a.O("\tl [address] [drive #] [sector #] [# sectors]")} +function jr(a,b){var c;if(b&&"?"==b[1])a.O("register commands:"),a.O("\tr\tdump registers"),a.Tb&&a.O("\trfp\tdump floating-point registers"),a.O("\trp\tdump all registers"),a.O("\trx [#]\tset flag or register x to [#]");else{var d;null==c&&(c=!0);if(null!=b&&1g;g++){var h=c,e=null;if(g=a.Ja&&(k=null), +k){case "AL":a.F.G=a.F.G&-256|h&255;break;case "AH":a.F.G=a.F.G&-65281|h<<8&255;break;case "AX":a.F.G=a.F.G&-65536|h&65535;break;case "BL":a.F.H=a.F.H&-256|h&255;break;case "BH":a.F.H=a.F.H&-65281|h<<8&255;break;case "BX":a.F.H=a.F.H&-65536|h&65535;break;case "CL":a.F.I=a.F.I&-256|h&255;break;case "CH":a.F.I=a.F.I&-65281|h<<8&255;break;case "CX":a.F.I=a.F.I&-65536|h&65535;break;case "DL":a.F.M=a.F.M&-256|h&255;break;case "DH":a.F.M=a.F.M&-65281|h<<8&255;break;case "DX":a.F.M=a.F.M&-65536|h&65535; +break;case "SP":G(a.F,I(a.F)&-65536|h&65535);break;case "BP":a.F.P=a.F.P&-65536|h&65535;break;case "SI":a.F.K=a.F.K&-65536|h&65535;break;case "DI":a.F.J=a.F.J&-65536|h&65535;break;case "DS":xd(a.F,h);break;case "ES":yd(a.F,h);break;case "SS":md(a.F,h);break;case "CS":nf(a.F,h);a.aa=jq(a,K(a.F),a.F.va.Z);break;case "IP":case "EIP":O(a.F,h);a.aa=jq(a,K(a.F),a.F.va.Z);break;case "PC":case "PS":Ad(a.F,h);break;case "C":h?zf(a.F):Af(a.F);break;case "P":h?(e=a.F,e.resultType&=-3,e.ca|=4):(e=a.F,e.resultType&= +-3,e.ca&=-5);break;case "A":h?Hf(a.F):Ff(a.F);break;case "Z":h?If(a.F):Gf(a.F);break;case "S":h?(e=a.F,e.resultType&=-17,e.ca|=128):(e=a.F,e.resultType&=-17,e.ca&=-129);break;case "I":h?(e=a.F,e.ca|=512):(e=a.F,e.ca&=-513);break;case "D":h?(e=a.F,e.ca|=1024):(e=a.F,e.ca&=-1025);break;case "V":h?Bf(a.F):Cf(a.F);break;default:var l=!0;if(80286<=a.F.ja)switch(l=!1,k){case "MS":Jf(a.F,h);break;case "TR":-1===a.F.Sa.load(h)&&(g=!1);break;default:if(l=!0,80386<=a.F.ja)switch(l=!1,k){case "EAX":a.F.G=h; +break;case "EBX":a.F.H=h;break;case "ECX":a.F.I=h;break;case "EDX":a.F.M=h;break;case "ESP":G(a.F,h);break;case "EBP":a.F.P=h;break;case "ESI":a.F.K=h;break;case "EDI":a.F.J=h;break;case "FS":a.F.Nb.load(h);break;case "GS":a.F.Ob.load(h);break;case "CR0":a.F.Za=h;sj.call(a.F,h);break;case "CR2":a.F.ue=h;break;case "CR3":a.F.Qd=h;Cd.call(a.F,h);break;default:l=!0}}if(l){a.O("unknown register: "+e);return}}if(!g){a.O("invalid value: "+f);return}Wc(a.F);a.O("updated registers:")}}a.O(zr(a,d));c&&(a.aa= +jq(a,K(a.F),a.F.va.Z),kr(a,Sq(a.aa)))}}function Kr(a,b){b=na(b);var c=b.match(/^(['"])(.*?)\1$/);c?a.O(hr(a,c[2])):ar(a,b,!0)}function Lr(a,b,c){for(var d=null,e=b.Ra,f=e,g=1;6>=g&&e;g++){if(2h[0].indexOf("+"))){var l=h[0]+":";h[2]&&(l+=" "+h[2]);a.O(l)}h[3]&&(g=h[3],f=null);f=rr(a,b,g,f);b.Xd||d||d++;a.O(f);a.aa=b;e-=b.Ea-k;c++}}} +function cr(a,b,c,d){if(c)if(b){0>a.U&&a.L.length&&(a.U=0);if(0>a.U||b!=a.L[a.U])a.L.splice(0,0,b),a.U=0;a.U--}else b=a.L[a.U+1];a=[];if(b){b=b.toLowerCase().replace(/""/g,"'");c=0;var e=null;d=d||";";for(var f=0;f<=b.length;f++){var g=b.charAt(f);if('"'==g||"'"==g)e?g==e&&(e=null):e=g;else if(g==d&&!e||!g)a.push(na(b.substring(c,f))),c=f+1}}return a} +function qr(a,b,c){var d=!0;try{if(!b.length||"end"==b)a.Da&&(a.O("ended assemble at "+Sq(a.ua)),a.aa=a.ua,a.Da=!1),b="";else if(!c){var e=">> ";a.F.Za&1&&(e=a.F.ca&131072?"-- ":"## ");a.O(e+b)}var f=b.charAt(0);if('"'==f||"'"==f)return!0;a.Pa=null;if(vb(a)&&0n||"z">>20;Da.wi=a.F.Qd+Da.ek;Da.yb=ce.sa[(Da.wi&ce.Hb)>>>ce.La];Da.Xi=Da.yb.Od(Da.ek);Da.fk=(Ue&4190208)>>>10;Da.xi=(Da.Xi&-4096)+Da.fk;Da.zb=ce.sa[(Da.xi&ce.Hb)>>>ce.La];Da.Yi=Da.zb.Od(Da.fk);Da.Ik=(Da.Yi&-4096)+(Ue&4095)}if(be=Da){a.O("linear PDE addr PDE PTE addr PTE physical");a.O("--------- ---------- -------- ---------- -------- ----------");var pd="%"+r(Ue),pd=pd+(" %%"+dr(be.wi,be.Xi)),pd=pd+(" %%"+dr(be.xi,be.Yi,!0)), +pd=pd+(" %%"+r(be.Ik));a.O(pd)}else a.O("unsupported operation")}}else a.O("missing address")}else{if("d"==ia){if("disk"==ja){P[0]="l";P[1]="json";Jr(a,P);break a}for(bb in Bb)if(P[1]==bb){var Dn=a.$a[bb];Dn?(P.shift(),P.shift(),Dn(P)):a.O("no dump registered for "+ja);break a}ja||(ia=a.Cc||"db")}else a.Cc=ia;if("dh"==ia){var En=ja,Fn=Ha,Gn="",Hn=0,tb=a.Fa,tc=a.ia;if(tc.length){var Eb=+En||a.Ub,de=+Fn||10;isNaN(Eb)?Eb=de:Gn="more ";Eb>tc.length&&(a.O("note: only "+tc.length+" available"),Eb=tc.length); +tb-=Eb;0>tb&&(null==tc[tc.length-1].Z?(Eb=tb+Eb,tb=0):tb+=tc.length);var li=[];"call"==Fn&&(de=1E5,li=["CALL"]);for(void 0!==En&&a.O(Eb+" instructions earlier:");0=tc.length&&(tb=0);a.Ub=Eb;Hn++;de--}}Hn||(a.O("no "+Gn+"history available"),a.Ub=void 0)}else if("di"==ia){P.shift(); +var mi=P[0];if(mi){var We=Eq(a,mi);if(void 0===We||0>We||255>> +0,65536>4||1;is--&&0ug?String.fromCharCode(ug):".";sg--}rd&&(rd+="\n");rd+=ja+" "+Ye+(0==Xe?" "+pi:"")}rd&&a.O(rd);a.Db=ee}}}}}break;case "e":if("else"==g[0])break;var vg=1,Mn=255,Nn=a.Qa,On=a.qc;"ew"==g[0]&&(vg=2,Mn=65535,Nn=a.na, +On=a.jb);var Pn=vg<<1,Qn=g[1];if(null==Qn)a.O("edit memory commands:"),a.O("\teb [a] [...] edit bytes at address a"),a.O("\tew [a] [...] edit words at address a");else{var wg=Zq(a,Qn);if(wg)for(var xg=2;xgvi;){for(var uc=null,ns=256;Uc.Ra>>>0>>0;){af.Ra=a.tb(Uc,!0);if(null==Uc.Ea||!ns--)break;af.Z=Sn;if(uc=Lr(a,af))break;af.Z=a.tb(Uc);if(uc=Lr(a,af,!0)){Sn=a.tb(Uc,!0);0\nLicense: GPL version 3 or later ");for(b=0;bQr){if(d.load(this.aa)){this.X=new lf(this,"1.24.2","failsafe");this.X.load()&&(Xr(this,d),a=2,Yr(this.X));N(this.X,"timestamp",ra());Zr(this.X);var e=this.A&&!this.V;if(1==a||Aa("Click OK to restore the previous PCx86 machine state, or CANCEL to reset the machine.")){if(c=Vr(d)){var f=Wr(d,"code"),g=Wr(d,"data");f&&("ok"==f?d.load(g):("error"== +f&&"no machine state"!=g?(this.Na("Error: "+g),"unable to verify user"==g&&(Ga("user",""),this.B=null)):this.O(f+": "+g),Yr(d),d.load()?(c=Vr(d),e=!0):c=!1))}e&&Ur(this,c?d:null)}else 2==a&&d.clear()}else Ur(this);delete this.aa;delete this.ea}e=ib(this.id);for(f=0;fa[1];a=a[2];this.wa=!0;this.la.cc=!0;var d=this.qa.power;d&&(d.textContent="Shutdown");this.F&&($r(this,this.F,b,c,a),Xc(this.F));this.ka&&(Xr(this,b),b.clear());!c&&this.X&&(this.X.clear(),delete this.X);this.N=0}; +function Xr(a,b){if(Aa("There may be a problem with your PCx86 machine.\n\nTo help us diagnose it, click OK to send this PCx86 machine state to http://www.pcjs.org.")){var c=a.le(),d=b.toString(),e={app:"PCx86",ver:"1.24.2"};e.url=a.ua;e.user=c;e.type="bug";e.data=d;xa("http://www.pcjs.org/api/v1/report",e,!0)}} +function Nr(a,b,c){var d,e="none";if(a.N)return null;a.N--;var f=new lf(a,"1.24.2"),g=new lf(a,"1.24.2","validate"),h=ra();N(g,"timestamp",h);N(f,"timestamp",h);N(f,"version","1.24.2");N(f,"url",window?window.location.href:null);N(f,"browser",za());a.F&&a.F.hc&&(c&&a.F.Wb(),d=a.F.hc(b,c),"object"===typeof d&&N(f,a.F.id,d),c&&(a.F.la.cc=!1,!1===d&&(e=null)));for(var h=ib(a.id),k=0;k>>d.La;f=f+g-1>>>d.La;e.bh=0;for(e.Vd=0;h<=f;)g=d.sa[h],e.bh+=g.size,g.size&&(e.Tg.push(ta(Kb,h,0,0,g.type)),e.Vd++),h++;c.A=e;c.ya=c.A.Vd*c.ga.Sb/691200;d=0;c.A.Ci=0;c.A.Bf||(c.A.Bf=[]);var e=-1,h=0,k=-1;for(f=0;f>1),k=g.y+(g.A>>1),l=g.A,g.ad>1,h.U+=(h.W>>1)-2,Mb(h,e),h.ra&&(h.N.restore(),h.ra=!1)}}else Mb(c,"This space intentionally left blank");c.context.drawImage(c.aa,0,0,c.aa.width,c.aa.height,c.sb,c.Jb,c.$a,c.fb);c.Ja=!1}} +Sa(function(){for(var a=pb(document,"pcx86-machine"),b=0;bh.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(h=window.location.pathname+h);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(h?' url="'+h+'"':""))}e||(a=a.replace(/().*?(<\/xsl:variable>)/,"$1pcx86$2")); +h=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(h=new window.ActiveXObject("Microsoft.XMLDOM"),h.async=!1,h.loadXML(a)):h=(new window.DOMParser).parseFromString(a,"text/xml")}catch(q){h=null,a=q.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");xa(e,null,!0,function(f,g,h){if(h||!g)c(a,"unable to resolve XML reference: "+d[0]+" ("+h+")");else{if(f=d[3])if(h=g.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var k=h[0],l,n=/( [a-z]+=)(['"])(.*?)\2/g;l=n.exec(f);)k=0>k.indexOf(l[1])?k.replace(">",l[0]+">"):k.replace(new RegExp(l[1]+"(['\"])(.*?)\\1"),l[0]);h[0]!=k&&(g=g.replace(h[0],k))}else{c(a,"missing <"+d[1]+"> in "+e);return}g=g.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],g);rs(a,b,c)}})}else c(a,null)} +function ss(a,b,c,d){function e(a){if(void 0===h){var b=g&&pb(g,"machine-warning");h=b&&b[0]||g}h&&(h.innerHTML=la(a))}function f(a){e("Error: "+a);k&&(--ds||Ua(!0));k=!1}var g,h,k=!0;ds++;gb[a]={};try{if(g=document.getElementById(a)){var l;if("object"==typeof resources&&(l=resources.css)){var n=document.head||document.getElementsByTagName("head")[0],q=document.createElement("style");q.type="text/css";q.styleSheet?q.styleSheet.cssText=l:q.appendChild(document.createTextNode(l));n.appendChild(q)}c|| +(c="/versions/pcx86/1.24.2/components.xsl");l=function(d,h){h?es(c,null,null,!1,e,function(d,k){if(k)if(hb(a,c,d),e("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var l=h.transformNode(k);l?(g.outerHTML=l,--ds||Ua(!0)):f("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(l=new XSLTProcessor,l.importStylesheet(k),(l=l.transformToFragment(h,document))?g.parentNode?(g.parentNode.replaceChild(l,g),--ds||Ua(!0)):f("invalid machine element: "+ +a):f("transformToFragment failed")):f("unable to transform XML: unsupported browser");else f(d)}):f(d)};"<"!=b.charAt(0)?es(b,a,d,!0,e,l):fs(b,null,a,d,!1,e,l)}else f("missing machine element: "+a)}catch(p){f(p.message)}return k}function ts(a,b,c,d){Ua(!1);return ss(a,b,c,d)}window.embedPC=ts;window.embedPCx86=ts;window.enableEvents=Ua;window.sendEvent=Va; +function us(a,b,c,d){if(!c&&b){d.push(b);a=gb[d[0]];b=null;for(var e in a)if(ha(e,"components.xsl")){b=e.replace(".xsl",".css");break}b?xa(b,null,!0,function(a,b){vs(b,d)}):vs(null,d)}else w("Error ("+c+") requesting "+a)} +function vs(a,b){var c,d,e,f=b[0],g=b[1];c=b[4];c=c.match(/^(\s*\(function\(\)\{)([\s\S]*)(}\)\(\);\s*)$/);var h=gb[f],k={},l;for(l in h){var n=h[l],q=ga(l);if("xml"==q){for(q=/[ \t]*]*path=(['"])(.*?)\1.*?<\/disk>\n?/g;d=q.exec(h[l]);){var p=d[2];p&&(h[p]||(n=n.replace(d[0],"")))}d=l=fa(l)}else"xsl"==q&&(e=l=fa(l));k[l]=n}a&&(k[l="css"]=a);b[2]&&(k[l="parms"]=b[2]);b[3]&&(k[l="state"]=b[3]);d&&e?(l=JSON.stringify(k),g+=".js",c=c[1]+"var resources="+l+";"+c[2]+c[3],c=c.replace(/\u00A9/g, +"©"),c=Ja(c,"javascript",!1,g),c=c+(', copy it to your web server as "'+g+'", and then add the following to your web page:\n\n')+('
    \n'),c+="...\n",c+=' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + float: + + + + js + + + +
    + + + + + + + + + + js + + + "" + + + + + +
    +
    + + + + + + + + + + + + + + + , + + + + + + + + + + + + + .machine + . + . + + + + + + + + + + + + + + + + + + + + ,comment:'' + + + + + + border:1px solid black;border-radius:15px; + border:; + + + + + + left:; + + + + + + top:; + + + + + + + + width:; + width:;max-width:; + width:auto;max-width:; + + + + + + + + height:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto;clear:both; + position:; + position:relative; + + + + + overflow:auto;width:100%; + background-color:; + + + + - -component + +
    + + + + + + +
    + + + + + + + + --object -screen + + +
    +
    + +
    + +
    +
    + + + + +
    + + +
    [XML]
    + +
    + + +
    +
    +
    +
    + + + + + text-align:center; + + + +

    +
    + + +
    +
    + + + + + + +
    +
    + + + + type:'' + + + binding:'' + + + value:'' + + + + border:1px solid black; + border:; + + + + + + width:; + + + + + + height:; + + + + + + left:; + + + + + + top:; + + + + + + padding:; + + padding-top:; + padding-right:; + padding-bottom:; + padding-left:; + + + + + + float:left; + float:right; + margin:0 auto; + position:; + position:relative; + float:left; + + + + + + + + + + + + + + + + + + +
    + + + font-size:; + + + + + -label + + + + width:; + width:; + + + + + + + + text-align:right; + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    + + + + +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + ; + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + desc:'' + + ,href:'' + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8088 + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + 1 + + + + + + + null + + + + + + + -1 + + + + + + + -1 + + + + + + + -1 + + + + + + ,model:'',stepping:'',fpu:,cycles:,multiplier:,autoStart:,csStart:,csInterval:,csStop: + + + + + + + + + + + + + + + 8087 + + + + + + + + + + + + ,model:'',stepping:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + true + + + + + + false + + + + + + {} + + + + + + + + + + + + + + + + + chipset + ,model:'',scaleTimers:,sw1:'',sw2:'',sound:,floppies:,monitor:'',rtcDate:'' + + + + + + + + + + + + + + + + + + + + keyboard + ,model:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + parallel + ,adapter:,binding:'' + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 0 + + + + + + + 0 + + + + + serial + ,adapter:,binding:'',tabSize:,charBOL: + + + + + + + + + + + + + + + + + + + + mouse + ,serial:'' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fdc + ,autoMount:'',sortBy:'' + + + + + + + + + + + + + + + + + + + + + xt + + + + + hdc + ,drives:'',type:'' + + + + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + null + + + + + + + + + + + + + + + + + + false + + + + + rom + ,addr:,size:,alias:,file:'',notify:'',writable: + + + + + + + + + + + + + + + 0 + + + + + + 0 + + + + + + true + + + + + ram + ,addr:,size:,test: + + + + + + + + + + + + + + + + + + + + + null + + + + + + + 256 + + + + + + + 224 + + + + + + + black + + + + + + 0 + + + + + + 0 + + + + + + false + + + + + + 1bpp + + + + + + 0 + + + + + + 0 + + + + + + 1 + + + + + + 0 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + false + + + + + + 1 + + + + + + 1 + + + + + + + 80 + + + + + + + 25 + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + 0 + + + + + + null + + + + + + 0 + + + + + + 60 + + + + + video + ,model:'',mode:,screenWidth:,screenHeight:,screenColor:'',screenRotate:,bufferAddr:,bufferRAM:,bufferFormat:'',bufferCols:,bufferRows:,bufferBits:,bufferLeft:,bufferRotate:,memory:,switches:'',scale:,cellWidth:,cellHeight:,charCols:,charRows:,fontROM:'',fontColor:'',touchScreen:'',autoLock:,aspectRatio:,smoothing:,interruptRate:,refreshRate: + + + + + + + + + + + + + + + + + + + + + + + + + + debugger + ,commands:'',messages:'' + + + + + + + + + + + + + + panel + + + + + + + + + + + + + + + + + + + + + true + + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + computer + ,autoPower:,busWidth:,resume:,state:'' + + + + + + + + diff --git a/versions/pdp11/1.24.2/document.css b/versions/pdp11/1.24.2/document.css new file mode 100644 index 000000000..7072b406e --- /dev/null +++ b/versions/pdp11/1.24.2/document.css @@ -0,0 +1,162 @@ +@CHARSET "UTF-8"; + +.page { + margin: 2% 2%; + padding: 2% 2%; + min-width: 30em; + overflow: auto; + font-size: large; + font-family: Helvetica, Arial, sans-serif; + background: #303030; + color: #ccc; + +} +.page-header { +} +.page-header-title { + text-align: center; + +} +.page a { + color: #7fc07f; + text-decoration: none; +} +a.footlink, a.paralink { + text-decoration: none; +} +a.footlink:link, a.paralink:link { + color: blue; +} +a.footlink:visited, a.paralink:visited { + color: blue; +} +.galleryitem { + float: left; + width: 200px; +} +.item { + float: left; + width: 2em; + text-indent: 1em; +} +.list { + margin-left: 3em; + text-indent: 0; + text-align: justify; +} +ul { + list-style: none; +} +div.pnumber { + float: left; + width: 2em; + text-indent: 1em; +} +div.pitem { + margin-left: 10em; +} +p.indent, .justified p { + text-indent: 2em; + text-align: justify; + line-height: 1.5em; +} +p.noindent { + text-indent: 0; + text-align: justify; +} +p.center, .center { + text-align: center; +} +li.para { + margin-top: 1em; + margin-bottom: 1em; +} +.left { + text-align: left; +} +.right { + text-align: right; +} +blockquote.tag { + font-size: small; + font-family: Monaco, Fixed, monospace; + margin-top: 0; + margin-bottom: 0; +} +.blockquote { + padding-left: 1em; + text-indent: 0; + text-align: justify; +} +.italics { + font-style: italic; +} +.medium { + font-size: medium; +} +.small { + font-size: x-small; +} +.smallcaps { + font-variant: small-caps; +} +.strike { + text-decoration: line-through; +} +.summation, .bracelist { + display: inline-block; + position: relative; + vertical-align: middle; + text-align: center; + margin-bottom: 0.5ex; + text-indent: 0; +} +.bracelist-symbol { + font-size: 3em; + vertical-align: -40%; +} +.summation .summation-lower, .summation .summation-upper, .bracelist-item { + display: block; + font-size: 75%; + text-align: center; +} +.summation .summation-upper { + margin-bottom: 0; + margin-left: 0.8ex; + font-style: italic; +} +.summation .summation-lower{ + margin-bottom: -0.6ex; + font-style: italic; +} +.summation .summation-symbol { + font-size: 2em; +} +p sup { + vertical-align: baseline; + position: relative; + bottom: .5em; + font-size: small; +} +p sub { + vertical-align: baseline; + position: relative; + bottom: -.5em; + font-size: small; +} +.footnote { + font-size: medium; + text-indent: 1em; + text-align: justify; + margin-top: .5em; +} +.image-right { + float: right; + margin-left: 1em; + margin-top: 1em; + margin-bottom: 1em; +} +.image-caption { + font-size: small; + text-align: center; +} \ No newline at end of file diff --git a/versions/pdp11/1.24.2/document.xsl b/versions/pdp11/1.24.2/document.xsl new file mode 100644 index 000000000..a84d622c9 --- /dev/null +++ b/versions/pdp11/1.24.2/document.xsl @@ -0,0 +1,452 @@ + + + + + +]> + + + + + + + + + +

    +
    + + + + + + + +

    +
    + +

    +
    +
    +
    + + + + + + +
    +
    + + +
    + +   + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + +

    +
    + + +

    +
    + + +

    +
    + + +
    +
    + + +
    +
    + + + + + + + + + + + + + + +
    +
    + + +
    +
    + + +
  • +
    + + +
    image
    +
    + + +
    +
    + + + + +
    {.}
    +
    + +
    {.}
    +
    +
    +
    + + + + + + + + + + < + > + + + + × + + ÷ + σ + + + + + + + + + + + + { + + + + + + + + + + [] + + + + +
    + +
    +
    + + + , and + + + + + MDY + + + + + + + + + + + + + + + + + + + + January + February + March + April + May + June + July + August + September + October + November + December + + + , + + + + + +

    + +
    +
    + + +
    + {.}
    +
    +
    +
    + + + +

    Timeline

    +
    + +

    +
    +
    + +
    +
    + + + + + + + + + +

    +
    + +
    +
    +
    + + + +

    People

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + +

    +
      + +
    +
    + + + + + + + + + + +
  • + +
  • +
    + + + +

    +
    +

    + +

    +
    +
    + + + + false + + + + + + [Original] + + + + + + + + + + [] + + +
    by
    + + +
    + [Source: + + + + + + + ] +
    +
    +
    + + + +

    Resources

    +
    + +

    +
    +
    + +
    +
    + + +

    + +
    + + + +

    +
    +
      + +
    +
    + + +
  • +
    + + + +

    +
    +
    + +
    +
    + + + +

    +
    + +
    + + + +

    +
    +
      + +
    +
    + + + + + +
      + +
    +
    + + + + +
  • +
    + +
  • +
    + +
  • +
    +
    +
    + + +
  • +
    + + + + + + + + + + +
    + < ="" + + ></> + ></> + /> + +
    +
    + +
    diff --git a/versions/pdp11/1.24.2/machine.xsl b/versions/pdp11/1.24.2/machine.xsl new file mode 100644 index 000000000..d35e21ad9 --- /dev/null +++ b/versions/pdp11/1.24.2/machine.xsl @@ -0,0 +1,49 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    +
    + + + + js + , + +
    +
    + +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pdp11/1.24.2/manifest.xsl b/versions/pdp11/1.24.2/manifest.xsl new file mode 100644 index 000000000..4a6a7186e --- /dev/null +++ b/versions/pdp11/1.24.2/manifest.xsl @@ -0,0 +1,247 @@ + + + + +]> + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Document Manifest

    +
    +
      + + + + None + + + + + + + + + + + + + + + + +
    +
    +
    +

    + +
    +
    +
    + + +
    + + + + + + + + + + + <xsl:value-of select="$SITEHOST"/> + + + + +
    + +
    +

    Software Manifest

    +
    +
      + + + + None + + + + + Unknown + + + + + None + + + + + None + + + + + + + + + + + + + UpdatedReleased + + Unknown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +

    No default machine specified for '' in manifest.xml

    +
    + +
    +
    +
    + + + + -dbg + + + + + + +
    + + + + + Unknown + +
  • +
      + + + + + + + + +
    • + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
      • + + + + + + +
      • +
        +
      +
      +
    • +
      + + + + + + + + +
    +
  • +
    +
    + +
    diff --git a/versions/pdp11/1.24.2/outline.xsl b/versions/pdp11/1.24.2/outline.xsl new file mode 100644 index 000000000..86a1189ec --- /dev/null +++ b/versions/pdp11/1.24.2/outline.xsl @@ -0,0 +1,47 @@ + + + + +]> + + + + + + + + + + + + + + + + + + <xsl:value-of select="title"/><xsl:text> | </xsl:text><xsl:value-of select="$SITEHOST"/> + + + + + +
    +
    + +
    +
    + + + + -dbg + + + + + + +
    + +
    diff --git a/versions/pdp11/1.24.2/pdp11-dbg.js b/versions/pdp11/1.24.2/pdp11-dbg.js new file mode 100644 index 000000000..02d1de6db --- /dev/null +++ b/versions/pdp11/1.24.2/pdp11-dbg.js @@ -0,0 +1,143 @@ +(function(){var g;function ba(a,b){var c;if(a){b||(b=16);if("$"==a.charAt(0))b=16,a=a.substr(1);else if("0x"==a.substr(0,2))b=16,a=a.substr(2);else{var d=a.charAt(a.length-1).toLowerCase();"h"==d?(b=16,d=null):"."==d&&(b=10,d=null);null==d&&(a=a.substr(0,a.length-1))}var e,d=a,f=b;(f&&10!=f?16==f?null!==d.match(/^[0-9a-f]+$/i):2==f&&null!==d.match(/^[01]+$/i):null!==d.match(/^[0-9]+$/))&&!isNaN(e=parseInt(a,b))&&(c=e|0)}return c} +function n(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function ca(a){return"0x"+n(a,4)}function da(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("&");0":">",'"':""","'":"'"};function ma(a){return a.replace(/[&<>"']/g,function(a){return la[a]})}function na(a,b){return(a+" ").slice(0,b)}function oa(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")}function pa(a,b,c){var d=0,e=a.length,f=0;for(void 0===c&&(c=function(a,b){return a>b?1:a>1,h;h=c(b,a[k]);0a?"0":"")+a}var b=new Date;return b.getFullYear()+"-"+a(b.getMonth()+1)+"-"+a(b.getDate())+" "+a(b.getHours())+":"+a(b.getMinutes())+":"+a(b.getSeconds())}function xa(a,b){var c;if(Array.prototype.indexOf)return a.indexOf(b,c);c=c||0;0>c&&(c+=a.length);0>c&&(c=0);for(var d=a.length;cb?this.Ka=this.id:(this.nb=this.id.substr(0,b),this.Ka=this.id.substr(b+1));this[a]=c;this.j={Ca:!1,za:!1,eb:!1,U:!1,Ba:!1};this.Za=null;this.j.Ba=!1;this.G={};this.C=null;this.W=d||0;x.push(this)}var Pa=void 0,Qa={}; +if(window){Pa||(Pa=window.location.search.substr(1));for(var Ra,ab=/\+/g,bb=/([^&=]+)=?([^&]*)/g;Ra=bb.exec(Pa);)Qa[decodeURIComponent(Ra[1].replace(ab," "))]=decodeURIComponent(Ra[2].replace(ab," "))}function cb(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b} +function z(a,b){b||(b=v);a.prototype=cb(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var db=window.PCjs.Machines||(window.PCjs.Machines={}),x=window.PCjs.Components||(window.PCjs.Components=[])}else db={},x=[];function eb(a,b,c){db[a]&&b&&(db[a][b]=c)}function D(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b=this.w?10:20>=this.w?12:24>=this.w?14:15;this.ga=1<>2;this.A=this.ga-1;this.D=this.F/this.ga|0;this.B=this.D-1;a=new K;qb(a,this.C);this.I=Array(this.D);for(b=0;b>>a.P;0f&&(m=f);if(h&&h.size){if(h.type==d){if(e+f<=h.u)return h.Xa+=h.u-e,h.u=e,!0;if(e>=h.u+h.Xa){m=h.size-(e-l);m>f&&(m=f);h.Xa=e-h.u+m;e=l+a.ga;f-=m;k++;continue}}return Eb(1,e,f)}e=new K(e,m,a.ga,d);qb(e,a.C,h);a.I[k++]=e;e=l+a.ga;f-=m}return 0>=f?(a.status(Math.floor(c/1024)+"Kb "+Fb[d]+" at "+ca(b)),!0):Eb(2,b,c)}g.ca=function(a){return this.I[(a&this.i)>>>this.P].Fa(a&this.A,a)}; +function Gb(a,b){return a.I[(b&a.i)>>>a.P].Qa(b&a.A,b)}g.Ma=function(a){var b=a&this.A,c=(a&this.i)>>>this.P;return b!=this.A?this.I[c].vb(b,a):this.I[c++].Fa(b,a)|this.I[c&this.B].Fa(0,a+1)<<8};g.Va=function(a,b){this.I[(a&this.i)>>>this.P].Ia(a&this.A,b&255,a)};g.xb=function(a,b){var c=a&this.A,d=(a&this.i)>>>this.P;c!=this.A?this.I[d].yb(c,b&65535,a):(this.I[d++].Ia(c,b&255,a),this.I[d&this.B].Ia(0,b>>8&255,a+1))};function Eb(a,b,c){r("Memory block error ("+a+": "+n(b)+","+n(c)+")");return!1}var Hb; +if(mb){var Ib=new ArrayBuffer(2);(new DataView(Ib)).setUint16(0,256,!0);Hb=256===(new Uint16Array(Ib))[0]}else Hb=!1;var Jb=Hb; +function K(a,b,c,d){this.id=Kb+=2;this.g=null;this.u=a;this.Xa=b;this.size=c||0;this.type=d||Lb;this.G=d==Mb;qb(this);this.ra=this.Cb=!1;if(c)if(mb)this.D=new ArrayBuffer(c),this.F=new DataView(this.D,0,c),this.A=new Uint8Array(this.D,0,c),this.J=new Uint16Array(this.D,0,c>>1),this.g=new Int32Array(this.D,0,c>>2),Nb(this,Jb?Ob:Pb);else{this.g=Array(c>>2);for(a=0;a>2),b=0;b>8,c)},S:function(a){return this.g[a>>2]>>>((a&3)<<3)&255},$:function(a){var b=a>>2;a=(a&3)<<3;var c=this.g[b]>>a;return 24>a?c&65535:c&255|(this.g[b+1]&255)<<8},ma:function(a,b){var c=a>>2,d=(a&3)<<3;this.g[c]=this.g[c]&~(255<>2,d=(a&3)<<3;24>d?this.g[c]=this.g[c]&~(65535<>8);this.ra=!0},N:function(a,b){if(this.C&&null!=this.u){var c=this.C;Ub(c,this.u+a,1,c.N)&&c.Y(!0)}return this.Qa(a,b)},V:function(a,b){if(this.C&&null!=this.u){var c=this.C;Ub(c,this.u+a,2,c.N)&&c.Y(!0)}return this.gb(a,b)},ja:function(a,b,c){if(this.C&&null!=this.u){var d=this.C;Ub(d,this.u+a,1,d.F)&&d.Y(!0)}this.G?this.B(a,b,c):this.Ja(a,b,c)},sa:function(a,b,c){if(this.C&& +null!=this.u){var d=this.C;Ub(d,this.u+a,2,d.F)&&d.Y(!0)}this.G?this.B(a,b,c):this.hb(a,b,c)},M:function(a){return this.A[a]},O:function(a){return this.A[a]},T:function(a){return this.F.getUint16(a,!0)},Z:function(a){return a&1?this.A[a]|this.A[a+1]<<8:this.J[a>>1]},fa:function(a,b){this.A[a]=b;this.ra=!0},ka:function(a,b){this.A[a]=b;this.ra=!0},na:function(a,b){this.F.setUint16(a,b,!0);this.ra=!0},Ka:function(a,b){a&1?(this.A[a]=b,this.A[a+1]=b>>8):this.J[a>>1]=b;this.ra=!0}}; +function qb(a,b,c){a.C=b;a.i=a.w=0;c&&((a.i=c.i)&&Tb(a,Sb,!1),(a.w=c.w)&&Rb(a,Sb,!1))}function Vb(a,b){b?0===--a.w&&(a.Ia=a.G?a.B:a.Ja,a.yb=a.G?a.H:a.hb):0===--a.i&&(a.Fa=a.Qa,a.vb=a.gb)}function Rb(a,b,c){c&&a.w||(a.Ia=!a.G&&b[2]||a.B,a.yb=!a.G&&b[3]||a.H);if(c||void 0===c)a.Ja=b[2]||a.B,a.hb=b[3]||a.H}function Tb(a,b,c){c&&a.i||(a.Fa=b[0]||a.K,a.vb=b[1]||a.L);if(c||void 0===c)a.Qa=b[0]||a.K,a.gb=b[1]||a.L}function Nb(a,b){b||(b=Wb);Tb(a,b,void 0);Rb(a,b,void 0)} +var Wb=[],Qb=[K.prototype.S,K.prototype.$,K.prototype.ma,K.prototype.La],Sb=[K.prototype.N,K.prototype.V,K.prototype.ja,K.prototype.sa];if(mb)var Pb=[K.prototype.M,K.prototype.T,K.prototype.fa,K.prototype.na],Ob=[K.prototype.O,K.prototype.Z,K.prototype.ka,K.prototype.Ka]; +function Xb(a,b){v.call(this,"CPU",a,Xb,1);var c=a.multiplier||1;this.$=a.cycles||b;this.xa=c;this.Z=Math.round(this.$/1E4)/100;this.wa=this.Z*this.xa;this.j.X=!1;this.j.fb=!1;this.j.rb=a.autoStart;this.j.sb=!1;this.j.Aa=!1;this.Na=this.L=0;this.Oa=a.csStart;this.Da=a.csInterval;this.Ea=a.csStop;this.S=[];this.sa=this.ya.bind(this);G(this)}z(Xb);var Yb=["power","reset"];g=Xb.prototype; +g.va=function(a,b,c,d){this.i=a;this.A=b;this.C=d;for(b=0;b=a.L&&(a.L+=a.Da,c=!0);0<=a.Ea&&a.Ea<=sc(a)&&(a.Da=a.Ea=-1,ac(a),a.Y(),c=!0);c&&a.b(sc(a)+" cycles: checksum="+n(a.Na))}} +function tc(a,b,c,d){a.G[b]&&(void 0===c&&(lb(a,"Value for "+b+" is invalid"),a.Y()),c=!a.j.X||a.j.sb?n(c,d):"--------".substr(0,d),a.G[b].textContent!=c&&(a.G[b].textContent=c))} +g.ba=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.G[b]=c;a=!0;break;case "run":this.G[b]=c;c.onclick=function(){var a;if(a=d.i)if(a=d.i,a.j.U)a=!0;else{var b=null,c,h=D(a.id);for(c=0;ca.H/a.wa?b=1:d=!0;a.xa=b;b=a.Z*a.xa;if(a.wa!=b){a.wa=b;b=a.wa.toFixed(2)+"Mhz";var e=a.G.setSpeed;e&&(e.textContent=b);a.b("target speed: "+b)}c&&a.i&&a.i.Wa()}vc(a,a.F);a.F=0;a.D=qa();a.J=0;wc(a);return d} +g.ya=function(a){if(ib(this,!0)){if(!this.j.X){uc(this);this.i&&this.i.start(this.D,sc(this));this.j.X=!0;this.j.fb=!0;this.N&&this.N.start();var b=this.G.run;b&&(b.textContent="Halt");this.i&&(this.i.ea(!0),a&&this.i.Wa(!0))}this.fa>=this.$&&wc(this,!0);this.O=0;this.T=qa();this.J&&(a=this.T-this.J,a>this.ma&&(this.D+=a,this.D>this.T&&(this.D=this.T)));try{do{for(var c=this.j.Aa?1:this.V,d=this.S.length-1;0<=d;d--){var e=this.S[d];0>e[0]||c>e[0]&&(c=e[0])}this.Ha(c);var f=this.w-this.g;a=f;for(var k= +this.S.length-1;0<=k;k--){var h=this.S[k];0>h[0]||(h[0]-=a,0>=h[0]&&(h[0]=-1,h[1]()))}this.O+=f;this.F+=f;vc(this,0,!0);dc(this,f);this.M-=f;if(0>=this.M){this.M+=this.V;15<=++this.na&&(this.i&&this.i.ea(),this.na=0);break}}while(this.j.X)}catch(l){this.Y();L(this);this.i&&this.i.stop(qa(),sc(this));ib(this,!1);lb(this,l.stack||l.message);return}c=setTimeout;d=this.sa;this.J=qa();e=this.ma;this.O&&(e=Math.round(e*this.O/this.V));e=e-(this.J-this.T);if(f=this.J-this.D)this.H=Math.round(this.F/(10* +f))/100,864E5<=f&&(this.K=0,uc(this));if(0>e||this.He&&(this.D-=e),e=0;this.fa+=this.O;this.J+=e;c(d,e)}else L(this),this.i&&this.i.stop(qa(),sc(this))};g.Ha=function(){return 0};g.Y=function(a){jb(this,!0);this.w-=this.g;this.g=0;vc(this,this.F);this.F=0;if(this.j.X){this.j.X=!1;this.N&&this.N.stop();var b=this.G.run;b&&(b.textContent="Run")}this.j.Ya=a};function L(a,b){a.i&&a.i.ea(b)} +function xc(a){this.ub=+a.model||1170;Xb.call(this,a,1E6);this.ja=yc;$b(this);this.j.Ya=this.j.Bb=!1;this.ka=0;zc(this)}z(xc,Xb);g=xc.prototype;g.reset=function(){this.j.X&&this.Y();zc(this);$b(this);this.j.Ba=!1;this.parent.reset.call(this)};function zc(a){a.Ga=0;a.Ra=0;a.$a=0;a.Sa=0;a.ab=0;a.Ta=0;a.bb=0;a.Ua=0;a.R=0;Ac(a,0);a.B=0}g.tb=function(){var a=this.Ga+this.Ra+this.$a+this.Sa+this.ab+this.Ta+this.bb|0;return a=a+this.Ua+this.R+Bc(this)|0}; +g.save=function(){var a=new M(this);N(a,0,[this.Ga,this.Ra,this.$a,this.Sa,this.ab,this.Ta,this.bb,this.Ua,this.R,Bc(this)]);N(a,1,[this.B,this.K,this.xa]);for(var b=this.A,c=0,d=[],e=0;ea&&!(this.B&1<a?255:1<>>0,k],q=pa(p,l,a.lb);0>q&&p.splice(-(q+1),0,l)}m&&(h.a=m.replace(/''/g,'"'))}a.H.push({Ib:b,u:c,Hb:d,oa:e,kb:f})}delete this.oa}return!0};Fc.prototype.pa=function(){return!0}; +function Gc(a,b,c,d){if(d)a.aa("Unable to load system ROM (error "+d+": "+b+")");else{eb(a.nb,b,c);if("["==c.charAt(0)||"{"==c.charAt(0))try{var e=eval("("+c+")"),f=e.bytes,k=e.data;if(f)a.i=f;else if(k)for(a.i=Array(4*k.length),d=c=0;c>8&255,a.i[d++]=k[c]>>16&255,a.i[d++]=k[c]>>24&255;else a.i=e;a.oa=e.symbols;if(!a.i.length){r("Empty ROM: "+b);return}if(1==a.i.length){r(a.i[0]);return}}catch(h){a.aa("ROM data error: "+h.message);return}else for(b=c.replace(/\n/gm, +" ").replace(/ +$/,"").split(" "),a.i=Array(b.length),e=0;e>>d.P].Ja(e&d.A,a.i[c]&255,e)}b=!0}else b=!1;if(b){b=[];"number"==typeof a.B?b.push(a.B):null!=a.B&&a.B.length&&(b=a.B);for(c=0;c>>e.P;0>>=e.P;0>>d.A.P;l=1}d.b("blockid physical blockaddr used size type");d.b("-------- --------- ---------- ------ ------ ----");for(var c=-1,m=0;l--;){var p=b[h];p.type==c?m++||d.b("..."):(c=p.type,m=Fb[c],p&&d.b(n(p.id)+" %"+n(h<>>c.P,c=e!=c.A?c.I[f].gb(e,d):c.I[f++].Qa(e,d)|c.I[f&c.B].Qa(0,d+1)<<8;b&&Tc(a,b)}return c}; +g.Va=function(a,b,c){var d=V(a);if(-1!==d){var e=this.A;e.I[(d&e.i)>>>e.P].Ja(d&e.A,b&255,d);c&&Tc(a,c);L(this.g,!0)}};g.xb=function(a,b,c){var d=V(a);if(-1!==d){var e=this.A,f=d&e.A,k=(d&e.i)>>>e.P;f!=e.A?e.I[k].hb(f,b&65535,d):(e.I[k++].Ja(f,b&255,d),e.I[k&e.B].Ja(0,b>>8&255,d+1));c&&Tc(a,c);L(this.g,!0)}};function P(a){return{u:a,la:!1}}function Uc(a){return[a.u,a.la]}function Vc(a){return{u:a[0],la:a[1]}} +function W(a,b,c){var d;c=(c?a.M:a.mb).u;if(void 0!==b){d=b=Wc(a,b);var e;if(d.match(/^[a-z_][a-z0-9_]*$/i))for(d=d.toUpperCase(),c=0;cc&&(c=xa(Qc,a.substr(b,1))));return c}function ad(a,b){var c;if(0<=b){var d=a.g;switch(b){case 12:c=d.R;break;case 14:c=Bc(d)&255|d.Ga<<8}}return c} +function bd(a,b){b=Wc(a,b);for(var c=0,d,e;0<=(c=b.indexOf("@",c));){e=$c(b,c+1);if(0<=e){d=0;var f=ad(a,e);if(void 0!==f)switch(e){case 12:case 14:d=4}b=b.substr(0,c)+(d?n(f,d):"??")+b.substr(c+1+Qc[e].length)}c++}for(c=0;0<=(c=b.indexOf("#",c));)e=b.substr(c+1,2),d=ba(e,16),null!=d&&32<=d&&128>d?(d=e+" '"+String.fromCharCode(d)+"'",b=b.replace("#"+e,d),c+=d.length):c++;for(c=0;0<=(c=b.indexOf("$",c));)e=b.substr(c+1,9),(d=W(a,e))?(d=e+' "'+Zc(a,d)+'"',b=b.replace("$"+e,d),c+=d.length):c++;for(c= +0;0<=(c=b.indexOf("^",c));)e=b.substr(c+1,9),(d=W(a,e))?(Tc(d),d=e+' "'+Zc(a,d,11)+'"',b=b.replace("^"+e,d),c+=d.length):c++;return b}g.message=function(a,b){b&&(a+=" at "+n(P(this.g.R).u,4));if(this.W&1073741824)this.ma.push(a);else if(!this.ka||a!=this.ka)if(this.ka=a,this.W&-2147483648&&(this.Y(),a+=" (cpu halted)"),this.b(a),this.g){var c=this.g;c.M=0;c.w-=c.g;c.g=0;L(c)}}; +function Mc(a){var b;if(Dc(a)){if(!a.L||!a.L.length){a.L=Array(1E3);for(b=0;b>>d.P],!1)}a.N=["br"];if(void 0!==a.F)for(b=1;b>>d.P],!0);a.F=["bw"];a.ob=0} +g.ta=function(a,b,c){var d=!0;c||gd(this,a,b,!1,!0);if(a!=this.w){var e=V(b);if(-1===e)this.b("invalid address: "+n(b.u,4)),d=!1;else{var f=this.A;f.I[e>>>f.P].ta(e&f.A,a==this.F)}}d&&(a.push(b),c?b.la=!0:(hd(this,a,a.length-1,"set"),Mc(this)));return d};function gd(a,b,c,d,e){var f=!1;c=V(c);for(var k=1;k>>d.P],b==a.F));h.la||Mc(a);break}}return f} +function id(a,b){for(var c=1;c>24,4);break;case 3:y=n(B.Ma(Y,2),4);break;default:B="imm("+ca(A)+")";break a}A&64?y="["+y+"]":A&16||(y="0x"+y);B=y}else A&16?B=Qc[(q&3840)>>8]:A&128&&(B=(f>>3&7).toString());if(!B||!B.length){h= +"INVALID";break}0=":6,">":6,"<=":6,"<":6,">>>":7,">>":7,"<<":7,"-":8,"+":8,"%":9,"/":9,"*":9}; +function md(a,b,c){for(c=c||-1;c--&&b.length;){var d=b.pop();if(2>a.length)return!1;var e=a.pop(),f=a.pop();switch(d){case "*":d=f*e;break;case "/":if(!e)return!1;d=f/e;break;case "%":if(!e)return!1;d=f%e;break;case "+":d=f+e;break;case "-":d=f-e;break;case "<<":d=f<>":d=f>>e;break;case ">>>":d=f>>>e;break;case "<":d=f":d=f>e?1:0;break;case ">=":d=f>=e?1:0;break;case "==":d=f==e?1:0;break;case "!=":d=f!=e?1:0;break;case "&":d=f&e;break; +case "^":d=f^e;break;case "|":d=f|e;break;case "&&":d=f&&e?1:0;break;case "||":d=f||e?1:0;break;default:return!1}a.push(d|0)}return!0} +function X(a,b,c){var d;if(b){b=Wc(a,b);for(var e=0,f=!1,k=b,h=[],l=[],m=b.split(/(\|\||&&|\||^|&|!=|==|>=|>>>|>>|>|<=|<<|<|-|\+|%|\/|\*)/);e>=1;k=p+"b"+k;d>>=8}d="0x"+n(c)+" "+c+". ("+k+")"}a.b((null!=b?b+": ":"")+d);return e}function Nd(a,b){if(b)return Md(a,b,a.Z[b]);var c=0;for(b in a.Z)Md(a,b,a.Z[b]),c++;return 0b[0]?1:a[0]>>0;for(b=0;b>>0,h=f.Hb;if(e>=k&&e>8&255;case "C":d.$a=h&255;break;case "D":d.Sa= +h&255;break;case "DE":d.Sa=h>>8&255;case "E":d.ab=h&255;break;case "H":d.Ta=h&255;break;case "HL":d.Ta=h>>8&255;case "L":d.bb=h&255;break;case "SP":d.Ua=h&65535;break;case "PC":d.R=h&65535;a.M=P(d.R);break;case "PS":Ac(d,h);break;case "PSW":Ac(d,h&255|d.ha&-256);d.Ga=h>>8;break;case "CF":d.da=h?d.da|256:d.da&255;break;case "ZF":d.da=h?d.da&-256:d.da|255;break;case "SF":h?d.ia&128||(d.ia^=192):d.ia&128&&(d.ia^=192);break;case "IF":d.ha=h?d.ha|512:d.ha&-513;break;default:a.b("unknown register: "+e); +return}if(!k){a.b("invalid value: "+f);return}L(d);a.b("updated registers:")}a.b("no regs");c&&(a.M=P(d.R),ed(a,n(a.M.u,4)))}}function Td(a,b){b=oa(b);var c=b.match(/^(['"])(.*?)\1$/);c?a.b(bd(a,c[2])):X(a,b,!0)}function Ud(a,b,c){var d="t"!=b;c=Ld(a,c,null,!0)||1;var e=1==c?0:1;"tc"==b&&(e=c,c=1);Fa(c,function(){return ib(a,!0)&&a.Ha(e,d,!1)},function(){L(a.g);ib(a,!1)})} +function ed(a,b,c,d){if(b=W(a,b,!0)){void 0===d&&(d=1);var e=256;if(void 0!==c){d=W(a,c,!0);if(!d||d.uh[0].indexOf("+"))){var m=h[0]+":";h[2]&&(m+=" "+h[2]);a.b(m)}h[3]&&(k=h[3],f=null);f=kd(a,b,k,f);a.b(f);a.M=b;e-=b.u-l;c++}}} +function Yc(a,b,c,d){if(c)if(b){0>a.D&&a.B.length&&(a.D=0);if(0>a.D||b!=a.B[a.D])a.B.splice(0,0,b),a.D=0;a.D--}else a.V?b="end":b=a.B[a.D+1];a=[];if(b){b=b.toLowerCase().replace(/""/g,"'");c=0;var e=null;d=d||";";for(var f=0;f<=b.length;f++){var k=b.charAt(f);if('"'==k||"'"==k)e?k==e&&(e=null):e=k;else if(k==d&&!e||!k)a.push(oa(b.substring(c,f))),c=f+1}}return a} +function jd(a,b,c){var d=!0;try{b.length&&"end"!=b?c||a.b(">> "+b):(a.V&&(a.b("ended assemble at "+n(a.T.u,4)),a.M=a.T,a.V=!1),b="");var e=b.charAt(0);if('"'==e||"'"==e)return!0;a.ka=null;if(kb(a)&&0m||"z"S.length&&(a.b("note: only "+S.length+" available"),I=S.length);C-=I;0>C&&(null==S[S.length-1].u?(I=C+I,C=0):C+=S.length);var gc=[];"call"==sd&&(wa=1E5,gc=["CALL"]);for(void 0!==rd&&a.b(I+" instructions earlier:");0=S.length&&(C=0);a.qb=I;ud++;wa--}}ud||(a.b("no "+td+"history available"),a.qb=void 0)}else{var sb= +W(a,Q);if(sb){var tb=0;fa&&("l"==fa.charAt(0)&&(fa=fa.substr(1)||ne),tb=Ld(a,fa)>>>0,65536>4||1;pe--&&0xb?String.fromCharCode(xb):".";vb--}ga&&(ga+="\n");ga+=Q+" "+Ua+(0==Ta?" "+ic:"")}ga&&a.b(ga);a.mb=sb}}}}break;case "e":if("else"== +f[0])break;var yb=1,xd=255,yd=a.ca,zd=a.Va;"ew"==f[0]&&(yb=2,xd=65535,yd=a.Ma,zd=a.xb);var Ad=yb<<1,Bd=f[1];if(null==Bd)a.b("edit memory commands:"),a.b("\teb [a] [...] edit bytes at address a"),a.b("\tew [a] [...] edit words at address a");else{var zb=W(a,Bd);if(zb)for(var Ab=2;Abnc;){for(var ia=null,ue=256;65536> +Xa.u>>>0;){Dd.u=a.Ma(Xa,2);if(null==Xa.u||!ue--)break;for(var ve=a,Cb=Dd,Ed=null,Ya=Cb.u,Fd=Ya,oc=1;6>=oc&&Ya;oc++){if(2\nLicense: GPL version 3 or later ");for(b=0;bYd){if($d(d,this.K)){this.F=new M(this,"1.24.2","failsafe");$d(this.F)&&(fe(this,d),a=2,ge(this.F));N(this.F,"timestamp",ra());he(this.F);var e=this.i&&!this.H;if(1==a||za("Click OK to restore the previous PDP11 machine state, or CANCEL to reset the machine.")){if(c=de(d)){var f=ee(d,"code"),k=ee(d,"data");f&&("ok"==f?$d(d,k):("error"==f&&"no machine state"!= +k?(this.aa("Error: "+k),"unable to verify user"==k&&(Da("user",""),this.w=null)):this.b(f+": "+k),ge(d),$d(d)?(c=de(d),e=!0):c=!1))}e&&ce(this,c?d:null)}else 2==a&&d.clear()}else ce(this);delete this.K;delete this.L}e=D(this.id);for(f=0;fa[1];a=a[2];this.$=!0;this.j.U=!0;var d=this.G.power;d&&(d.textContent="Shutdown");this.g&&(ie(this,this.g,b,c,a),cc(this.g));this.O&&(fe(this,b),b.clear());!c&&this.F&&(this.F.clear(),delete this.F);this.B=0}; +function fe(a,b){if(za("There may be a problem with your PDP11 machine.\n\nTo help us diagnose it, click OK to send this PDP11 machine state to http://www.pcjs.org.")){var c=a.w||"",d=b.toString(),e={app:"PDP11",ver:"1.24.2"};e.url=a.Z;e.user=c;e.type="bug";e.data=d;ya("http://www.pcjs.org/api/v1/report",e,!0)}} +function Vd(a,b,c){var d,e="none";if(a.B)return null;a.B--;var f=new M(a,"1.24.2"),k=new M(a,"1.24.2","validate"),h=ra();N(k,"timestamp",h);N(f,"timestamp",h);N(f,"version","1.24.2");N(f,"url",window?window.location.href:null);N(f,"browser",window?window.navigator.userAgent:"");a.g&&a.g.pa&&(c&&a.g.Y(),d=a.g.pa(b,c),"object"===typeof d&&N(f,a.g.id,d),c&&(a.g.j.U=!1,!1===d&&(e=null)));for(var h=D(a.id),l=0;lh.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(h=window.location.pathname+h);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(h?' url="'+h+'"':""))}e||(a=a.replace(/().*?(<\/xsl:variable>)/,"$1pdp11$2")); +h=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(h=new window.ActiveXObject("Microsoft.XMLDOM"),h.async=!1,h.loadXML(a)):h=(new window.DOMParser).parseFromString(a,"text/xml")}catch(q){h=null,a=q.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");ya(e,null,!0,function(f,k,h){if(h||!k)c(a,"unable to resolve XML reference: "+d[0]+" ("+h+")");else{if(f=d[3])if(h=k.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var l=h[0],m,p=/( [a-z]+=)(['"])(.*?)\2/g;m=p.exec(f);)l=0>l.indexOf(m[1])?l.replace(">",m[0]+">"):l.replace(new RegExp(m[1]+"(['\"])(.*?)\\1"),m[0]);h[0]!=l&&(k=k.replace(h[0],l))}else{c(a,"missing <"+d[1]+"> in "+e);return}k=k.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],k);Be(a,b,c)}})}else c(a,null)} +function Ce(a,b,c,d){function e(a){if(void 0===h){var b=k&&F(k,"machine-warning");h=b&&b[0]||k}h&&(h.innerHTML=ma(a))}function f(a){e("Error: "+a);l&&(--me||Na(!0));l=!1}var k,h,l=!0;me++;db[a]={};try{if(k=document.getElementById(a)){var m;if("object"==typeof resources&&(m=resources.css)){var p=document.head||document.getElementsByTagName("head")[0],q=document.createElement("style");q.type="text/css";q.styleSheet?q.styleSheet.cssText=m:q.appendChild(document.createTextNode(m));p.appendChild(q)}c|| +(c="/versions/pdp11/1.24.2/components.xsl");m=function(d,h){h?ze(c,null,null,!1,e,function(d,l){if(l)if(eb(a,c,d),e("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var m=h.transformNode(l);m?(k.outerHTML=m,--me||Na(!0)):f("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(m=new XSLTProcessor,m.importStylesheet(l),(m=m.transformToFragment(h,document))?k.parentNode?(k.parentNode.replaceChild(m,k),--me||Na(!0)):f("invalid machine element: "+ +a):f("transformToFragment failed")):f("unable to transform XML: unsupported browser");else f(d)}):f(d)};"<"!=b.charAt(0)?ze(b,a,d,!0,e,m):Ae(b,null,a,d,!1,e,m)}else f("missing machine element: "+a)}catch(w){f(w.message)}return l}window.embedPDP11=function(a,b,c,d){Na(!1);return Ce(a,b,c,d)};window.enableEvents=Na;window.sendEvent=Oa;})(); diff --git a/versions/pdp11/1.24.2/pdp11.js b/versions/pdp11/1.24.2/pdp11.js new file mode 100644 index 000000000..3997b25db --- /dev/null +++ b/versions/pdp11/1.24.2/pdp11.js @@ -0,0 +1,81 @@ +(function(){var e;function aa(a){var b=16,c;if(a){b||(b=16);if("$"==a.charAt(0))b=16,a=a.substr(1);else if("0x"==a.substr(0,2))b=16,a=a.substr(2);else{var d=a.charAt(a.length-1).toLowerCase();"h"==d?(b=16,d=null):"."==d&&(b=10,d=null);null==d&&(a=a.substr(0,a.length-1))}var f,d=a,g=b;(g&&10!=g?16==g?null!==d.match(/^[0-9a-f]+$/i):2==g&&null!==d.match(/^[01]+$/i):null!==d.match(/^[0-9]+$/))&&!isNaN(f=parseInt(a,b))&&(c=f|0)}return c} +function n(a,b){var c="";void 0===b?b=8:8=d?48:55),c=String.fromCharCode(d)+c;a>>=4}return c}function ba(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("&");0":">",'"':""","'":"'"};function fa(a){return a.replace(/[&<>"']/g,function(a){return ea[a]})}var q=Date.now||function(){return+new Date};function ga(){function a(a){return(10>a?"0":"")+a}var b=new Date;return b.getFullYear()+"-"+a(b.getMonth()+1)+"-"+a(b.getDate())+" "+a(b.getHours())+":"+a(b.getMinutes())+":"+a(b.getSeconds())} +function t(a,b,c,d){var f=0,g=null,k=null;if("object"==typeof resources&&(g=resources[a]))return d&&d(a,g,f),[g,f];if(c&&"function"==typeof resources)return resources(a,function(b,c){d&&d(a,b,c)}),k;var h=window.XMLHttpRequest?new window.XMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");c&&(h.onreadystatechange=function(){4===h.readyState&&(g=h.responseText,200==h.status||!h.status&&g.length&&"file:"==(window?window.location.protocol:"file:")||(f=h.status||-1),d&&d(a,g,f))});if(b&&"object"== +typeof b){var l="",m;for(m in b)b.hasOwnProperty(m)&&(l&&(l+="&"),l+=m+"="+encodeURIComponent(b[m]));l=l.replace(/%20/g,"+");h.open("POST",a,!!c);h.setRequestHeader("Content-type","application/x-www-form-urlencoded");h.send(l)}else h.open("GET",a,!!c),"bytes"==b&&h.overrideMimeType("text/plain; charset=x-user-defined"),h.send();c||(g=h.responseText,200!=h.status&&(f=h.status||-1),d&&d(a,g,f),k=[g,f]);return k}function p(){return"http://"+(window?window.location.host:"www.pcjs.org")} +function u(a){window&&window.alert(a)}function ha(a){var b=!1;window&&(b=window.confirm(a));return b}var ia=null;function ja(){if(null==ia){var a=!1;if(window)try{window.localStorage.setItem("PCjs.localStorage","PCjs.localStorage"),a="PCjs.localStorage"==window.localStorage.getItem("PCjs.localStorage"),window.localStorage.removeItem("PCjs.localStorage")}catch(b){a=!1}ia=a}return ia}function ka(a){var b;if(window)try{b=window.localStorage.getItem(a)}catch(c){}return b} +function v(a,b){try{return window.localStorage.setItem(a,b),!0}catch(c){}return!1}function la(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}var w={init:[],show:[],exit:[]},ma=!1,na=!1,oa=!0;function pa(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function x(a){w.init.push(a)} +function qa(a){if(oa)try{for(var b=0;bb?this.ca=this.id:(this.Ea=this.id.substr(0,b),this.ca=this.id.substr(b+1));this[a]=c;this.b={aa:!1,ha:!1,wa:!1,u:!1,U:!1};this.la=null;this.b.U=!1;this.c={};this.v=null;A.push(this)}var sa=void 0,ta={}; +if(window){sa||(sa=window.location.search.substr(1));for(var ua,va=/\+/g,wa=/([^&=]+)=?([^&]*)/g;ua=wa.exec(sa);)ta[decodeURIComponent(ua[1].replace(va," "))]=decodeURIComponent(ua[2].replace(va," "))}function xa(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b} +function B(a,b){b||(b=z);a.prototype=xa(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var ya=window.PCjs.Machines||(window.PCjs.Machines={}),A=window.PCjs.Components||(window.PCjs.Components=[])}else ya={},A=[];function za(a,b,c){ya[a]&&b&&(ya[a][b]=c)}function C(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b=this.h?10:20>=this.h?12:24>=this.h?14:15;this.i=1<>2;this.o=this.i-1;this.j=this.l/this.i|0;a=new L;Ea(a,this.v);this.a=Array(this.j);for(b=0;b>>a.g;0g&&(m=g);if(h&&h.size){if(h.type==d){if(f+g<=h.ga)return h.ma+=h.ga-f,h.ga=f,!0;if(f>=h.ga+h.ma){m=h.size-(f-l);m>g&&(m=g);h.ma=f-h.ga+m;f=l+a.i;g-=m;k++;continue}}return Ga(1,f,g)}f=new L(f,m,a.i,d);Ea(f,a.v,h);a.a[k++]=f;f=l+a.i;g-=m}return 0>=g?(a.status(Math.floor(c/1024)+"Kb "+Ha[d]+" at "+("0x"+n(b,4))),!0):Ga(2,b,c)} +K.prototype.xa=function(a){return this.a[(a&this.s)>>>this.g].ya(a&this.o,a)};function Ga(a,b,c){u("Memory block error ("+a+": "+n(b)+","+n(c)+")");return!1}var Ia;if(J){var Ja=new ArrayBuffer(2);(new DataView(Ja)).setUint16(0,256,!0);Ia=256===(new Uint16Array(Ja))[0]}else Ia=!1;var Ka=Ia; +function L(a,b,c,d){this.id=La+=2;this.c=null;this.ga=a;this.ma=b;this.size=c||0;this.type=d||Ma;this.j=d==Na;Ea(this);this.N=this.Oa=!1;if(c)if(J)this.a=new ArrayBuffer(c),this.i=new DataView(this.a,0,c),this.f=new Uint8Array(this.a,0,c),this.l=new Uint16Array(this.a,0,c>>1),this.c=new Int32Array(this.a,0,c>>2),Oa(this,Ka?Pa:Qa);else{this.c=Array(c>>2);for(a=0;a>2),b=0;b>8,c)},F:function(a){return this.c[a>> +2]>>>((a&3)<<3)&255},S:function(a){var b=a>>2;a=(a&3)<<3;var c=this.c[b]>>a;return 24>a?c&65535:c&255|(this.c[b+1]&255)<<8},Y:function(a,b){var c=a>>2,d=(a&3)<<3;this.c[c]=this.c[c]&~(255<>2,d=(a&3)<<3;24>d?this.c[c]=this.c[c]&~(65535<>8);this.N=!0},B:function(a,b){return this.C(a,b)},K:function(a,b){return this.M(a,b)},W:function(a,b,c){this.j||this.Ma(a,b,c)},$:function(a,b,c){this.j|| +this.da(a,b,c)},A:function(a){return this.f[a]},D:function(a){return this.f[a]},I:function(a){return this.i.getUint16(a,!0)},R:function(a){return a&1?this.f[a]|this.f[a+1]<<8:this.l[a>>1]},T:function(a,b){this.f[a]=b;this.N=!0},X:function(a,b){this.f[a]=b;this.N=!0},Z:function(a,b){this.i.setUint16(a,b,!0);this.N=!0},ea:function(a,b){a&1?(this.f[a]=b,this.f[a+1]=b>>8):this.l[a>>1]=b;this.N=!0}};function Ea(a,b,c){a.v=b;a.g=a.h=0;c&&((a.g=c.g)&&Sa(a,Ta,!1),(a.h=c.h)&&Ua(a,Ta,!1))} +function Ua(a,b,c){c&&a.h||(a.o=!a.j&&b[2]||a.s);if(c||void 0===c)a.Ma=b[2]||a.s,a.da=b[3]||a.ca}function Sa(a,b,c){c&&a.g||(a.ya=b[0]||a.m);if(c||void 0===c)a.C=b[0]||a.m,a.M=b[1]||a.L}function Oa(a,b){b||(b=Va);Sa(a,b,void 0);Ua(a,b,void 0)}var Va=[],Ra=[L.prototype.F,L.prototype.S,L.prototype.Y,L.prototype.fa],Ta=[L.prototype.B,L.prototype.K,L.prototype.W,L.prototype.$];if(J)var Qa=[L.prototype.A,L.prototype.I,L.prototype.T,L.prototype.Z],Pa=[L.prototype.D,L.prototype.R,L.prototype.X,L.prototype.ea]; +function M(a,b){z.call(this,"CPU",a,M);var c=a.multiplier||1;this.ea=a.cycles||b;this.D=c;this.da=Math.round(this.ea/1E4)/100;this.B=this.da*this.D;this.b.J=!1;this.b.Ha=!1;this.b.Fa=a.autoStart;this.b.Ga=!1;this.b.ja=!1;this.Y=this.C=0;this.Z=a.csStart;this.K=a.csInterval;this.L=a.csStop;this.W=[];this.Qa=this.za.bind(this);I(this)}B(M);var Wa=["power","reset"];e=M.prototype; +e.ba=function(a,b,c,d){this.a=a;this.i=b;this.v=d;for(b=0;ba.m/a.B&&(b=1);a.D=b;var c=a.da*a.D;if(a.B!=c){a.B=c;var c=a.B.toFixed(2)+"Mhz",d=a.c.setSpeed;d&&(d.textContent=c);a.G("target speed: "+c)}}bb(a,a.l);a.l=0;a.j=q();a.o=0;cb(a)} +e.za=function(){if(Aa(this,!0)){if(!this.b.J){P(this);this.a&&this.a.start(this.j,Q(this));this.b.J=!0;this.b.Ha=!0;this.I&&this.I.start();var a=this.c.run;a&&(a.textContent="Halt");this.a&&this.a.V(!0)}this.fa>=this.ea&&cb(this,!0);this.R=0;this.X=q();this.o&&(a=this.X-this.o,a>this.Ia&&(this.j+=a,this.j>this.X&&(this.j=this.X)));try{do{for(var b=this.b.ja?1:this.$,c=this.W.length-1;0<=c;c--){var d=this.W[c];0>d[0]||b>d[0]&&(b=d[0])}this.La(b);for(var f=this.h-this.f,a=f,g=this.W.length-1;0<=g;g--){var k= +this.W[g];0>k[0]||(k[0]-=a,0>=k[0]&&(k[0]=-1,k[1]()))}this.R+=f;this.l+=f;bb(this,0,!0);a=f;if(this.b.ja){var h=!1;this.Y=this.Y+this.Ka()|0;this.C-=a;0>=this.C&&(this.C+=this.K,h=!0);0<=this.L&&this.L<=Q(this)&&(this.K=this.L=-1,Za(this),O(this),h=!0);h&&this.G(Q(this)+" cycles: checksum="+n(this.Y))}this.M-=f;if(0>=this.M){this.M+=this.$;15<=++this.Ja&&(this.a&&this.a.V(),this.Ja=0);break}}while(this.b.J)}catch(l){O(this);$a(this);this.a&&this.a.stop(q(),Q(this));Aa(this,!1);b=l.stack||l.message; +this.b.U=!0;this.w(b);return}b=setTimeout;c=this.Qa;this.o=q();d=this.Ia;this.R&&(d=Math.round(d*this.R/this.$));d=d-(this.o-this.X);if(f=this.o-this.j)this.m=Math.round(this.l/(10*f))/100,864E5<=f&&(this.s=0,P(this));if(0>d||this.md&&(this.j-=d),d=0;this.fa+=this.R;this.o+=d;b(c,d)}else $a(this),this.a&&this.a.stop(q(),Q(this))};e.La=function(){return 0}; +function O(a){a.b.ha&&(a.b.wa=!0);a.h-=a.f;a.f=0;bb(a,a.l);a.l=0;if(a.b.J){a.b.J=!1;a.I&&a.I.stop();var b=a.c.run;b&&(b.textContent="Run")}a.b.ka=void 0}function $a(a){a.a&&a.a.V(void 0)}function db(a){this.Pa=+a.model||1170;M.call(this,a,1E6);this.Aa=eb;Ya(this);this.b.ka=this.b.Na=!1;this.Ba=0;fb(this)}B(db,M);e=db.prototype;e.reset=function(){this.b.J&&O(this);fb(this);Ya(this);this.b.U=!1;this.parent.reset.call(this)}; +function fb(a){a.oa=0;a.pa=0;a.qa=0;a.ra=0;a.sa=0;a.ta=0;a.na=0;a.ua=0;a.A=0;gb(a,0);a.g=0}e.Ka=function(){var a=this.oa+this.pa+this.qa+this.ra+this.sa+this.ta+this.na|0;return a=a+this.ua+this.A+hb(this)|0}; +e.save=function(){var a=new R(this);S(a,0,[this.oa,this.pa,this.qa,this.ra,this.sa,this.ta,this.na,this.ua,this.A,hb(this)]);S(a,1,[this.g,this.s,this.D]);for(var b=this.i,c=0,d=[],f=0;fa&&!(this.g&1<a?255:1<>8&255,a.a[d++]=k[c]>>16&255,a.a[d++]=k[c]>>24&255;else a.a=f;a.l=f.symbols;if(!a.a.length){u("Empty ROM: "+b);return}if(1==a.a.length){u(a.a[0]);return}}catch(h){a.w("ROM data error: "+h.message);return}else for(b=c.replace(/\n/gm, +" ").replace(/ +$/,"").split(" "),a.a=Array(b.length),f=0;f>>d.g].Ma(f&d.o,a.a[c]&255,f)}b=!0}else b=!1;if(b){b=[];"number"==typeof a.h?b.push(a.h):null!=a.h&&a.h.length&&(b=a.h);for(c=0;c>>f.g;0>>=f.g;0\nLicense: GPL version 3 or later ");for(b=0;bW){if(X(d,this.s)){this.l=new R(this,"1.24.2","failsafe");X(this.l)&&(sb(this,d),a=2,tb(this.l));S(this.l,"timestamp",ga());ub(this.l);var f=this.a&&!this.m;if(1==a||ha("Click OK to restore the previous PDP11 machine state, or CANCEL to reset the machine.")){if(c=rb(d)){var g=Z(d,"code"),k=Z(d,"data");g&&("ok"==g?X(d,k):("error"==g&&"no machine state"!= +k?(this.w("Error: "+k),"unable to verify user"==k&&(v("user",""),this.g=null)):this.G(g+": "+k),tb(d),X(d)?(c=rb(d),f=!0):c=!1))}f&&qb(this,c?d:null)}else 2==a&&d.clear()}else qb(this);delete this.s;delete this.A}f=C(this.id);for(g=0;ga[1];a=a[2];this.M=!0;this.b.u=!0;var d=this.c.power;d&&(d.textContent="Shutdown");this.f&&(vb(this,this.f,b,c,a),ab(this.f));this.D&&(sb(this,b),b.clear());!c&&this.l&&(this.l.clear(),delete this.l);this.h=0}; +function sb(a,b){if(ha("There may be a problem with your PDP11 machine.\n\nTo help us diagnose it, click OK to send this PDP11 machine state to http://www.pcjs.org.")){var c=a.g||"",d=b.toString(),f={app:"PDP11",ver:"1.24.2"};f.url=a.L;f.user=c;f.type="bug";f.data=d;t("http://www.pcjs.org/api/v1/report",f,!0)}} +function wb(a,b,c){var d,f="none";if(a.h)return null;a.h--;var g=new R(a,"1.24.2"),k=new R(a,"1.24.2","validate"),h=ga();S(k,"timestamp",h);S(g,"timestamp",h);S(g,"version","1.24.2");S(g,"url",window?window.location.href:null);S(g,"browser",window?window.navigator.userAgent:"");a.f&&a.f.O&&(c&&O(a.f),d=a.f.O(b,c),"object"===typeof d&&S(g,a.f.id,d),c&&(a.f.b.u=!1,!1===d&&(f=null)));for(var h=C(a.id),l=0;lh.indexOf("/")&&"/"==window.location.pathname.slice(-1)&&(h=window.location.pathname+h);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(h?' url="'+h+'"':""))}f||(a=a.replace(/().*?(<\/xsl:variable>)/,"$1pdp11$2")); +h=null;if("<"==a.charAt(0))try{f||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(h=new window.ActiveXObject("Microsoft.XMLDOM"),h.async=!1,h.loadXML(a)):h=(new window.DOMParser).parseFromString(a,"text/xml")}catch(r){h=null,a=r.message}else a="unrecognized XML: "+(255/g.exec(a)){var f=d[2];b("Loading "+f+"...");t(f,null,!0,function(g,k,h){if(h||!k)c(a,"unable to resolve XML reference: "+d[0]+" ("+h+")");else{if(g=d[3])if(h=k.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var l=h[0],m,F=/( [a-z]+=)(['"])(.*?)\2/g;m=F.exec(g);)l=0>l.indexOf(m[1])?l.replace(">",m[0]+">"):l.replace(new RegExp(m[1]+"(['\"])(.*?)\\1"),m[0]);h[0]!=l&&(k=k.replace(h[0],l))}else{c(a,"missing <"+d[1]+"> in "+f);return}k=k.replace(/<\?xml[^>]*>[\r\n]*/, +"");a=a.replace(d[0],k);Db(a,b,c)}})}else c(a,null)} +function Eb(a,b,c,d){function f(a){if(void 0===h){var b=k&&H(k,"machine-warning");h=b&&b[0]||k}h&&(h.innerHTML=fa(a))}function g(a){f("Error: "+a);l&&(--Ab||y(!0));l=!1}var k,h,l=!0;Ab++;ya[a]={};try{if(k=document.getElementById(a)){var m;if("object"==typeof resources&&(m=resources.css)){var F=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css";r.styleSheet?r.styleSheet.cssText=m:r.appendChild(document.createTextNode(m));F.appendChild(r)}c|| +(c="/versions/pdp11/1.24.2/components.xsl");m=function(d,h){h?Bb(c,null,null,!1,f,function(d,l){if(l)if(za(a,c,d),f("Processing "+b+"..."),window.ActiveXObject||"ActiveXObject"in window){var m=h.transformNode(l);m?(k.outerHTML=m,--Ab||y(!0)):g("transformNodeToObject failed")}else document.implementation&&document.implementation.createDocument?(m=new XSLTProcessor,m.importStylesheet(l),(m=m.transformToFragment(h,document))?k.parentNode?(k.parentNode.replaceChild(m,k),--Ab||y(!0)):g("invalid machine element: "+ +a):g("transformToFragment failed")):g("unable to transform XML: unsupported browser");else g(d)}):g(d)};"<"!=b.charAt(0)?Bb(b,a,d,!0,f,m):Cb(b,null,a,d,!1,f,m)}else g("missing machine element: "+a)}catch(Fb){g(Fb.message)}return l}window.embedPDP11=function(a,b,c,d){y(!1);return Eb(a,b,c,d)};window.enableEvents=y;window.sendEvent=ra;})();